Thứ Hai, 5 tháng 11, 2012

Tối ưu Blind SQL Injection - Phần 2


Hi All,

Mình mạn phép share bài viết tiếp theo của Luật về chủ đề Tối Ưu Blind SQL Injection.

---------------------------------------------------------------------------------------------
Okie, tiếp tục bài viết "Tối ưu hóa Blind SQL Injection" cách đây vài hôm của mình . Có hứa là "ngày mai" ...nhưng các bạn thông cảm. Ăn tất niên quên cả giờ giấc.

Thôi vào thẳng vấn đề. Cách tối ưu của mình thì cũng không có gì đặc sắc lắm, cứ xem nó là 1 gợi ý cho các bạn để tìm cách tấn công tối ưu nhất vậy.
.................


I. Sleep cùng 1 lúc...tên hay phết.
Thay vì như cách sleep luôn giá trị find_in_set trả về thì có thể sleep rất lâu, cũng có thể sleep rất lẹ và 1 số nhược điểm mà mình nói trong bài lần trước, thì mình có cách khắc phục đó là:

Hình đã gửi

Tức là thay vì sleep 39 giây. thì chúng ta sẽ tách ra là 3 và 9 để sleep. Với cách này có thể khắc phục các trường hợp find_in_set quá lớn và quá nhỏ, ngoài ra cũng có thể code ra tool để chạy song song 2 query này. Thế là nội trong ít nhất 9 giây ta có thể biết luôn cả char cần tìm thay vì là 39 giây .


II. Tùy chọn giá trị trả về

Đây là cách mình nói ở cuối bài lần trước, tuy rằng cách này thiên về tốc độ, không như cách sleep của anh gamma là tối ưu về số lượng query và câu cú query đơn giản.

VD: Ta có 1 trang news (ex: http://gov.ca.gov/news.php?id=17267). Như các bạn biết, các table chứa các nội dung của những bản tin tức sẽ được tạo theo cấu trúc (minh họa đơn giản nhất, thực tế thì sẽ có thêm vài columns nữa)

Hình đã gửi

Tức là với mỗi ID khác thì Content cũng sẽ khác, với mỗi id khác thì bản tin được trang web in ra cũng sẽ khác. vậy lợi dụng vào việc này ta có thể tùy chọn giá trị id trả về sau mỗi query rồi dùng một ngôn ngữ nào đó ta regex (regular expression) để so sánh.

Để cụ thể hơn mình có 1 source ở localhost. giả dụ đây là 1 trang tin tức. Click vào để xem hình chi tiết hơn.



Hình đã gửi


Hình đã gửi

như các bạn thấy ở mỗi id khác thì nội dung cũng sẽ khác.

Vấn đề ở đây là nếu Blind SQLI như bình thường thì ta chỉ quan tâm TRUE or FALSE, rồi xem những nội dung mà chỉ khi TRUE mới hiện ra có được trang web in ra hay không. Nhưng ta cũng có thể tùy chọn giá trị id trả về. Ví dụ ta khai thác trang localhost bằng query này:

[font=courier new,courier,monospace]content.php?id=if(substring(@@version,1,1)=5,1,2)[/font]


Tức là nếu kí tự đầu tiên của version SQL là 5 thì id sẽ là 1 , nếu không phải id sẽ là 2. Rồi dựa vào nội dung đặc trưng và khác nhau giữa 2 bản tin ấy ta có thể biết kí tự đầu tiên của version có phải là 5 hay không. Vậy với câu query như thế này thì sao ?


if((@a:=mid(INSTR(0x6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738395f21402324255e262a28292d2b3d5c2e225c277e605c5c7c7b7d5b5d3a3b20,mid(@@version,1,1)),1,1))!='',if(@a=0,10,if(@a=1,1,if(@a=2,2,if(@a=3,3,if(@a=4,4,if(@a=5,5,if(@a=6,6,if(@a=7,7,if(@a=8,8,if(@a=9,9,0)))))))))),0) 

Câu query này đang tách giá trị find_in_set ra làm 2 rồi tìm, giống như cách 1 ở trên. Nhờ vào nội dung ta có thể biết đang là id mấy, từ id ta có thể truy ra con số đầu tiên mà find_in_set trả về là bao nhiêu chỉ trong vòng 1 query ? vậy tối đa ta chỉ dùng 2 query là đã ra 1 kí tự.Done.

?id=0 , SQL nó không trả về kết quả vì nó hiểu giống như là NULL ở kiểu định dạng string,thì đây là NULL ở dạng int...thì phải. Cái này không rõ lắm .



Vậy các điều kiện để thực hiện cách khai thác này chỉ là có đủ 10 nội dung ở 10 id khác nhau , ở đây là 10 bản tin khác nhau để có thể so sánh qua lại tìm ra giá trị cần tìm . Mọi chi tiết, thắc mắc về bài viết này xin gửi mail cho mình ở bên dưới. Peace!




manhluat93

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

Thanks,

Thong Ngo. 

Không có nhận xét nào: