Phân tích lỗ hổng uploadfile trên Apache Ofbiz (CVE-2021-37608 bypass)

    Gần đây mình thấy có 1 CVE với Apache Ofbiz CVE-2021-37608, các bạn có thể đọc thêm issue tại đây https://issues.apache.org/jira/browse/OFBIZ-12297, tuy nhiên mình cảm thấy bản patch hơi ảo ma 1 chút

    Mình phân tích cái CVE này do nó oánh điểm CVSS là 9.8, tuy nhiên khi vào nghiên cứu thì nó vẫn cần authen, thế điểm 9.8 ở đâu ra nhỉ :-?
Hoặc cũng có thể là do mình gà nên chưa tìm được endpoint unauthen nữa 😄

Dựng môi trường Debug

    Về phần này có bạn Ngọc Anh đã hướng dẫn dựng môi trường debug ofbiz với Intelijin rồi, các bạn có thể ghé qua xem hướng dẫn nhé

    Ở đây mình đang sử dụng bản release17.12.08, download tại https://github.com/apache/ofbiz-framework/releases/tag/release17.12.08

    Hướng dẫn debug: https://viblo.asia/p/phan-tich-cve-2021-30128-apache-ofbiz-63vKjdGVl2R

Phân tích CVE-2021-37608 vulnerability bypass

    Có thể thấy bản path của CVE-2021-37608 khá sơ sài, các bạn có thể kiểm tra tại đây

    https://github.com/apache/ofbiz-framework/commit/8d49af4/

    image.png

    Bản path này fix mỗi cái chỗ isValidFile, chuyển cái fileToCheck sang file.toString()

    Mình đã dựng môi trường lên, và tìm thấy endpoint tại Image Management https://127.0.0.1:8443/catalog/control/ImageUpload

    image.png

    Đặt breakpoint tại dòng 157 tại org/apache/ofbiz/product/imagemanagement/ImageManagementServices.java

    image.png

    Ta có thể thấy giá trị file=C:\Research\Java\ofbiz-framework-release17.12.08\themes\common\webapp\images\products\management\WG-9943\shell.jsp tức là toàn bộ nội dung file đã được upload lên server, và giữ nguyên tên file shell.jsp (kiểm tra lại file trong server thì đúng là thế thật, file không hề bị sửa đổi gì).

    image.png

    Tại đây có thể sử dụng Race Condition tới RCE (tức là bạn sẽ liên tục upload file shell.jsp và truy cập đến URL https://127.0.0.1:8443/images/products/management/WG-9943/shell.jsp là có thể gọi file shell lên).

    Tuy nhiên, khi phân tích sâu hơn thì một vấn đề nữa tại hàm isValidFile tại org/apache/ofbiz/security/SecuredUpload.java

    Xem online tại: https://github.com/apache/ofbiz-framework/blob/54acc03858eb28bb13dbf17c32d5e394b42ff869/framework/security/src/main/java/org/apache/ofbiz/security/SecuredUpload.java#L102:L219

    Tại đây mình sẽ chia ra làm 3 case khác nhau:

Upload file ảnh bình thường:

    Pass được qua hết các check file và giữ lại file ảnh trên server

Upload file jsp:

  • Đầu tiên sẽ pass được qua check filename bằng 1 đoạn regex [a-zA-Z0-9-_ ]{1,249}.[a-zA-Z0-9-_ ]{1,10}, đoạn này chỉ check xem file name chỉ tồn tại 1 dấu . duy nhất hay không thôi, tên file không chứa ký tự lạ lùng gì cả.

    Code: https://github.com/apache/ofbiz-framework/blob/54acc03858eb28bb13dbf17c32d5e394b42ff869/framework/security/src/main/java/org/apache/ofbiz/security/SecuredUpload.java#L108:L134

  • Tiếp theo đến phần check có phải file image, PDF, vân vân mây mây hay không bằng cách check header của file đó. Nếu k được break thì sẽ tới đoạn xoá file đi
    File badFile = new File(fileToCheck);
    if (!badFile.delete()) {
        Debug.logError("File :" + fileToCheck + ", couldn't be deleted", MODULE);
    }
    return false;
    
    Tuy nhiên toàn bộ quá trình check file trên file đã tồn tại trên server, có thể race condition để RCE như mình nói bên trên

Upload file jsp nhưng không bị xoá file:

  • Như bên trên thì các bạn có thể follow theo luồng hoạt động check file, nhưng đến tận cuối cùng của luồng check file thì mới xoá file => Vậy chỉ cần upload file không hợp lệ nhưng lại không bị xoá file là xong
    if (wrongFile) {
        Debug.logError("Uploaded file "
                + " should contain only Alpha-Numeric characters, hyphen, underscore and spaces,"
                + " only 1 dot as an input for the file name and the extension."
                + "The file name and extension should not be empty at all",
                MODULE);
        return false;
    }
    
  • Tại đây có đoạn code check wrongFile, nếu là wrongFile không thoả mãn bất kỳ điều gì mô tả ở logError thì sẽ return false và không có bất kỳ hành động xoá file trên server gì cả. Thế nên hoàn toàn ta có thể upload file ví dụ như shell.png.jsp, hoặc %%abc.jsp ... để upload file shell jsp lên server, và từ đây chúng ta có thể RCE với quyền user được phép upload ảnh sử dụng tính năng Image Management

Kết luận

    Vậy bypass CVE-2021-37608 có 2 cách khác nhau có thể bypass upload file, sử dụng upload file jsp rồi race condition để RCE, hoặc dễ dàng hơn cả là upload file không thoả mãn điều kiện và không bị xoá file trên server là có thể RCE được.

    Hiện tại lỗi chưa được fix trên bản demo, các bạn có thể sử dụng server demo của apache để thử xem sao https://demo-stable.ofbiz.apache.org

Tham khảo

Bình luận
Vui lòng đăng nhập để bình luận
Một số bài viết liên quan