recon

Ai cũng có lúc mắc sai lầm #3

Tl;dr: Chiếm quyền admin một trang nội bộ của một mạng xã hội bằng social engineering.


Mình là người rất thích đồ công nghệ, máy tính, màn hình, điện thoại,… các thứ. Nhưng mà sau một thời gian “chạy đua” sắm đồ công nghệ, mình nhận ra mình đang làm chuyện vô nghĩa, tốn tiền vô ích. Một cái điện thoại mới, máy tính mới chỉ làm ta vui vài ngày, rồi lại chán. Đồ công nghệ mạnh thật đấy, nhưng đôi lúc nhu cầu ta không đến mức đó, chỉ cần vừa đủ. Nghĩ được như thế rồi nhưng mình vẫn không bỏ thói quen lướt các trang tin công nghệ khoảng 10-15 phút mỗi ngày, lướt không phải để mua mà chỉ để đọc thêm tin tức, biết thêm nay có chip gì, hãng A có công nghệ gì mới, hãng B có tai nghe gì hay,…

Một ngày đẹp trời, vẫn như thói quen đọc tin tức hàng ngày trên một trang mạng xã hội của Việt Nam, mình bắt gặp một video khá thú vị, video giới thiệu một bộ sản phẩm của hãng L, nghe bảo giá lên tới $5000. Mình cũng đang dùng đồ của hãng này, nên click vào xem review. Xem khoảng chừng gần 02 phút thì mình phát hiện một thứ có vẻ hay ho. Đây là screenshot lúc đó:

Tinh ý thì bạn sẽ thấy anh này đang dùng ứng dụng nhắn tin T ở bên trái, và có vẻ anh ấy dùng Saved messages để take note: gửi file, gửi preview, gửi bookmark link…; còn bên phải là một trang web. URL trong thanh chat khá rõ, nên mình pause video lại rồi gõ URL đó thử vào browser. Đây là giao diện trang web sau khi mình gõ vào và nhấn Enter:

Chắc nhiều người cũng đồng ý với mình rằng bất kỳ việc gì, nếu ta làm đủ nhiều thì ta sẽ hình thành được một cái “sense” nhất định. Mình làm trong ngành này cũng được vài năm, bắt đầu từ việc tò mò về password, nên may mắn có “sense” “đánh hơi” được password khá tốt. Mình đoán cái dòng dưới URL là password, khá chắc chắn.

Nhưng để login được thì còn cần email. Đây là lúc social engineering phát huy tác dụng. Mình theo dõi diễn đàn/mạng xã hội này đủ lâu để có thể biết được quy cách đặt email của họ. Thay vì dùng họ tên thì họ dùng nickname, may mắn là mình cũng theo dõi đủ lâu để biết được nickname của một số admin, moderator. “Thử và sai” – may mắn mình đúng ngay lần đầu thử:

Mình có tìm hiểu sơ qua thì biết được ứng dụng Metabase này là một ứng dụng dạng BI (Business Intelligence), cho phép chia sẻ data và analytics trong tổ chức. Người dùng có thể “Ask a question” – Metabase có một thứ gọi là question builder – dựa trên các câu truy vấn dựng sẵn. Hoặc người dùng cũng có thể tự truy vấn SQL bằng SQL editor. Tài khoản mình vào được, may mắn là tài khoản admin, có quyền cao nhất. Từ đó mình có toàn quyền truy vấn vào cơ sở dữ liệu (nội bộ) của diễn đàn/mạng xã hội này.

Để chứng minh impact thì mình có chụp tấm hình này gửi cho admin của diễn đàn:

Sau khi nhận được report nhanh của mình thì admin cũng nhanh chóng đổi password, rà soát lại server, và tất cả những gì mình nhận được sau khi report là một câu cám ơn:

Nói chung thì mình cũng không đòi hỏi gì cả, mình vẫn report từ thiện như vầy rất nhiều lần, có đôi khi lời cám ơn còn không được nhận. Mình tin là ở hiền gặp lành, cứ làm việc tốt, mình thấy vui là được. Hi vọng có bạn đọc nào đọc được bài này, và cũng bắt đầu “report từ thiện” giống mình – nếu có vô tình thấy được lỗi – để giúp thêm được một cá nhân/tổ chức nào đó tự bảo vệ được mình trong cái thế giới internet càng ngày càng loạn lạc này. Nếu có bug bounty program thì tốt, không thì thôi, gửi cho họ một cái email báo lỗi đàng hoàng, chắc họ cũng không bỏ qua.


Nếu các bạn nghĩ bài viết này có ích thì có thể mời mình một ly cà phê, hoặc tạo thêm động lực viết bài cho mình bằng cách giúp mình duy trì blog qua PayPal hoặc MoMo. Chân thành cám ơn lòng tốt của mọi người.

Happy hacking!

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!

Code bẩn #1

Tl;dr: viết một (quick, dirty and easy) script để tìm kiếm/theo dõi keywords trên GitHub.


Câu chuyện bắt đầu khi mình vô tình tìm được một vài “lỗi” dạng information disclosure trên GitHub của một công ty ở VN. Information disclosure thì cũng có this có that, dăm ba cái full path, version,… thì thôi bỏ đi, chứ những thứ sensitive như là hardcode secret, API keys, authorization token,… thì đáng được đưa vào report. Developers của công ty này, uhm, thường xuyên push code lên GitHub và sẵn tiện thì hay kèm thêm username/password/URL/token… trong repository luôn. Ờ thì, thấy lỗi, tìm cách report, may mắn thì có bounty, không may thì nhận lời cám ơn, không may nữa thì bị bơ luôn, chuyện bình thường. Chuyện sẽ không có gì để nói nếu developers của bên công ty đó không chơi trò mèo vờn chuột với mình: mình phát hiện lỗi, report cho công ty, họ gỡ xuống, vài hôm sau lại thấy ông khác đẩy code khác lên, vẫn có “hàng nóng” kèm theo, lại report. Ban đầu mình tìm thủ công, sau đó thấy bên này lặp đi lặp lại khoảng gần chục lần, nên mình nảy ra ý tưởng là đi tìm tool hoặc viết tool tìm tự động cho nhanh.

Thực ra ý tưởng này hoàn toàn không mới, bằng chứng là khi đi dạo một vòng trên GitHub bạn có thể dễ dàng tìm được những tool/script với công dụng tương tự và hoạt động rất hiệu quả, đã được dùng từ rất lâu rồi, ví dụ như gitleaks, gitGraber,… Chính GitHub cũng đề cập cũng như cảnh báo việc developer ném sensitive information lên GitHub, và cho phép secret scanning đối với cả public lẫn private repository để hạn chế tình trạng trên. Nhưng kết quả thì cũng không khá hơn là bao, đơn giản thôi, vì ai cũng có lúc mắc sai lầm.

Tuy nhiên, có vài điểm trong các tool public này hơi không đúng ý mình lắm, sửa lại thì cũng được nhưng khá mất công, mình thì lười, nên thôi, viết script tìm luôn cho nhanh. Như đã đề cập ở trên, developers có thói quen vứt sensitive information lên GitHub, và trong code push lên thường có mention đến domain, nên mình sẽ thực hiện tìm kiếm chủ động, và theo dõi (monitor) các keyword liên quan đến domain của công ty (target) mình nhắm đến. Không phải lúc nào mình cũng rảnh để vào GitHub search rồi sort theo recently indexed, nên mình code một (quick and dirty) script để làm hộ. Ý tưởng của mình rất đơn giản: tìm kiếm thông tin về domain (keyword) của target bằng cách search trên GitHub, đếm số lần xuất hiện của keyword, lưu vào một database, cho chạy cronjob. Nếu số lần xuất hiện của keyword thay đổi nghĩa là vừa có code mới được push lên, lúc này database sẽ được update số lần xuất hiện của keyword, đồng thời sẽ có thông báo qua Slack/Telegram/Discord,… mình chỉ việc vào check repository mới nhất có chứa keyword bằng link Slack/Telegram/Discord vừa send.

Trong các quảng cáo thường có câu: “Đọc kỹ hướng dẫn sử dụng trước khi dùng”, cá nhân mình thấy câu này xứng đáng 10 điểm. RTFM, ta biết được GitHub có cung cấp Search API đầy đủ và rõ ràng cho chúng ta sử dụng, chỉ cần vào Developer settings tạo cho mình một Personal access token với permission phù hợp. Trường hợp này mình chỉ muốn search theo keyword thì đơn giản chỉ cần dùng:

import requests

url = 'https://api.github.com/search/code?q="%s"'
header = {'Authorization': 'token github-personal-access-token'}
r = requests.get(url % keyword, headers=header)

Ở response sẽ có rất nhiều thông tin, tuy nhiên mình chỉ cần đếm số lần xuất hiện của keyword, nên chỉ cần quan tâm field total_count.

print(r.json()['total_count'])

Phần database mình dùng thư viện mysql.connector, code kiểu như:

mydb = mysql.connector.connect(
  host='localhost',
  user='',
  password='',
  database='githubmonitor'
)

Phần send notification mình chọn Telegram, tham khảo thêm cách tạo bot tại đây. Code khá đơn giản, à mà lấy trên Google thì lại chả dễ =]]

def telegram_bot_sendtext(bot_message):
    bot_token = ''
    bot_chatID = ''
    send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + bot_chatID + '&parse_mode=Markdown&text=' + bot_message
    response = requests.get(send_text)

    return response.json()

Đến đây thì phần cắt ghép cũng coi như xong rồi, chỉ cần thêm một chút magic nữa để script hoạt động trơn tru. Tận dụng con VPS $5/tháng sống bằng tiền donate của các bạn để chạy cron, thời gian thì tuỳ các bạn, mình thì chọn 5 phút, máy chạy chứ mình có chạy đâu mà lo. Kết quả sẽ là dạng như thế này:

Script này hoạt động tốt nhất với các trường hợp monitor một hoặc nhiều keyword/domain của một công ty cùng lúc (dạng internal hunting), nếu keyword hoặc domain đó unique nữa thì càng tốt. Ưu điểm (và cũng là nhược điểm) của phương pháp này là bạn chỉ biết được có keyword xuất hiện, còn ở đâu thì bạn phải tự check repository thủ công, do đó rất dễ gặp trường hợp false positive. Với mình thì không vấn đề gì, vì mục đích mình muốn như vậy, còn với các bạn thì tuỳ nhu cầu sử dụng thực tế mà các bạn hoàn toàn có thể phát triển thêm.

Spoiler: Bài này chỉ là bài chia sẻ, không phải bài hướng dẫn. Mình cũng không phải developer cao siêu gì, code nhanh code vội, quan trọng dùng được, nên các siêu nhân nhìn vô code sẽ rất ngứa mắt. Code này có lẽ còn chứa nhiều potential critical security issues. Code bẩn, code bẩn, code bẩn, cái gì quan trọng nhắc ba lần, nên mong các chuyên gia nếu có vô tình ghé mắt qua đây thì bỏ qua cho em, góp ý hoặc donate thì em xin nhận, còn gạch đá thì thôi, em cám ơn nhiều.

Full script: here. Good luck =]]]]


Như thường lệ, nếu bạn cảm thấy bài viết có ích thì có thể giúp mình duy trì VPS thông qua PayPal hoặc MoMo, cám ơn các bạn rất nhiều!

Happy hacking!