token

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

Tl;dr: Something about JWT.


Trước giờ tất cả những lần mình đi phỏng vấn (ở cả 2 đầu bàn) thì đều hỏi/được hỏi những câu hỏi liên quan đến JWT, và trong tất cả những lần đó thì “alg=none” luôn luôn là đáp án đầu tiên. Nhưng hôm rồi vô tình lượn Twitter mình lại thấy có một câu hỏi khá hay:

Rõ ràng đây là một câu hỏi rất thực tế, vì thực ra rất hiếm gặp những lỗi “ngớ ngẩn” như vậy, đặc biệt khi bây giờ developers đã sử dụng các library JWT một cách đúng đắn hơn rất nhiều. Tuy nhiên “alg=none” không phải là lỗi duy nhất có thể xảy ra với JWT. RFC 8725 chỉ ra rất nhiều “lỗ hổng” có thể xảy ra khi dùng JWT, và “alg=none” chỉ là một trong số đó. Vậy thì, any chance for you, the penetration testers/the bug bounty hunters, to find these JWT bugs?


Có 02 cases thực tế mình đã gặp trong quá trình đi pentest/bug bounty từ trước đến nay liên quan đến JWT. Case thứ nhất và cũng là case thường gặp nhất liên quan đến JWT là lỗi không verify phần signature. Nghe hơi sai sai nhưng đây là sự thật. Có một thực tế là một trong những library về JWT được sử dụng nhiều nhất cũng đã từng làm developer confuse giữa jwt.decode()jwt.verify().

Rõ ràng nếu như developer chỉ dùng jwt.decode() thì sẽ xảy ra trường hợp attacker xoá phần signature nhưng vẫn access được API như hình dưới đây:

Lỗi này lúc trước mình thường xuyên gặp phải, bây giờ thì đỡ hơn nhiều rồi, vì các library đã force phải sử dụng jwt.verify(). Nhưng cẩn thận không bao giờ là thừa, hãy luôn check xem chuyện gì sẽ xảy ra nếu ta xoá phần signature của JWT. Còn nếu tiếp cận theo hướng whitebox thì keyword “.decode()” là một keyword rất đáng để thử.

Case thứ hai, hiếm gặp hơn nhưng không phải là không có khả năng gặp. Theo lý thuyết, suggested key size khi dùng algorithm HS256 là 256 bits – 32 bytes. Tuy nhiên như trường hợp dưới đây thì đúng là “rớt lý thuyết rớt cả thực hành”:


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.


P/s: https://howmanydayssinceajwtalgnonevuln.com

P/s2: https://auth0.com/blog/brute-forcing-hs256-is-possible-the-importance-of-using-strong-keys-to-sign-jwts/

Bug this, bug that #2

Tl;dr: Vô tình tìm được một lỗi có thể làm lộ toàn bộ source code của công ty U, impact tương tự như vụ gần đây nhất của công ty G ở VN. Bug low tech, không chứa quá nhiều hàm lượng kỹ thuật. Nút donate ở cuối bài =]]]]


Chuyện xảy ra vào một buổi chiều đẹp trời, report của mình cho một private program trên HackerOne bị duplicate. Nghĩ cũng đúng, bug dễ tìm quá, low-hanging fruit thì ai cũng tìm được.

Khi khai thác lỗi đó mình có tìm được một token gọi là “gitlab-ci-token“, và có mention trong report. Sau khi report thì mình mới nảy ra ý tưởng: lấy keyword “gitlab-ci-token” này đi search trên GitHub, rất có thể có nhiều công ty/tổ chức/cá nhân cũng đang mắc lỗi này. Nghĩ là làm, mình search ngay, sort theo recently indexed, và nhận được vài kết quả có vẻ khả quan, trong đó có một kết quả là một file json, của một plugin wordpress, thời gian upload lên cũng khá gần. Mình vào thẳng website của plugin đó, tải source về để kiểm tra xem token này là của người dùng upload lên GitHub, hay là của plugin.

Plugin có hai version, free và premium (có trả phí). Mình chọn bản free, được redirect qua trang download plugin. Plugin này nằm trong top popular, với hơn 3 triệu người dùng.

Sorry vì phần censored, lúc đầu mình xin phép được private disclose, che đi thông tin, không ngờ họ hào phóng cho mình full disclose, mà mình lại lỡ che mất rồi.

Sau khi download file zip về, extract ra, mình tìm tới đúng file json đã đề cập ở trên (vendor/composer/installed.json). Vẫn thấy tồn tại token, nghĩa là token này vô tình bị developer plugin cho vào đây, và quên xoá khi release.

gitlab-ci-token“, như tên gọi, là một job token, được mô tả rõ ràng ở đây. Bản chất nó vẫn là token (khác biệt là job token không có quyền write) nên hoàn toàn có thể được dùng để access vào projects như một personal/projects access token, theo cách được mô tả ở đây.

Rõ ràng token này vẫn còn valid, ai có được token này đều có thể access được vào GitLab nội bộ này. Nguy hiểm hơn, token bị leak ra này gần như có quyền trên toàn bộ các projects trong GitLab. Clone thử một cái về để “chứng minh lỗ hổng”:

Fact: Sau khi screenshot thì folder này đã được xoá ngay.

Đủ để chứng minh lỗ hổng rồi, viết ngay một email report. Xác định là làm từ thiện rồi, vì trên homepage mình không tìm được chỗ nào cho email hay có form contact gì cả. May là trong source code vẫn có email của developer ở phần header. Vài tiếng sau thì nhận được email reply, họ báo là đã up lên version mới, xoá cái token bị leak trong source code, revoke toàn bộ token cũ, và đã audit toàn bộ source code để ngăn tình trạng này xảy ra.

Hôm sau thì họ cho mình lên trang acknowledgements, và đương nhiên rồi, report từ thiện thì làm gì có bounty. Tuy nhiên, nếu có ai đó cảm thấy mình xứng đáng được nhận bounty, hoặc cảm thấy (các) bài viết của mình có ích, đừng ngại nhấn nút Click to Donate mời mình một ly cafe nhé =]]]]

Happy hacking!