Tối ưu thời gian khai thác Blind SQL injection

Như chúng ta đã biết SQL injection cho phép chúng ta khai thác thông tin từ cơ sở dữ liệu. Riêng với blind, chúng ta phải đoán thông tin dần dần dựa theo kết quả trả về là true hay false. Do đó sẽ dẫn tới một vấn đề đó là nếu thông tin chúng ta cần lấy ví du: tên cơ sở dữ liệu, tên bảng, tên user quá dài thì việc đoán sẽ gặp trở ngại lớn về thời gian.

Trong khuôn khổ bài viết này tôi xin trình hai phương pháp đoán một ký tự đúng có trong thông in chúng cần khai thác.

blind+sqli+tut[1]

1. Tìm kiếm nhị phân trong khai thác Blind SQL Injection

Đây là một thuật toán tìm kiếm khả phổ biến. Về nguyên tắc nếu bạn cần tìm một phần tử nào đó trong tập hợp đã được sắp xếp, bạn chỉ cần xác định xem nó thuộc vào khoảng nào, từ đó dần dần thu hẹp phạm vi tìm.

Cụ thể : có dãy số : 1 2 3 4 5 6 7 8 9 . Giờ mình cần tìm phần tử 9 ở vị trí nào, thay vì bạn duyệt và kiểm tra từng phần tử của dãy bạn có thể tiến hành như sau:

  • Kiểm tra 9 lớn hay nhỏ hơn phần từ ở giữa là 5 trong dãy trên Ta thấy rõ ràng lớn hơn => ta được khoảng đầu tiên 6 7 8 9
  • Cứ thế tìm tới khi chỉ còn 2 phần từ 8, 9 ta chỉ so sánh 1 lần là tìm được giá trị mong muốn.
  • Thuật toán này rất tối ưu về thời gian và có độ phức tạp O(log n).

Quay trở lại với việc khai thác lỗi bind SQLi, ta có thể tìm 1 ký tự đúng bằng thuât toán trên bằng việc so sánh với mã ascii.

Ví dụ: and ascii(substring((select username from jos_users),1,1) > 124

Với câu truy vấn trên, bạn sẽ lấy ra ký tự đầu tiên của user để so sánh và tìm ký tự đúng. Tìm kiếm nhị phân là phương pháp được dùng khá phổ biến trong kĩ thuật khai thác bind SQLi.

2. Dịch bit trong khai thác Blind SQL Injection

Thông thường một ký tự bất kỳ sẽ được biểu diễn qua 8 bit nhị phân (theo ascii) do đó chúng ta sẽ dịch dần từng bit cho tới khi tìm được ký tự đúng.

Cụ thể: chúng ta sẽ tiến hành dịch phải từ 7 bit tới 0 bit. Như ta đã biết với mỗi bit nhị phân bất kỳ sẽ chỉ có 2 lựa chọn hoặc là 1 hoặc là 0. Với mỗi lần chúng ta sẽ kiểm tra chính xác vị trí đó sẽ nhận giá trị nào. Cứ dần như thế tới khi dịch đủ 7 bit ta sẽ đoán thành công mã ascii của ký tự cần tìm.

Ví dụ: chữ cái đầu tên của database là ‘a’ sẽ có mã ascii là 97.

  • Ta tiến hành dịch phải 7 bit và đoán xem nó là 0 hay 1
  • Sau khi được bit đầu tiên ta lại thử điền vào vị trí bít thứ 6 và so sánh tiếp để tìm.
  • Cứ làm tuần tự như trên ta chỉ cần thực hiện 7 lần để đoán chính xác 1 ký tự

Kĩ thuật này đơn giản và thực hiện dễ dàng hơn so với tìm kiếm nhị phân và cũng đươc dùng tương đối phổ biến. Thông qua hai kĩ thuật trên ta có thể dễ dàng lấy thông tin từ database và tiết kiệm thời gian rất nhiều so với cách tìm kiếm tuần tự thông thường.