Một lỗ hổng, một câu chuyện riêng, một vẻ đẹp riêng: Em SQLi ngọt nước

Một lỗ hổng, một câu chuyện riêng, một vẻ đẹp riêng: Em SQLi ngọt nước

·

8 min read

Play this article

Okay, giờ là 8h40 27/05/2023. Sau 1 tháng drop bug bounty mình cảm thấy cơ thể như hòa vào vạn vật, có thể nghe hiểu toàn bộ nhạc của Đấng Skyler, nhạc Anh Phan bỗng ý nghĩa và sâu sắc đến lạ thường, những câu joke của vị MC nào đó trở nên thâm sâu và buồn cười khó tả (đến nỗi mình nghe xong phải vỗ đùi bạch bạch bạch), nghe và hiểu được tiếng nói của cá heo, đọc và đ*o hiểu ngôn ngữ máy tính, ...

Mình định xin lỗi vì bỏ bê không viết blog 1 thời gian, nhưng nghĩ lại có ai đọc đâu mà phải xin lỗi =))) nên thôi. Lý do mình bỏ bê vậy không phải vì không biết viết cái gì, mà đơn giản là vì mình không thích (chưa đủ say, chưa đủ vui, chưa đủ buồn, chưa đủ tiền đô nết, ... ). Hôm nay mình quay trở lại với một case SQLi mà mình tìm được trong quá trình beg bounty, và có một điểm đặc biệt là nó sẽ làm rõ một kĩ năng quan trọng mà bạn cần có trong quá trình beg bounty. Kĩ năng đấy là gì thì đến cuối bài viết bạn sẽ rõ, chắc vậy.


24/03/2023, mình nhận được mail mời vào 1 private program trên Intigriti mặc dù mình không active trên đó một thời gian (đoạn này không phải quảng cáo - điểm hay của Intigriti là dù bạn có không active trên đấy một thời gian dài thì họ vẫn mời private program đều đều, không bao giờ bị bỏ quên : D).

Tất nhiên như mọi lần, mình không quan tâm nhiều đến nó. Phải 2 hôm sau mình mới vào ngó qua (vì tự dưng thấy ngứa nghề). Sau vài phút tìm hiểu, mình biết được đây là program của một tổ chức trong ngành Y tế, sức khỏe - một kiểu program mà mình không hứng thú lắm, nhưng mình đã quyết định stick với nó vì nó liên quan đến Y tế, sức khỏe (Nghe có vẻ là mình sẽ làm được một việc siêu tốt nếu tìm ra lỗi trong hệ thống kiểu vậy : D).

Sau 15p ngồi đọc description, scope, out of scope, rule rủng các kiểu và tìm hiểu rõ hơn về tổ chức đó, mình bắt đầu tiếp cận một target trong scope. Program này cũng không nhiều target lắm, vỏn vẹn 4 URL với các chức năng, nghiệp vụ khác nhau. Mở cả 4 target ra và mình chọn target mà bản thân cảm thấy dễ dàng clear nghiệp vụ của nó nhất. Target đó là một trang quản lý xe cứu thương, chuyến xe cứu thương, tình trạng bệnh nhân trên xe, thuốc thang trên xe cứu thương, ... kèm với đó là hóa đơn dịch vụ. Sau khoảng 30p dùng các chức năng, đặt giả thuyết và kiểm chứng, nghĩ đến các trường hợp mà ông dev có thể chưa cover hết, mình vẫn không tìm được bất kỳ lỗi nào liên quan đến nghiệp vụ (hoặc chưa đủ khả năng để nghĩ đến hết, trộm vía đã lái xe cứu thương, đi cấp cứu bao giờ đâu mà biết 🐧). Có 2 thứ làm mình để mắt đến, đó là 2 ô search =))))))))). Nào, kiểm tra bài mới, ô search thì có thể bị lỗi gì ? Trả lời!!

Ok, câu trả lời chính xác, ô search hay bị lỗi XSS và SQLi. Thực ra mindset như vậy hơi máy móc (nếu bạn không hình dung ra chức năng search thường được mấy ông dev code như nào, thì nghĩ kiểu đấy là máy móc, còn nếu hình dung được, thì vẫn là máy móc 🐧). Bỏ qua vấn đề nó có máy móc hay không (hẹn cái đấy ở bài khác), mình sẽ đặt ra giả thuyết hiện tại là những năm cuối thế kỉ 20, đầu thế kỉ 21, cụ thể là 1998 nếu mình nhớ không nhầm, SQLi lần đầu được biết đến thông qua một bài viết của Jeff Forristal aka Rain Forrest Puppy trên Phrack (.:: Phrack Magazine ::. - quà quê cho người anh em nào thích hoài niệm, sống trong quá khứ, quý lắm mới cho đếy). Sau khi đặt ra giả thiết, việc còn lại cần làm là kiểm chứng, tiếc thay mình có một tật xấu, đấy là lười vãi l, nên mình đã để cho Burp Suite làm việc đấy thay mình. Kết quả không quá bất ngờ, sau khi scan HTTP GET request được gửi khi sử dụng chức năng search, Burp Suite chả tìm ra lỗi gì, #surevkl, mong chờ gì ở cái tool mà thằng bug bounty hunter nào cũng có khả năng dùng, được sử dụng bởi đa số người làm trong ngành chứ. Nhưng như mình đã nói ở trên, chúng ta có 2 ô search. Thử scan với HTTP GET request được gửi khi sử dụng ô search thứ 2, kết quả trả về vẫn là số 0 tròn trĩnh. Ngay khi bản thân bỏ quyển sách đang đọc dở, rời giường (ừ, mình pentest/bug bounty hunting trên giường, mình sống như thế đấy bạn) và quyết định múa về khả năng manual hunt đỉnh cao thì mình đã phát hiện ra một thứ đẹp đẽ vô cùng. Đó là option Advanced search (mẹ keep). Thử sử dụng Advanced search, mình nhận ra nó gửi một HTTP GET request hoàn toàn khác, với nhiều trường hơn, và lười thì vẫn là lười, lần này đảm nhiệm trọng trách test vẫn là Burp Suite. Như các cụ nói, quá tam ba bận, lần thứ 3 Burp Suite đã không làm mình thất vọng (sao nó không dump luôn database rồi viết report hộ mình nhỉ 🐧). Xin lỗi vì mình đã xóa project nên không thể show kết quả detect được của Burp Suite, nhưng Burp Suite detect bằng cách này:

  • Đầu tiên, nó thêm một dấu ' vào một trường trong GET parameter, server trả về 500

  • Tiếp theo, nó thêm một đấu ' nữa, khi đấy '' sẽ thành một chuỗi rỗng và query hoạt động bình thường, trả về 200

Burp Suite detect đến đây thôi, mình khá sure nó là SQLi, nhưng nếu chỉ vậy thì chưa đủ đã với một cái SQLi, mục tiêu cuối cùng của một kẻ tấn công không phải thể hiện cho người khác thấy nó biết SQL và có thể thao túng duy nhất 1 cái truy vấn để trả về 500 hoặc 200 (nghe đần vl, thề), mà là dữ liệu của tổ chức, thông tin cá nhân hoặc RCE. Và như một người xấu chuyên nghiệp, mình cũng cố gắng làm thế. Loay hoay 1 hồi, sử dụng SQLmap quét nguyên cái HTTP request, mình thất bại trong việc dump database cũng như RCE vì hệ thống quá chậm, còn bản thân mình thì quá báo. SQLmap cũng chỉ dừng lại ở bước confirm được đó là SQLi. Đoạn scale impact là đoạn mình bổ sung vào report (sau khi đi tắm -> Nếu gặp khó, hãy đi tắm. Không làm được 1 bài CTF, hãy đi tắm.), lúc đầu chỉ với 2 cái request phía trên mình đã viết report rồi : D.

Sau khi đi tắm thành công, mình đã nhớ ra 1 con tool cũng để test SQLi nhưng có 1 cái hay hơn sqlmap, đó là nó có thể detect được những cái sqlmap không làm được - GitHub - r0oth3x49/ghauri: An advanced cross-platform tool that automates the process of detecting and exploiting SQL injection security flaws. Hehe boiz, sau khi thử ghauri với request đó, mình đã thành công lấy được DBMS của target.

Ok, mình biết là các bạn đợi đoàn này lâu lắm rồi đúng không =))) Số phận của cái report như nào á ? Tada

Triager nâng impact lên 9.8, nhưng (đúng vậy, luôn có nhưng)

Impact bị giảm 1 bậc so với ban đầu, với lý do account mình sử dụng để test có quyền cao. Tất nhiên, là một người làm việc vì đam mê, không hề quan tâm bounty cao hay thấp, mình đã ngay lập tức thắc mắc vì chưa clear vụ phân quyền, vì theo mình thấy, account mình được cấp hoàn toàn không có quyền cao. Ngay sau đó, program owner (người trong công ty) đã reply lại, giải thích rất rõ ràng, nghe cũng bùi tai, hợp lý nên mình ôm tiền về.

Câu chuyện vẫn không dừng lại ở đấy, hôm sau (ngay sau khi đi tắm🐧), mình test lại và phát hiện ra không chỉ có 1 parameter đấy có thể bị SQLi, mà còn thêm 2 parameter nữa, và lần này mình có thể dump được toàn bộ db bằng cách sử dụng ghauri (thấy lợi ích của việc đi tắm chưa?). Vẫn là câu chuyện tính tiền theo lỗi hay parameter, nhưng kệ, tìm ra thì tội đ*o gì không report. Mất thêm tầm 1 tháng trao đổi giữa mình, triager và owner, tất cả đi đến thống nhất là sẽ không có thêm đồng nào cho mình, không bonus cho đống parameter mà mình tìm thêm. Mình cũng hài lòng sau tất cả, cũng không muốn presssing một công ty làm viêc liên quan đến y tế sức khỏe (nghe mất dạy vl). Câu chuyện kết thức bằng một câu gáy khét của mình, và màn tung hứng lại của owner:

Thế tóm lại, kĩ năng cần thiết của beg bounty hunter là gì? Đi tắm à? Không, kĩ năng mình nói đến ở đây là may mắn. Ừ, may mắn đấy. "May mắn cũng là một kĩ năng." Đó là một câu nói mình nghe từ người bạn cũ - một người cực kì đỉnh nhưng hiếm khi gặp may mắn trong thi cử hay học hành...

Okay, bài hôm nay đến đây thôi. Đm viết nhiều quá hashnode bị lag, mình gõ bị delay cmnl. Mình đi úp vội bát mì ăn đây, chưa ăn gì cả. Đời beg bounty hunter nó bạc vậy đấy, nếu ai muốn nếm thử 4 chữ Hào quang rực rỡ thì ... thôi dẹp mẹ đi.

10h28, 27/05/2023. Gud night.

Vừa làm xong cái banner, banner làm trong 1p31s nên chỉ có thế thôi, xem thì xem không xem thì xem.