nǝıH
Active Member
-
23/03/2020
-
24
-
37 bài viết
Phân tích lỗ hổng RCE trong các dịch vụ WSO2 (CVE-2022-29464)
CVE-2022-29464 là lỗ hổng nghiêm trọng dẫn đến RCE ảnh hưởng đến các ứng dụng của WSO2 bao gồm API Manager, Identity Server, Enterprise Integrator. Lỗ hổng này xảy ra do tính năng upload file và không kiểm tra nội dung mà người dùng gửi lên dẫn đến lỗi Path Traversal. Từ đó kẻ tấn công có thể upload file mã độc vào vị trí tùy ý trên server.
Dựa vào POC đã công khai có thể thấy vị trí lỗ hổng ở /fileupload được xử lý bởi class FileUploadServlet. Và /fileupload không được bảo vệ (secured=”false”) trong cấu hình của file indetity.xml.
Khi FileUploadServlet được khởi tạo thì phương thức init() cũng được chạy. Init sẽ phân tích file cấu hình carbon.xml để chọn ra đối tượng phù hợp xử lý các loại file khác nhau được tải lên.
Contructor của FileUploadExecutorManager gọi đến phương thức loadExecutorMap().
loadExecutorMap() là phương thức để tải file cấu hình trong file carbon.xml.
Sau đó tạo một HashMap <Action, Class>. Giá trị Action và Class được lấy trong file cấu hình và sau này được dùng để chọn ra Class để xử lý theo đúng Action (HashMap khai báo một đối tượng là executorMap).
Khi gọi đến /fileupload với method POST, phương thức doPost() của FileUploadServlet sẽ được gọi.
doPost() sau đó sẽ gọi đến fileUploadExecutorManager.execute().
execute(): đầu tiên thực hiện cắt theo chuỗi “fileupload/” để lấy string sau “fileupload/” và lưu vào biến actionString.
actionString sau đó được truyền vào CarbonXmlFileUploadExecHandler() cùng với request và response. Các giá trị này lưu vào constructor.
Đối tượng carbonXmlExecHandler sau đó được truyền vào execHandlerManager.addExecHandler(carbonXmlExecHandler);
Sau đó execHandlerManager.startExec() được gọi, startExec gọi đến execute()
Vòng lắp lấy giá trị trong executorMap ra và so sanh với actionString nếu giống nhau sẽ gọi đến executeGeneric() (Sửa lại giá trị của actionString thành 1 trong số 10 giá trị trong executorMap).
Sau đó trong hàm executeGeneric() gọi đến parseRequest với tham số là request.
ParseRequest thực hiện kiểm tra xem có phải yêu cầu POST multipart không, kiểm tra kích thước file…
Sau khi thực hiện parseRequest(), exetuteGeneric gọi đến phương thức execute(). Phương thức này bị lỗi Path Traversal khi tin đầu vào (“name”) do người dùng truyền vào.
Với giá trị uuid được trả lại trong response ta có thể biết được vị trí file upload được lưu.
Ở đây chỉ cần lợi dụng lỗ hổng Path Traversal (“../../”) để thoát khỏi thư mục tmp và upload file jsp vào vị trí dịch vụ web của WSO2. Vị trí được sử dụng ở đây là authenticationendpoint:
./repository/deployment/server/webapps/authenticationendpoint.
POC:
Hướng dẫn giảm thiểu lỗ hổng có thể tham khảo ở đây: https://docs.wso2.com/display/Security/Security+Advisory+WSO2-2021-1738
Dựa vào POC đã công khai có thể thấy vị trí lỗ hổng ở /fileupload được xử lý bởi class FileUploadServlet. Và /fileupload không được bảo vệ (secured=”false”) trong cấu hình của file indetity.xml.
Khi FileUploadServlet được khởi tạo thì phương thức init() cũng được chạy. Init sẽ phân tích file cấu hình carbon.xml để chọn ra đối tượng phù hợp xử lý các loại file khác nhau được tải lên.
Contructor của FileUploadExecutorManager gọi đến phương thức loadExecutorMap().
loadExecutorMap() là phương thức để tải file cấu hình trong file carbon.xml.
Sau đó tạo một HashMap <Action, Class>. Giá trị Action và Class được lấy trong file cấu hình và sau này được dùng để chọn ra Class để xử lý theo đúng Action (HashMap khai báo một đối tượng là executorMap).
Khi gọi đến /fileupload với method POST, phương thức doPost() của FileUploadServlet sẽ được gọi.
doPost() sau đó sẽ gọi đến fileUploadExecutorManager.execute().
execute(): đầu tiên thực hiện cắt theo chuỗi “fileupload/” để lấy string sau “fileupload/” và lưu vào biến actionString.
actionString sau đó được truyền vào CarbonXmlFileUploadExecHandler() cùng với request và response. Các giá trị này lưu vào constructor.
Đối tượng carbonXmlExecHandler sau đó được truyền vào execHandlerManager.addExecHandler(carbonXmlExecHandler);
Sau đó execHandlerManager.startExec() được gọi, startExec gọi đến execute()
Vòng lắp lấy giá trị trong executorMap ra và so sanh với actionString nếu giống nhau sẽ gọi đến executeGeneric() (Sửa lại giá trị của actionString thành 1 trong số 10 giá trị trong executorMap).
Sau đó trong hàm executeGeneric() gọi đến parseRequest với tham số là request.
ParseRequest thực hiện kiểm tra xem có phải yêu cầu POST multipart không, kiểm tra kích thước file…
Sau khi thực hiện parseRequest(), exetuteGeneric gọi đến phương thức execute(). Phương thức này bị lỗi Path Traversal khi tin đầu vào (“name”) do người dùng truyền vào.
Với giá trị uuid được trả lại trong response ta có thể biết được vị trí file upload được lưu.
Ở đây chỉ cần lợi dụng lỗ hổng Path Traversal (“../../”) để thoát khỏi thư mục tmp và upload file jsp vào vị trí dịch vụ web của WSO2. Vị trí được sử dụng ở đây là authenticationendpoint:
./repository/deployment/server/webapps/authenticationendpoint.
POC:
Hướng dẫn giảm thiểu lỗ hổng có thể tham khảo ở đây: https://docs.wso2.com/display/Security/Security+Advisory+WSO2-2021-1738