Kết quả tiêm dựa trên một số giả định về cú pháp truy vấn cơ bản.
Điều được giả định ở đây là có một truy vấn ở đâu đó trong mã sẽ lấy tham số "id" và thay thế nó trực tiếp vào truy vấn, mà không làm phiền nó.
Nó giả định một cú pháp truy vấn ngây thơ của một cái gì đó như:
select * from records where id = {id param}
Điều này không là kết quả trong một truy vấn thay (trong ví dụ trên của bạn) của:
select * from records where id = 1 union select 0, 1 , concat_ws(user(),0x3a,database(),0x3a,version()), 3, 4, 5, 6 --
Bây giờ, điều này không đó là hữu ích là nó quản lý để lấy không chỉ là kỷ lục mà chương trình đã quan tâm đến, nhưng cũng có thể nó đoàn nó với một tập dữ liệu không có thật mà nói với những kẻ tấn công (những giá trị này xuất hiện cách nhau bởi dấu hai chấm trong cột thứ ba):
- tên người dùng mà chúng tôi đang kết nối với cơ sở dữ liệu
- tên của cơ sở dữ liệu
- phiên bản của phần mềm db
Bạn có thể nhận được các thông tin tương tự bằng cách đơn giản chạy:
select concat_ws(user(),0x3a,database(),0x3a,version())
Trực tiếp tại dấu nhắc sql và bạn sẽ nhận được thông báo như sau:
joe:production_db:mysql v. whatever
Ngoài ra, vì UNION thực hiện sắp xếp ngầm định và cột đầu tiên trong tập dữ liệu không có thật bắt đầu bằng 0, rất có thể là kết quả không có thật của bạn sẽ ở đầu danh sách. Điều này quan trọng bởi vì chương trình có lẽ chỉ sử dụng kết quả đầu tiên, hoặc có thêm một chút SQL trong biểu thức cơ bản mà tôi đã cho bạn ở trên giới hạn kết quả được đặt thành một bản ghi.
Lý do có tiếng ồn trên (ví dụ: chọn 0,1, ... vv) là để làm việc này, câu lệnh bạn đang gọi UNION phải có cùng số cột như tập kết quả đầu tiên. Kết quả là, cuộc tấn công tiêm ở trên chỉ hoạt động nếu bảng ghi tương ứng có 7 cột. Nếu không, bạn sẽ nhận được một lỗi cú pháp và cuộc tấn công này sẽ không thực sự cung cấp cho bạn những gì bạn muốn. Các dấu gạch ngang kép (-) chỉ là để đảm bảo rằng bất cứ điều gì có thể xảy ra afterwords trong thay thế được bỏ qua, và tôi nhận được kết quả tôi muốn. Rác 0x3a chỉ nói "tách các giá trị của tôi bằng dấu hai chấm".
Bây giờ, điều làm cho truy vấn này hữu ích như một vectơ tấn công là dễ dàng viết lại bằng tay nếu bảng có nhiều hơn hoặc ít hơn 7 cột.
Thí dụ nếu các truy vấn trên không hiệu quả, và các bảng trong câu hỏi có 5 cột, sau khi một số thử nghiệm tôi sẽ nhấn khi url truy vấn sau đây để sử dụng như một vector tiêm:
http://server/path/page.php?id=1+union+select+0,1,concat_ws(user(),0x3a,database(),0x3a,version()),3,4--
Các số cột mà kẻ tấn công đoán là có lẽ dựa trên giao diện được giáo dục trên trang. Ví dụ, nếu bạn đang tìm kiếm một trang liệt kê tất cả các doodads trong một cửa hàng, và có vẻ như:
Name | Type | Manufacturer
Doodad Foo Shiny Shiny Co.
Doodad Bar Flat Simple Doodads, Inc.
Đó là một đoán khá tốt mà bảng bạn đang nhìn vào có 4 cột (nhớ có nhất có thể là một khóa chính ẩn ở đâu đó nếu chúng ta đang tìm kiếm bằng tham số 'id').
Xin lỗi vì bức tường văn bản, nhưng hy vọng rằng câu trả lời cho câu hỏi của bạn.
Chỉ cần lưu ý: 0x3A là dấu hai chấm (:) trong hex –
+1: Cũng lưu ý rằng nó không thực sự thay thế '? 'Làm trình giữ chỗ - nếu nó là, nó sẽ không phải là lần tiêm! Nó thay thế nó thành văn bản * trước khi * diễn giải thành SQL; đó chính là bản chất của các cuộc tấn công SQL injection. –
@Donal: làm cho nó rõ ràng hơn trong câu trả lời. – Quassnoi