[exploit][sqli]Challenge ngày Tết
Một bài blog 80% giải trí, chém gió 20% học thuật =)))
Last updated
Was this helpful?
Một bài blog 80% giải trí, chém gió 20% học thuật =)))
Last updated
Was this helpful?
Chuyện là mình có một thằng bạn cùng chạy bộ, đá banh mỗi chiều những ngày nghỉ dịch ở sân vận động. Một hôm đẹp trời nó mới bảo:
Bạn: mày học làm hacker vậy hack giùm tao cái này ...
Tui: Nah nahhhhh!! Lạy mày đừng kêu tao hack facebook :<
Bạn: Đâu.. kì rồi tao làm đồ án dựng cái web xịn xò lắm nên nhờ mày xem thử độ bảo mật của cái web.
*bạn tui vẫn đang blah..blah..tiếp tục show ra các công nghệ xịn xò dùng trong web của y.
Tui: Oke, nghe kể quá trời mà thấy mày không bật filter ký tự đặc biệt là dễ bị sql injection lắm đấy. Để tao thử mày xem nhé :))))
Bạn: tao vẫn thắc mắc là mày injection rồi nó đâu hiển thị ra đầu thì sao mày lấy được dữ liệu từ database của tao nhỉ?
*Bạn tui tiếp tục ngàn câu hỏi vì sao về cách thức injection và nhận data trả về
Tui: Bạn êiii, bình tĩnh. Tao cũng còn non lắm chỉ học vài cái cơ bản nhưng trong số loại sqli tao từng đọc qua thì có loại blind sqli rất xịn xò, không cần mày show data ra những vẫn sẽ đoán được dữ liệu của mày :)) theo tao hiểu thì nó như cái cách người mù mò chữ nổi vậy đó. Thôi để tao demo mày xem nhé! Đưa tao cái địa chỉ web mày nào.
Và rồi bắt đầu chuỗi ngày sáng thức dậy vừa đọc doc vừa tìm cách exploit vào lỗ hỏng của nó :>>>
Đầu tiên là thằng bạn có nhắc nó dùng mysql thì tạm là khỏi bước scan để biết nó dùng cái gì. Kế tiếp là dùng plugin Wappalyer thì biết thêm nó dùng NodeJS, Express, Jquery, Bootstrap,...
Tiếp theo tui nghĩ rằng đây là 1 project môn học thì khá chắc bạn tui sẽ dùng user root để liên kết database (nếu hong phải thì thoy tính sau), kế đến là con server sẽ vừa để code và để cả database chung.
Mới nhìn vô trong đầu mình nhảy số ngay sẽ lựa một trong 2: thanh search HOẶC đăng nhập/đăng ký để exploit.
Ngẫm nghĩ thêm vài giây, so với việc điền quá nhiều fields so với thanh search :))) nên tui chọn bắt đầu với search trước.
Okay bắt đầu "nháy 1 cái" với ẻm nè:
Kết quả:
"Nháy" lại 1 cái nữa nhưng ở chỗ khác thử:
Á àaaaaa :))) nó có lỗi nè. Điều này suy ra được gì?
=> Việc gửi nháy đơn lên server và nó xuất hiện lỗi thì tui khá chắc chắn đó là ông bạn dev của tui đã không lọc dấu nháy đơn (1 ký tự rất đặt biệt trong mysql), cứ thế dấu nháy đơn được đưa vào câu truy vấn của bạn tui (việc này khẳng định thêm ông bạn dùng raw query chứ hong có dùng ORM) dẫn đến lỗi syntax mysql báo về server. Cuối cùng ông bạn catch lỗi và phản hồi client cái page 500 này.
Oke thử thêm 1 việc nữa:
Như vậy nháy 1 cái để kết thúc và # comment vô hiệu hóa đoạn query phía sau.
Trước tiên bắt đầu, mình sẽ gạch vài đầu dòng để nói rõ hơn về blind sql injection:
Bạn list database chỉ cần 1 query: SELECT schema_name FROM information_schema.schemata;
Nhưng bạn làm sao thấy được tên database khi dev chỉ trả về kết quả nhưng thông tin liên quan đến category hoặc courses?? Nếu bạn run query trên thì khi chạy cùng query của ông dev cũng sẽ không trả về cái gì cả.
Từ những cái trên bạn phải tạo ra 1 query làm sao khi chạy cùng query của ông dev vẫn sẽ ra kết quả và bạn đứng từ phía client vẫn biết được kết quả đó là gì dù không hề trả kết quả về client... (đây gọi là blind sql injection).
Để biết kết quả trả về thì kỹ thuật blind sql injection mình thấy có 2 dạng thường xuyên được áp dụng: base on error và base on time.
Trong trường hợp này ông dev chỉ trả về trang báo lỗi chứ không hiển lỗi nên tui không sử dụng base-error mà sẽ dùng base-time:
Base-time nôm na là dựa vào thời gian trả về để đoán xem kết quả đó là gì.
Cụ thể hơn xíu là tui chèn 1 câu query list all database (list này có 1 cột và nhiều hàng).
Tui dùng hàm limit để lấy 1 row, kết hợp hàm substring (mid củng được) trong mysql để lấy 1 ký tự.
Sau đó tui đem đi so sánh với 1 ký tự có thể in được (ký tự 32 đến 126 trong bảng mã ascii).
Nếu đúng tui sleep 2 giây, sai thì server sẽ response khá nhanh (<1s với tốc độ mạng ok)
Cứ thế tui vét cạn hết từng ký tự của từng row thì tui sẽ nhận được kết quả.
Với số 0 là bạn lấy dòng đầu tiên, để lấy dòng tiếp theo cứ tăng số 0 lên 1, 2, 3,...
Với số 1 tham số thứ 2 của hàm substring là lấy ký tự thứ nhất. Cứ thế bạn tăng số 1 lên 2, 3, 4 để lấy ký tự tiếp theo.
Ví dụ trên là lấy 1 ký tự so sách với ký tự a, nếu đúng thì sleep 2 giây.
Để linh hoạt hơn khi đưa vào code thì thay thế so sánh trực tiếp với 'a' thì mình thay thế bằng char(97).
Dấu nháy đầu tiên: Để kết thúc tham số truyền vào
Dấu thăng cuối: để comment tất cả query phía sau
Như vậy đã có quey, tiếp để mình sử dụng python để request payload này lên server
Tách từng payload để lúc request có thể dễ dàng thay đổi tham số phía bên trong ở mỗi vòng lặp.
Bây giờ vô phần chính quan trọng nhất là tạo vòng lặp để gửi request và kiểm tra response.
Ở phần code này dựa vào tư duy lập trình, dựa vào những ý tưởng trên rồi xào nấu cho hợp lý ra được cái code chạy ngon lành :)))) Không thể giải thích nên chỉ comment trong hình nhaaaaa
Ở line thứ 26, chạy từ 33 đến bé hơn 127 chứ không phải từ 32 (dấu cách) vì sao? Vì ban đầu mình cho chạy từ 32 thì phát hiện ra khi lấy ký tự rỗng so sánh với dấu cách thì bằng nhau dẫn đến mình không thoát vòng lặp được. Vậy nên sẽ bắt đầu từ 33 luôn (thường thì đặt tên trong sql sẽ hong ai đặt có dấu trắng cả)
Thời gian sleep mình thay đổi từ 2s xuống còn 1s vì respone khi cho sleep 2s lên tới tận >80s. Mình nghĩ vì lý do câu truy vấn khá loằn ngoằn nên mới trả về thời gian lâu thế.
Sau gần 1 tiếng run đoạn script trên thì mình về kết quả khá tốt:
Như vậy là tui đã thấy db chính của website ông bạn (db_online_academy) và hơn thế là còn vài cái db hay ho mà ông ấy lưu chung mà tui đã tô đỏ.
Ông bạn của tui dùng bcrypt để hash password nên nếu có vào xem được username + password thì cũng hong làm gì được :< Vậy giờ tui có thể làm gì với database của ông bạnnn?
Lấy tên của tất cả DB, TABLEs, COLUMNs.
Crawl tất cả data có trong DB.
DROP DATABASE??? :)))) ai lại làm vạiiiiiii với lại có DROP thì cũng còn backup thoyyy
Leak username + password root rồi remote DB để có thể tùy chỉnh DB (thêm, xóa, sửa, ...)
...
Những gì có thể làm phải khiến mình mất thêm 1 khoảng thời gian nữaaaaa, nên tạm dừng ở đây đi ngủ trưa rồi chiều ra sân banh report với thằng bạn mình thoyyyyy
Trên đây là tất cả nhật ký "hack" website thằng bạn mình, trình còn non và trong blog chủ yếu múa rìu thôi chứ hong có gì cao siêu hay có ý qua mắt aiiiiiii. Rất mong sẽ nhận được góp ý từ mọi người.
Chân thành cảm ơn ạ! <3
Ơ kìaaaaa hong bị gì luônnnnn?????
Tới lúc này tui bắt tay vào tìm payload đẹp nhất để exploit
=> Chi tiết hơn về kỹ thuật blind sql injection xem thêm tại: , ,...
Như vậy là tui đã xong mặt ý tưởng, bắt tay vào việc nữa thoyyyyyy
Khi mình thử lần đầu 26 ký tự alphabet đều phản hồi về <1s Lúc đấy mình nghĩ mình sai cơ. Ngồi vò đầu bức tóc không nghĩ ra mình sai cái gì :< bất ngờ mình request bằng browser thì chợt nhớ ra ký tự # trong url là 1 id section :D Úissssss hóa ra mình phải url encode cái payload :<<<<< làm mình nghĩ mãi vẫn hong hiểu. Url encode thì tất cả ký tự sẽ chuyển sang hex thì ký tự # là %23