rce

Bug this, bug that #6

Tl;dr: from recon to RCE.


Hello, long time no see.

Nếu bạn theo dõi series vớ vẩn này đủ lâu thì sẽ nhận ra cái quy trình tìm bug của mình thường thường là dạo vòng ngoài, tìm các bug unauthenticated (nếu có) trước, sau đó mới đến bước register/login để tìm các bug authenticated. Dễ dàng nhận thấy tìm bug kiểu như vậy thì khả năng thấy bug ngay khá là thấp, nhưng nếu có bug thì có thể sẽ là một bug to. Mình nghĩ đó là một kiểu đánh đổi thôi, mình sẽ không có lợi thế so với các bạn khác, ví dụ các lỗi XSS hay IDOR (broken access control) thì thường thường không đến lượt mình, còn nếu lỡ như có bug gì unauthenticated thì mình hốt ngay được. À mà xác suất để tìm được unauthenticated RCE thì còn thấp hơn nữa, nên đây là một cách tìm lỗi thất bại, hi vọng trong các bạn không có ai học theo mình =]]

Tuy nhiên xác suất thấp không có nghĩa là không thể xảy ra, cuộc sống mà, không nên đánh mất hi vọng. Target lần này là một trang khá cũ, chạy PHP, cũng không có nhiều chức năng. Fuzz nhẹ thì thấy directory listing ở gần như tất cả các directory:

Cái folder filemanager kia có vẻ hay ho, nhảy vào xem thử thì đúng là hay ho thật. Có 2 files đáng lưu ý ở đây:

  • filemanager.php, file này cần username và password để authentication:
  • phpfm.png, có vẻ như là một screenshot:

Với chừng này thông tin, mình đi search trên Google, và tìm thấy một repository trên GitHub, nhìn rất tiềm năng: https://github.com/alexantr/filemanager/:

Không cần phải tinh mắt lắm mới có thể nhận ra file phpfm.png trong folder filemanager trên server và screenshot trong repository là hoàn toàn giống nhau. Quay lại đọc code, cũng không khó để tìm thấy default username và password là fm_admin:fm_admin.

Một pha ăn may đỉnh cao khi mình dùng credential này và log in thành công:

Cũng giống như mọi bài toán đều dễ khi ta biết đáp án, lần này mọi chuyện cũng bớt khó khăn hơn rất nhiều khi ta có source code (lại còn không dài, không phức tạp). Theo như source code, để tìm path upload, mình chỉ cần view-source (sau khi đã login thành công):

Đến đây thì thôi coi như xong rồi. Được upload tuỳ ý, lại còn biết path upload, tiếp tục làm đúng theo các bước trong source code từ repository trên GitHub, mình thực hiện tạo folder và upload cái phpinfo() làm PoC lên server thôi:


Thêm một lần nữa ăn may, ai mà có ngờ từ directory listing -> reconnaissance -> default credential -> arbitrary file upload -> RCE được, nhỉ.

Dịch bệnh càng ngày càng phức tạp, không biết đến khi nào mới được trở về cuộc sống bình thường nữa, mọi người cố gắng ở nhà, hạn chế ra ngoài, giữ sức khoẻ nhé. Dịch bệnh ai cũng khó khăn, treo donate tiếp thì cũng kỳ, nên nếu mọi người cảm thấy bài viết của mình có ích thì thay vì donate cho mình, mọi người có thể giúp đỡ cho các hoàn cảnh khác khó khăn hơn quanh khu vực mình đang sống nhé. Cám ơn mọi người nhiều nhiều.

Stay safe and happy hacking!

Bug this, bug that #4

Tl;dr: Abuse a feature to achieve Root Command Injection. Original report: https://whitehub.net/submissions/2039.


Hơn bốn tháng trời không viết nổi một bài, bờ-lốc bờ liếc mốc meo phủ bụi, cũng muốn viết lắm, nhưng mà làm gì có bug đâu mà viết 😭

May sao tháng trước sàn WhiteHub có email thông báo có program mới, cũng không trông mong gì nhiều, vào xem thử cho biết. Lúc nhìn target thú thực mình cũng không muốn làm cho lắm, lý do thì chắc các bạn cũng sẽ hiểu được khi xem hình dưới đây:

Nhưng thôi đang trong giai đoạn khó khăn, 🍚 👕 🌾 💰, kiếm được đồng nào hay đồng nấy, mình thử mở Burp (tất nhiên là Community Edition) lên xem thế nào. Sau khi lướt qua một vòng thì mình thấy có tính năng Add link YouTube, tính năng này mình cũng đã có gặp một vài lần ở những program khác, vì vậy nên không khó lắm để mình tìm được lỗi SSRF ở đây:

Tuy nhiên nếu chỉ dừng lại ở scan internal port và leak service banners thế này thì impact cao nhất có thể chỉ là Medium. Mà nhìn cái “bảng giá” ở trên thì…

Nhìn kỹ hơn một tí, trong response trả về có một điểm hơi lạ, nhìn có vẻ như là một warning/error khi chạy command line vậy. Đi search keyword youtube-dl, biết được đây là một tool cho phép download video từ YouTube từ CLI. Linh tính mách bảo mình: ở đây có bug, rất có thể sẽ inject được gì đó.

Để kiểm chứng, mình thử nhập các ký tự đầu lâu xương cá, đặc biệt là các ký tự như , , &, |, >, `… vào phía sau http://localhost để xem kết quả trả về là gì. May mắn, không lâu sau thì mình có một kết quả khả quan:

Input: http://localhost'; || `id`'
Output: "/bin/sh: -c: line 0: syntax error near unexpected token `||'\n/bin/sh: -c: line 0: `youtube-dl  -J 'http://localhost'; || `id`''\n"

Ngoài lề, chỗ này chắc sẽ có bạn hỏi sao không có hình cho trực quan, cho dễ nhìn, thì xin thưa là do xài Burp Community Edition, không có chức năng save state, nên lỡ tay bấm tắt project là mất luôn, text thì do copy ra để debug nên còn chứ hình thì không kịp chụp 😂 để cố kiếm bug rồi đầu tư bản Pro, mạnh dạn nói “Không” với hàng crack nhé ahihi.

Quay lại chủ đề chính, có error như kia thì khá rõ ràng rồi. Input của mình sẽ được truyền thẳng vào câu lệnh download, mình đoán kiểu có dạng như sau:

`youtube-dl  -J '$input'`

Việc của mình bây giờ chỉ là inject payload sao cho đúng chỗ và work 🙂 payload thì đơn giản nhẹ nhàng thôi:

http://localhost'; id; echo '

Chạy command dưới quyền root như này thì thôi, còn gì để nói nữa. Viết nhanh cái report chứ không thì lại là người đến sau mất, dù biết là report nếu viết gấp nó sẽ không ra thể thống gì cả, không được đàng hoàng như trên blog, nhưng thôi kệ, “cuộc đua số” mà, đành chấp nhận. Cũng may trời thương, không duplicate. Team xử lý rất nhanh, chỉ trong khoảng 3 tiếng từ khi mình report là issue đã được triaged, fixed, resolved và bounty rewarded.

Bounty 2 triệu, đóng thuế hết 10% còn 1 triệu 800 nghìn, hơn bốn tháng kiếm được một bug (vừa đúng bằng thời gian giãn cách giữa hai bài #3 và #4). Còn buồn hơn nữa, khi bài viết này được đăng cũng là lúc program tăng giá gạo lên thành 5 triệu cho một lỗi critical 🤦

Quay qua quay lại mất hẳn 3 triệu, đúng thật làm IT giàu, nhưng chắc là giàu tình cảm… tuy nhiên thiết nghĩ tình cảm thì nên được thể hiện đúng chỗ, mà chỗ đúng là Click to Donate (PayPal) hoặc chỗ này (MoMo) nhé các bạn, donate cho mình có tiền trả tiền thuê server với, chân thành ghi ơn 🙏

Happy hacking!

Cú lừa

Cuộc sống đâu lường trước điều gì… Lại tiếp tục chuỗi ngày ngồi cafe tìm bug dạo thôi các bạn ạ… Bug càng ngày càng khó kiếm, cuộc sống thì khó khăn, ngày xưa còn uống cafe size lớn giờ chuyển xuống uống size vừa… hic…

Hôm trước vừa giới thiệu case exposed folder /.git/, dẫn đến việc lộ source code (bạn nào chưa đọc thì có thể đọc ở đây) xong, thì sau đó một thời gian ngắn, mình lại gặp lại một case tương tự. Tuy nhiên, lần này hơi khác, khi mình check đến folder /.git/ của website thì thấy status code 403 – Forbidden.

Kiểu này là có thanh niên nào nhanh tay report mất rồi. Thường thì “gặp 403 ta cho qua”, tuy nhiên trong trường hợp này thì không nên. Bởi vì rất nhiều sysadmin không biết fix lỗi này hoặc fix không triệt để, dẫn đến việc mặc dù bị forbidden nhưng mình vẫn có thể khai thác bằng cách truy cập thẳng vào /index hoặc /config như hình:

Đọc được file index có nghĩa là mình hoàn toàn có thể đọc được source code, đơn giản chỉ cần ném vào gitdumper.

Trường hợp ngon lành, download được source về thì kiếm file nào có sensitive information mà đọc thôi, ví dụ như:

Leak được info này thực ra cũng không làm được gì nhiều, vì IP internal…

Nhưng mà cuộc đời đâu phải chỉ toàn màu hồng… Có những trường hợp không download được, có thể là do folder /.git/ này đã cũ, có download về được thì cũng chỉ được vài file code cũ hoặc file rác. À nói rác vậy thôi chứ cũng không đến nỗi rác lắm… mấy ông sysadmin hay có kiểu fix thôi chứ không đổi password đâu, biết đâu còn ăn may được…

Nhìn cái kiểu đặt password kia thì khả năng cao là password này dùng chung rồi. Cầm đi login thử, không ngờ vào được admin thật…

Mà với WordPress, đã vào được admin thì nghĩa là đã có RCE…

Thật không may, dưới quyền nginx không chỉ có mỗi WordPress mà còn chạy nhiều thứ khác với kha khá critical info… ls một cái rồi viết report cho nhanh, mất công lại duplicate thì khổ.

Hihi, nói RCE nghe đao to búa lớn vậy thôi chứ thực ra root cause vẫn chỉ là weak/reused password. Mà kệ chứ, cứ có bug là đời đỡ buồn hơn một tí rồi. Mai mạnh dạn gọi ly cafe size lớn, happy hacking!

Test tool và cái kết

Khai trương blog mới bằng một case mình mới gặp gần đây. Case này thì khá là đơn giản (nếu không muốn nói là rất dễ, ai cũng làm được, không hề có kỹ thuật gì cao siêu, rất cơ bản). Mấu chốt để mình có thể tìm được bug này theo mình là “đúng thời điểm”.

Lúc trước viết write-up nhiều, nên được các lãnh đạo ưu ái cho làm writer trên blog tradahacking.vn. May sao số view vừa đủ để được tặng một vé dự Trà đá Hacking #8, vé tận mấy trăm nghìn. Bỏ thì tiếc, mà đi thì không biết đào đâu ra tiền mà đi (nói mọi người không tin, chứ đến tận lúc viết bài trong tài khoản mình còn không tới nổi 100k, đứa nào nói điêu làm :dog: sủa gâu gâu).

Chợt nhớ lại mấy target bug bounty ở VN thời gian trước mình có làm, tầm gần nửa năm về trước. Tại sao lúc đó mình chọn những target VN? Dễ thôi, thứ nhất mình là người Việt, nên những target VN mình sẽ dễ dàng hiểu được flow chương trình hơn; thứ hai mình muốn ủng hộ “hàng Việt”, thay vì để đám hacker nước ngoài phá thì thôi để mình làm cho, ít thiệt hại hơn; thứ ba, tại thời điểm đó mình không/chưa đủ trình làm mấy target trên HackerOne hay Bugcrowd các kiểu. Trên đó tiền bounty toàn mấy anh trong private program lượm hết, còn public thì chỉ có đợi định mệnh gọi tên. Cựu đồng nghiệp của mình RCE còn bị duplicate nữa thì hiểu rồi. Nên thôi, ta về ta tắm ao ta, mặc dù tiền ít, nhưng được một cái là ít người tranh giành hơn, may ra còn sót được vài bug low-hanging fruit cho mình lượm.

Thế là mình bắt tay vào thử tìm bug, với tâm thế là không còn gì để mất. Có bug thì mình book vé đi Hà Nội chơi Trà đá Hacking, không thì đành ở nhà hóng các idol từ xa vậy :((

Bởi vì đây là một target cũ, trong một chương trình public bug bounty, mình đã làm khoảng nửa năm rồi, nên mình sẽ skip qua phần subdomain enumeration, cho đỡ tốn thời gian.

Ơ khoan đã! Nửa năm rồi, làm sao biết được không có subdomain mới?

Tình cờ, hai ngày trước, kênh Telegram The Bug Bounty Hunter suggest một tool tìm subdomain mới, với description rất kêu: “The fastest and cross-platform subdomain enumerator, don’t waste your time“. Thôi thì nhân tiện, thử tool mới xem sao.

Clone về, chmod rồi run thử. Tool chạy khá nhanh, và cho kết quả khá nhiều. Lướt xem thì đúng như dự đoán, có một subdomain mới. Truy cập vào thì thấy một trang trắng trơn. Đúng hơn là có vài option cho chọn, nhưng chẳng có gì xuất hiện, hơn nữa còn đòi quyền access location. Với “bản năng” của một người làm web (=]]]]), mình view source, tìm xem có chỗ nào khả nghi không. Lại tình cờ, hôm trước mình vừa đọc một bài viết của một idol bằng tuổi, bài viết bảo rằng muốn tìm bug low-hanging fruit thì nên chăm nhìn vào các file javascript. Mình thì rất tin các idol, nên mình check /js/script.js. Trời không phụ lòng người, mình thấy một endpoint khá thú vị.

OK, access thử vào endpoint xem. Thật bất ngờ, APP_DEBUG đang bật, và…

Username và password rành rành ra thế kia thì lấy submit thôi chứ đợi gì nữa. Soạn một report cực kỳ tâm huyết, đầy đủ các bước từ lúc subdomain enumeration đến khi leak được username/password, rồi nhấn submit. Tắt máy đi ăn.

Ơ khoan đã! Cứ thế mà submit thì nó lại không hay, vì không có impact gì cụ thể cả. Mình tự hỏi với username và password đó không biết mình còn có thể làm gì được nữa không? Thế là như một thói quen, mình ném cái domain này vào nmap. Còn tại sao cái này được gọi là “thói quen” thì… ahihi.

Đây rồi, port 22 đây rồi. Thử ssh vào bằng username và password trên kia thử, biết đâu bất ngờ. Ơ mà bất ngờ thật…

Tới đây thì còn gì để nói nữa đâu hả những người anh em thiện lành :))

À đâu, còn chứ. Chuyện nó cứ thế mà kết thúc thì có gì là hấp dẫn đâu. Cứ tưởng có tiền bù được tiền vé đi Trà đá Hacking, không ngờ… 

Đời không như là mơ các bạn ạ :((