TLDR: lỗ hổng này đã bị loại bỏ khỏi phần mềm nhưng không kèm theo thông báo hoặc CVE và câu chuyện của chúng tôi.

Mở đầu

JFrog Artifactory là chương trình quản lý các tạo tác (sau đây gọi là artifact) sinh ra trong quá trình phát triển phần mềm. Hay gặp nhất là các bản phân phối gói thư viện phụ thuộc dạng binary. Các hệ thống tương tự JFrog Artifactory mà bạn đọc có thể đã từng biết đến là Github Release, Nexus Repository Manager.

Bài viết này là một kết quả được trích xuất từ quá trình tìm kiếm lỗ hổng trong JFrog Artifactory.

Lỗ hổng bảo mật

Trong một hệ thống lớn thì đôi khi việc cập nhật phần mềm không có được mức độ ưu tiên cao nhất vì nhiều lý do. Ở một lần redteam, chúng tôi xác định có một ứng dụng JFrog Artifactory 7.35.1 và không phải phiên bản mới nhất tới thời điểm đó. Các lỗ hổng đã biết (CVE, security advisor) không cho thấy một kết quả khả quan nào trên phiên bản hiện tại. Do vậy chúng tôi bắt tay vào nghiên cứu để tìm kiếm một lỗ hổng có thể khai thác được.

Bắt đầu từ CVE có mức độ ảnh hưởng nghiêm trọng gần nhất là CVE-2020-7931 (bạn đọc có thể dễ dàng tìm được full exploit đầy đủ), CVE-2022-0573 . Phiên bản được sử dùng để tìm lỗi là Artifactory Pro 7.35.1.

Công việc setup để debug trên môi trường linux (ubuntu) không gặp nhiều khó khăn lắm.

Để tải một phiên bản cũ thì bạn đọc có thể vào https://jfrog.com/download-legacy/?product=artifactory và tải về phiên bản linux định dạng tar.gz để dễ thay đổi cấu hình.

Sau khi giải nén, chạy lệnh app/bin/artifactory.sh để khởi chạy ứng dụng. Ứng dụng listen ở port 8081 và 8082 với thông tin đăng nhập:

  • username: admin
  • password: password

http://localhost:8082/ui/login/

Sau đó cần kích hoạt license.

Untitled

Để debug thì tôi dùng IntelliJ IDEA. Tạo Debug Configurations loại Remote JVM Debug như sau

Untitled

Trong command line arguments chính là tham số để sử dụng cho tham số debug trong file app/bin/artifactory.sh (dòng 429)

setCatalinaOpts() {
    setupTomcatRedirection # This ensures catalina logs are redirected to the common log file
    export CATALINA_OPTS=" -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005  $JAVA_OPTIONS -Djruby.bytecode.version=1.8"
}

Trong Project structure add libraries tới thư mục webapps của Tomcat.

Untitled

Sau đó từ Modules bổ sung thêm dependency tới libjar để có thể đặt breakpoint trong các class.

Untitled

CVE-2020-7931 được vá bằng cách thêm implement để chặn sử dụng các phương thức như getClass ở danh sách blackListedKeys

Untitled

Bên cạnh đó các class được dùng chỉ có

Map.Entry
Security
User
Properties
Request
RepoPath
Enumeration

Đặt breakpoint trong lớp /org/artifactory/addon/filtered/adapters/ArtifactoryTemplateAdapter.class dòng 42 this.assertUnsecuredMethods(key); file artifactory-addon-filtered-resources-7.35.1.jarvà debug chương trình bằng cách deploy file xml có nội dung mã khai thác CVE-2020-7931

<#attempt>
    <#assign filename=request.getParameter("filename")>
    <#assign protected_domain=security.getClass().getProtectionDomain()>
    <#assign urls=protected_domain.getClassLoader().getURLs()>
    <#assign file_url=urls[0].toURI().resolve(filename).toURL()>
    <#assign file_content=file_url.getContent()>
print("".join([<#list 0..999999999 as _><#assign byte=file_content.read()><#if byte == -1><#break></#if>chr(${byte}), </#list>]))
<#recover>
print("Failed to read ${filename}")
</#attempt>

Untitled

Untitled

Remote Downloads cần được tick (setFiltered = true) để trigger render template

Untitled

Chúng tôi theo dõi quá trình xử lý và debug thì không lâu sau đó xác định được một lỗi lợi dụng template để tấn công CSRF nâng quyền tài khoản của kẻ tấn công.

Freemarker là một thư viện xử lý template nhưng có thể cấu hình cài đặt thêm nhiều hạn chế để chặn sử dụng các lớp Java để thực thi lệnh. Dẫu vậy, trong nhiều trường hợp chúng tôi vẫn có thể sử dụng phương pháp vượt qua hộp cát (bypass sandbox) để đạt được kết quả nhất định. Điều này cũng tương tự như khai thác bằng các gadget trong pwn hay gadget trong object deserialization. Bạn đọc có thể tham khảo các bài viết ở [0], [1], [2] để hiểu hơn về vấn đề sandbox.

Cuối cùng chúng tôi có được payload tấn công ngắn gọn như sau:

<#assign userpoc = security.findUser("poc")>
${userpoc.setAdmin(true)}
${security.updateUser(userpoc)}

Payload này sẽ làm gì?

  1. Tìm user có name là “poc”
  2. Cấp quyền admin cho user đó
  3. Cập nhật dữ liệu quyền, nếu không có bước này thì việc thay đổi không được lưu vào ứng dụng.

Bởi vì các lớp thuộc danh sách cho phép và các phương thức không bị blacklist nên template này vẫn được xử lý như bình thường.

Để thử nghiệm payload trên bạn đọc cần tạo thêm user poc, cung cấp quyền deploy trong Identity and Access/Permission.

Để tấn công thành công lỗ hổng này thì cần có 2 điều kiện

  • File upload: Để upload template xml có thể cần quyền upload hoặc chỉnh sửa repository. Có thể làm được điều này với CVE-2019-9733. Khi nghĩ đến việc upload file tùy ý vào một repository manager thì chúng ta cũng nhiều khi liên tưởng đến việc liệu file này khả năng cao sẽ được sử dụng ở đâu đó. Nếu như thay thế binary hoặc file script bằng backdoor là dễ dàng ăn “một chiếc RCE” nhẹ nhàng được rồi.
  • CSRF: Cần user quyền cao hơn click vào link hoặc truy cập trang web tải trang để nâng quyền cho user của kẻ tấn công do đây không phải là một lỗi vượt quyền.

Sau khi phát hiện ra lỗ hổng này và thử nghiệm trên phiên bản mới nhất thì rất tiếc là nó đã được vá, nhưng khi tìm trong toàn bộ các thông báo phát hành thì đều không có bất cứ thông tin gì đề cập đến lỗ hổng này.

Vậy JFrog đã làm gì để vá lỗ hổng này? Vẫn trong file ArtifactoryTemplateAdapter.class

private static boolean isUnsecuredKey(Class<?> cls, String key) {
        return Stream.of(User.class, Security.class).anyMatch((clazz) -> {
            return clazz.isAssignableFrom(cls) && (key.startsWith("update") || key.startsWith("set"));
        });
    }

Họ đã loại bỏ các phương thức với từ khóa updateset làm cho payload của chúng tôi không còn hoạt động nữa. Vậy còn các bạn thì sao, các bạn có thể tìm ra payload khác để bypass blacklist một lần nữa không?

Dò theo các phiên bản thì nó đã được vá loanh quanh ở thời điểm phát hành Artifactory 7.37.13. Tại thời điểm viết bài thì chúng tôi cũng chưa rõ liệu đã có thông tin gì về lỗ hổng này được công bố hay chưa.

Demo

Theo dõi chúng tôi để được cập nhật những kiến thức chuyên sâu trong lĩnh vực bảo mật 👍

[0] https://securitylab.github.com/research/template-security-ssti/

[1] https://www.synacktiv.com/en/publications/exploiting-cve-2021-25770-a-server-side-template-injection-in-youtrack.html

[2] https://testbnull.medium.com/quick-note-of-vcenter-rce-cve-2021-22005-4337d5a817ee