CVE-2024-4142: Lỗ hổng khai thác nâng quyền trong Jfrog Artifactory
Gần đây, khi đang lướt Twitter, tôi đã bắt gặp một thông báo từ Matthias Kaiser liên quan đến lỗ hổng bảo mật trong Jfrog Artifactory: link tweet. Ngay lập tức, tôi đã tải Jfrog Artifactory về để tiến hành kiểm tra.
1. Cách thức lỗ hổng xảy ra
Mã nguồn không thay đổi nhiều, và tôi đã phát hiện ra sự thay đổi chỉ sau vài phút kiểm tra.
Trong phiên bản có lỗ hổng, nhóm phát triển Jfrog đã kiểm tra tên nhóm được yêu cầu bằng hàm AppliedPermissionsScopeToken.isIdentityToken
. Trong khi đó, trong phiên bản đã được khắc phục, họ đã gỡ bỏ kiểm tra này.
Hãy cùng tìm hiểu vấn đề này.
2. Tìm nguồn gốc của lỗi
Tôi sẽ tóm tắt về con đường từ nguồn gốc đến vị trí lỗi:
org.artifactory.rest.resource.token.TokenResource#createOrRefreshToken
--> org.artifactory.rest.resource.token.TokenResource#createToken
--> org.artifactory.security.access.AccessServiceImpl#createToken(org.artifactory.api.security.access.TokenSpec)
--> org.artifactory.security.access.AccessServiceImpl#createToken(org.artifactory.api.security.access.TokenSpec, boolean, boolean)
--> org.artifactory.security.access.AccessServiceImpl#assertLoggedInCanCreateToken
--> org.artifactory.security.access.AccessServiceImpl#assertNonAdminUserCanCreateToken
--> org.artifactory.security.access.AccessServiceImpl#assertValidScopeForNonAdmin(java.util.List<java.lang.String>)
--> org.artifactory.security.access.AccessServiceImpl#assertValidGroupsForNonAdmin
API được xử lý bởi org.artifactory.rest.resource.token.TokenResource#createOrRefreshToken
chính là /artifactory/api/security/token
. API này cung cấp tài liệu rõ ràng tại đây.
API này được sử dụng để tạo một token, trong đó tên người dùng và phạm vi được lấy từ đầu vào của người dùng (thông qua xác thực cơ bản hoặc bearer token). Tham số đầu tiên là username
, đại diện cho người dùng hiện tại trong ngữ cảnh.
Tuy nhiên, điểm thú vị là tham số scope
, nơi người dùng có thể nhập phạm vi cho token API này. Có 9 loại phạm vi được chấp nhận (được mô tả rõ ràng trong tài liệu trên hoặc bạn có thể kiểm tra khi gỡ lỗi).
2.1 Các loại phạm vi của token
Có hai loại phạm vi quan trọng: applied-permissions/groups:
và member-of-groups:
để phân quyền cho token. Còn có applied-permissions/user
, cung cấp quyền truy cập cho người dùng. Nếu để cài đặt mặc định, token sẽ được tạo với phạm vi nhận diện người dùng, cho phép người dùng nhận diện trong nền tảng mà không cấp quyền truy cập cụ thể nào.
Người dùng có thể cấp một hoặc nhiều phạm vi cho token bằng cách thêm ký tự khoảng trắng trong giá trị của tham số scope
. Điều này được xử lý bởi org.jfrog.access.util.TokenScopeUtils#splitScopeToList
, nó sẽ kiểm tra có ký tự khoảng trắng trong giá trị phạm vi hay không, sau đó phân tách chuỗi và thêm chúng vào danh sách.
Kết luận, nếu muốn cấp quyền cho nhiều nhóm, bạn cần gửi yêu cầu với tham số như sau:
username=TEST&scope=member-of-groups:test%20applied-permissions/groups:readers
2.2 Phân tích lỗ hổng
Để quay lại với vị trí có lỗ hổng, nhóm phát triển đã kiểm tra nếu số nhóm không bằng 1, hoặc nhóm yêu cầu không chứa ký tự *
, và hàm AppliedPermissionsScopeToken.isIdentityToken(scope)
bằng false
. Hãy xem qua hàm org.artifactory.security.access.AppliedPermissionsScopeToken#isIdentityToken
, nó kiểm tra xem phạm vi có chứa applied-permissions/user
hay không.
Khi phạm vi có applied-permissions/user
, token sẽ được tạo ra với quyền truy cập của những nhóm mà bạn đã nhập.
Ví dụ, nếu trên máy chủ có một nhóm với quyền quản trị viên, chúng ta có thể áp dụng quyền này cho token không? Để xác minh giả thuyết của mình, tôi tạo một tài khoản với tên test
và một nhóm có tên là admin
với quyền quản trị. Sau đó, tôi đã gửi yêu cầu với 2 nhóm: readers
(thuộc về test
) và admin
(mà test
không thuộc về).
Kết quả cho thấy yêu cầu không được chấp nhận. Tôi đã thay đổi tham số phạm vi thành member-of-groups:admin%20applied-permissions/user
, và tôi đã nhận được token. Tiếp theo, tôi sử dụng token này để kiểm tra xem có thể thực hiện hành động với quyền quản trị hay không. Và đúng vậy, tôi đã có quyền quản trị.
3. Kết luận
Đây là một lỗ hổng khó khai thác trong thực tế, vì máy chủ cần có một nhóm quản trị trước đó (cần biết tên nhóm), và phải cho phép truy cập ẩn danh để có thể thực hiện vượt qua xác thực. Tôi không chắc đây có phải là lỗ hổng gốc của tác giả hay không, có thể còn nhiều cách khai thác khác với các phạm vi khác. Tôi đang chờ đợi những chuyên gia giải thích thêm nếu họ đã phát hiện ra điều gì đó khác.
source: viblo