Phát hiện RCE nhưng... bạn phải đăng nhập trước đã: Câu chuyện CVE của mình với 56.000 host!
Sumary
Bạn có biết rằng có những lỗ hổng nghe có vẻ rất nguy hiểm nhưng lại có một điều kiện 'bé xíu' là bạn phải đăng nhập không? Hôm nay, mình sẽ kể cho các bạn nghe về một lỗi RCE mà mình đã phát hiện và ảnh hưởng đến hơn 56.000 host. Nhưng đừng quá lo lắng, bạn sẽ cần phải đăng nhập để khai thác nó! Lỗi dẫn đến RCE này được định danh CVE-2024-46256 và CVE-2024-46257.
Bối cảnh
Lỗ hổng này xuất hiện trong Nginx Proxy Manager, một ứng dụng web phổ biến sử dụng để quản lý proxy nginx do nhiều bên đang sử dụng. Với hơn 56.000 host bị ảnh hưởng, đây thực sự là một lỗi đáng lo ngại. Và đúng thế, mình đã tìm thấy nó!
Quá trình phát hiện ra lỗ hổng
Nói thật với mọi người, mình đã từng bị ám ảnh với những CVE, mình quay cuồng trong việc tìm lỗi từ các opensource để cố gắng cho mình một cái CVE. Nhưng có lẽ, đúng như mọi người nói, càng cố gắng tìm càng không thấy, đôi khi vô tình lại hay hơn. Đúng vậy, mình đã vô tình phát hiện được cái CVE đầu tiên của mình.
Vẫn là một buổi chiều, mình vô tình tìm thấy một site đăng nhập Nginx Proxy Manage với đường link dẫn tới github [https://github.com/NginxProxyManager/nginx-proxy-manager]
Cũng thử tìm kiếm trên Shodan như hình trên bạn thấy, mình thấy đây là một tiềm năng nào đó cho bản thân. Bắt tay vào tìm thôi nào!!!
Setup hệ thống
Rất may, hệ thống này lại có sẵn docker file để tạo container, với các bước setup đơn giản, mình đã có cho mình một hệ thống mới nhất. Thông tin đăng nhập mặc định cũng được tạo sẵn admin@example.com / changeme
. Bên cạnh đó, mình tải luôn source code bản mới nhất để có thể whitebox cho tiện.
Xác định lỗi
Trước tiên là tìm hiểu hệ thống có gì đã! Thường sẽ thực hiện sử dụng lướt qua để mình hiểu được nghiệp vụ hệ thống. Rồi từ các api thu được mình tra cứu trong code. Hệ thống này sử dụng NodeJS. Đây là một ngôn ngữ mà hiếm khi nào mình sử dụng, việc đọc code ở mức hiểu là vẫn có thể thực hiện được, mình cũng phải áp dụng cả ChatGPT cho việc hiểu được code. Cũng không có nhiều kinh nghiệm liên quan đến research CVE, 1-day gì cả, tất cả đều tự học từ internet. Thiếu đâu thì tìm và đọc đó.
Khi đã hiểu được hết các chức năng và trace được các api trả về được xử lý ở đâu thì mình đã nghiên cứu sâu hơn vào từng file trong folder /nginx-proxy-manager-2.11.3/backend/internal
. Ở đây có một file khiến mình chú ý hơn cả certificate.js
. Tại sao ư? Bởi vì có một số dòng code như thế này:
Theo kinh nghiệm của bản thân, cái gì cộng chuỗi cũng có thể tiềm năng có lỗi. Nhưng khoan, sao lại lộ liễu thế, thử truy ngược lại bản mới này được comment gì khi release không:
Diff patch:
Trong đầu mình đang nghĩ, ủa, sao fix như chưa fix thế nhỉ? Tại sao mình lại nghĩ vậy ư? Thật ra nếu chú ý thì có thể thấy biến certificate.domain_names
Domain name là giá trị chúng ta có thể kiểm soát, đúng vậy, ý tưởng bừng lên, Command Injection rồi!!!
Case này thì quá cơ bản với trường hợp cộng chuỗi rồi, thêm đôi ba cái |
là thành công thôi quá dễ: test.com" || whoami # "
Có thể thấy lỗi trả về không hề trả thông tin gì. Nhưng check debug trong docker có gì nào:
Ohhh! Root
Chính xác là những gì mình cần. Sau đó thì thử các câu lệnh khác cũng tương tự, bật debug check thì quá là ok! Sau đó là thực hiện reverse shell
cũng thành công
Bên cạnh đó, mình đã trace thêm các hàm tương tự thực hiện execute command thì cũng thấy một hàm bị lỗi tương tự.
Report
Sau các bước confirm và viết POC hoàn chỉnh cho lỗi, mình lập tức thực hiện report CVE này đến https://www.cve.org/. Và chờ đợi!
Thật vui khi 2 lỗi report đều được gán CVE với các tên lần lượt là CVE-2024-46256 và CVE-2024-46257, bên cạnh đó, trong lúc chờ đợi lỗi RCE được cấp CVE thì mình cũng tìm được thêm 1 lỗi trên hệ thống và cũng submit, thằng em ngồi trên công ty cứ đùa bữa nay submit như rau ấy nhỉ? Mình cũng chỉ biết cười thôi :v
Kết
Phương án khắc phục tạm thời
Tại thời điểm này, nếu có thể các bạn hãy sửa lại mã nguồn của hệ thống tại vị trí mình có chụp ở phía trên.
Còn một số cách khả dĩ hơn nếu không can thiệp code như:
- Tạm thời giới hạn truy cập vào cổng dịch vụ hoặc không public ra internet
- Thay đổi thông tin đăng nhập với bản docker, và sử dụng mật khẩu mạnh với hệ thống này
- Cách cuối ai cũng biết
Tổng kết
Hãy cố gắng đôi khi thành công sẽ là điều bất ngờ!
Và đừng dùng cộng chuỗi cho các câu lệnh thực thi command trong hệ thống :V
All Rights Reserved