Giới thiệu
TeamCity là một máy chủ tích hợp liên tục (CI) và công cụ quản lý xây dựng (build) mạnh mẽ. Với khả năng tự động hóa các quy trình thường xuyên, nó giúp cải thiện sự hợp tác giữa các nhóm phát triển và tối ưu hóa quy trình phát triển phần mềm.
CVE-2023-42793
CVE-2023-42793 là một lỗ hổng nghiêm trọng cho phép kẻ tấn công vượt qua xác thực và chiếm quyền quản trị (admin), dẫn đến khả năng thực thi mã từ xa (RCE). Lỗ hổng này không chỉ ảnh hưởng đến bảo mật của hệ thống mà còn có thể được khai thác để chiếm quyền kiểm soát toàn bộ ứng dụng.
Thiết Lập Môi Trường
Để thử nghiệm lỗ hổng này, tác giả đã sử dụng Docker và thiết lập gỡ lỗi trên cổng 5005 với lệnh sau:
bash
docker run -dt -p 8111:8111 -p 5005:5005 -e TEAMCITY_SERVER_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 jetbrains/teamcity-server:2023.05.3
Khác Biệt Giữa Các Phiên Bản
Sau khi so sánh hai phiên bản của TeamCity, tác giả nhận thấy rằng đường dẫn wildcard đã bị loại bỏ trong jetbrains.buildServer.controllers.interceptors.RequestInterceptors
.
Lỗi Bỏ Qua Xác Thực
Qua việc đặt điểm gỡ lỗi tại jetbrains.buildServer.controllers.interceptors.RequestInterceptors#RequestInterceptors
, tác giả nhận ra rằng giá trị của XmlRpcController.getPathSuffix()
là /RPC2
, dẫn đến lỗi bỏ qua xác thực.
Trong quá trình khởi tạo RequestInterceptors
, một thành phần authorizedUserInterceptor
được thêm vào danh sách myInterceptors
, có nhiệm vụ kiểm tra xác thực của các yêu cầu. File cấu hình webapps\ROOT\WEB-INF\buildServerSpringWeb.xml
cho thấy calledOnceInterceptors
là một thể hiện của lớp RequestInterceptors
.
RequestInterceptors
kiểm soát các yêu cầu HTTP thông qua phương thức preHandle
.
java
public final boolean preHandle(final HttpServletRequest httpServletRequest, final HttpServletResponse httpServletResponse, final Object o) throws Exception {
// Logic kiểm tra và xử lý yêu cầu
}
Nếu requestPreHandlingAllowed
trả về false, hàm preHandle
sẽ kết thúc sớm. Ngược lại, nếu trả về true, danh sách myInterceptors
sẽ được lặp qua, bao gồm cả authorizedUserInterceptor
, kiểm tra tính xác thực của yêu cầu.
Tuy nhiên, nếu kẻ tấn công có thể gửi một yêu cầu để requestPreHandlingAllowed
trả về false, họ có thể tránh được kiểm tra xác thực. Do đó, việc phân tích phương thức requestPreHandlingAllowed
cho thấy rằng myPreHandlingDisabled
chứa đường dẫn wildcard /**/RPC2
, dẫn đến việc bỏ qua xác thực.
java
private boolean requestPreHandlingAllowed(@NotNull final HttpServletRequest httpServletRequest) {
// Logic kiểm tra đường dẫn và xác thực
}
Khai Thác Lỗ Hổng
Để khai thác lỗ hổng này, các API cần cho phép tùy chỉnh hậu tố đường dẫn. Một trong những endpoint đã biết là /app/rest/users/id:1/tokens/RPC2
. Endpoint này cho phép tạo token xác thực cho người dùng. Kẻ tấn công có thể cung cấp ID của quản trị viên để tạo token cho bất cứ người dùng nào, dẫn đến việc chiếm quyền điều khiển.
Ví Dụ Kiểm Chứng (POC)
Dựa trên những phân tích ở trên, việc gởi yêu cầu đến endpoint nói trên với parameter name
cho phép kẻ tấn công tạo ra token cho người dùng admin dễ dàng.
Tài Liệu Tham Khảo
- Rapid7 Analysis
- GitHub CVE-2023-42793
source: viblo