- vừa được xem lúc

Phân tích lỗ hổng CVE-2021-30179 - Apache Dubbo Pre-auth RCE

0 0 7

Người đăng: Real Alpha Man

Theo Viblo Asia

Prefix

Khi phân tích lỗ hổng này, mình thấy bồi hồi vì nhớ lại những kỉ niệm ngày trước. Lúc bắt đầu đi làm thì mình mới năm 2, lúc ấy chẳng biết gì nhưng vẫn luôn mơ mộng về việc trở thành 1 pro, có hàng trăm cái CVE 10.0, nhưng việc research đối với mình thực sự quá khó. Trải qua 2 công ty đầu, không ai dạy mình cách research cũng như là như thế nào mới thực sự là khai thác lỗ hổng bảo mật.

Thế nhưng may mắn thay, cuộc đời mình đi đâu cũng có quý nhân phù trợ. Ở công ty hiện tại, lúc mình vào làm được 1 tháng thì công ty cũng tuyển được 1 ông anh top tier trong mảng Pentest + Researcher ở Việt Nam, trùng hợp thay lại là người hướng dẫn trực tiếp cho mình 🥴.

Mình có hỏi ông anh là Tại sao em thấy em làm lâu mà không pro lên nhỉ. Trong quá trình làm việc, khi anh gặp 1 bức tường anh cảm giác tìm mãi không tìm được cách vượt qua thì anh làm như thế nào, ông anh đã trả lời: "Đấy là do em đặt mục tiêu chưa đúng thôi. Ví dụ em đặt mục tiêu tìm ra CVE thì cái đấy là sai, em đang đặt một mục tiêu nó không rõ ràng và khó đạt được, không phụ thuộc hoàn toàn vào bản thân của mình vì sản phẩm ấy chưa chắc đã có lỗi. Thay vào đó em nên đặt mục tiêu là phân tích 1day hoặc là nắm vững một cái giao thức nào đó. Ví dụ như RPC anh nghĩ em chắc không hiểu rõ về cái đấy đâu". Nghe điều này xong mình thấy mừng rơi nước mắt. Còn không biết ông anh có nhớ bản thân đã từng nói vậy không 😓

Nhân tiện mình liên hệ đến câu chuyện này vì lỗ hổng lần này có liên quan đến giao thức RPC, và mình nghĩ kia cũng là một lời khuyên đúng đắn cho mọi người.

1. Tìm hiểu lỗ hổng

1.1. Mục tiêu

Apache Dubbo là một framework mã nguồn mở dùng để phát triển các hệ thống phân tán. Kiến trúc của Apache Dubbo bao gồm ba phần chính:

  • Service Provider: cung cấp dịch vụ, triển khai các interface của service và đăng ký với Service Registry.
  • Service Consumer: sử dụng dịch vụ, truy cập Service Registry để tìm kiếm các service provider và giao tiếp với chúng.
  • Service Registry: lưu trữ các thông tin về service provider, giúp service consumer tìm kiếm các service provider.

Ngoài ra còn 2 phần hỗ trợ: Monitor có vai trò đếm số lần service được gọi, thời gian tiêu tốn và Container quản lý thời gian tồn tại của service.

Các phần này hoạt động với nhau để tạo ra một hệ thống phân tán, cho phép các service provider và service consumer truyền tải dữ liệu qua mạng một cách hiệu quả. Dubbo cũng cung cấp các tính năng khác như giao tiếp đồng bộ và bất đồng bộ, khả năng mở rộng, quản lý và giám sát, và nhiều tính năng khác để hỗ trợ phát triển ứng dụng phân tán.

Chi tiết hơn, vui lòng tham khảo tại https://dubbo.apache.org/en/docs/v2.7/user/preface/architecture/

1.2. Mô tả lỗ hổng

Lỗ hổng này được mô tả như sau: Lỗ hổng này là một lỗ hổng liên quan đến việc giải tuần tự hoá đối tượng không an toàn - Insecure Deserialization. Version ảnh hưởng là 2.7.8, bản fix lỗi là 2.7.9.

2. Phân tích

Theo mô tả lỗi, lỗ hổng nằm ở chức năng GenericFilter của service Provider. Filter Extension được cài đặt mặc định trong Apache Dubbo với vai trò chặn lại các cuộc gọi từ xa cho Provider và Consumer. Mỗi khi một phương thức từ xa được gọi thì Filter Extension cũng được thực thi và được response tuỳ theo kết quả filter. (Phân tích cái này làm mình nhớ đến cái Network Filter Driver mình làm trong đồ án tốt nghiệp, cơ chế cũng gần tương tự, một thời từng suýt bục dạ dày vì nó 😢 ).

2.1. Điểm kích hoạt lỗ hổng

GenericFilter là một filter implement từ Filter Interface, trong số các tham số được gọi bởi dịch vụ, có một tham số là một mảng byte Object

Tham số này sẽ được deserialize ở phía sau với một trong các phương thức deserialize bao gồm nativejava, bean, protobuf-json.

Có một chút thú vị ở chỗ trong quá khứ cũng đã có một số CVE của Dubbo tương tự lỗi này CVE-2021-25641, khi mà kẻ tấn công có thể tuỳ ý lựa chọn phương thức mà đối tượng có thể được deserialize (attacker chọn nativejava với rất nhiều chain) và để chặn tấn công, dev đã không cho phép người dùng có thể truyền trực tiếp đối tượng với phương thức giải tuần tự hoá là nativejava. Nhưng thực tế trong lỗ hổng này, nơi trigger lại là bộ lọc GenericFilter, trước khi đối tượng thực sự được thực hiện RPC Invocation.

2.2. Cách khai thác

Client giao tiếp với Service Provider bằng RPC, vì vậy ta phải gửi 1 RPC Request hợp lệ.

Mỗi thư viện RPC sẽ sử dụng một cấu trúc request khác nhau, với Apache Dubbo các bạn tham khảo thêm tại https://dubbo.apache.org/en/docs/v2.7/user/references/metadata/

Muốn gọi RPC đến Dubbo Provider nói riêng và các RPC Server khác nói chung, bắt buộc cần có một service hợp lệ. Trong Dubbo có sẵn một service là org.apache.dubbo.samples.metadatareport.local.xml.api.DemoService#sayHello.

Chi tiết về cách triển khai service các bạn xem thêm tại https://dubbo.apache.org/en/docs/v2.7/user/references/telnet/.

Có thể gói gọn về một RPC Request trong Dubbo gồm 3 phần: phần metadata bao gồm thông tin service, method name, version Dubbo, v.v..., phần args bao gồm các tham số cho method và phần attachments là thông tin thêm đính kèm.

Bỏ qua phần metadata, trong phần args, GenericFilter đã nêu rõ gồm 3 args

Args 1 là method name, trong trường hợp này phải set bằng sayHello.

Chương trình thực hiện kiểm tra method có tồn tại không, và bằng việc set method name là sayHello thì nó đã thực hiện cuộc gọi tới phương thức mặc định nêu trên

Args 2 là một string object. Hiện tại mình chưa thấy tác dụng của args này.

Args 3 là 1 Object, đây chính là object dùng để trigger lỗ hổng.

Attachment phải là "generic":"nativejava" để chương trình nhảy sang phần deserialize cho object bằng phương thức nativejava

Việc lựa chọn gadget chains thì tuỳ tình hình thực tế của hệ thống thật. Do Dubbo chỉ là base của hệ thống, trong quá trình xây dựng sản phẩm, dev sẽ thêm các thư viện khác vào.

Tóm lại, một RPC request hoàn chỉnh sẽ có phần body như sau:

{ "service_name": "org.apache.dubbo.samples.basic.api.DemoService", "method_name": "$invoke", "param_types": "Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;", "service_version": "", "args": ["sayHello", ["java.lang.String"], ["<Payload byte array>"] ], "attachment": { "generic": "nativejava" }
}

Về Poc mình sẽ update sau 🥴 hiện tại chưa có.

Postfix

Có thể RCE bằng cách sử dụng phương thức deserialize với bean, raw.return, ... nhưng đó thuộc về một CVE khác đi liền với CVE này nên mình không đề cập thêm. Cách khai thác khá tương tự với nhau.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tạo ra virus bằng tool (Part1)

Virus. Tác hại của nó để lại cũng nặng nề:. . Gây khó chịu cho chúng ta là tác hại đầu tiên.

0 0 33

- vừa được xem lúc

Facebook và google "hiểu" chúng ta như thế nào?

Tổng quan. Đã bao giờ bạn gặp những tình huống dưới đây và đặt câu hỏi thắc mắc tại sao chưa.

0 0 32

- vừa được xem lúc

Mã hoá dữ liệu trên Android với Jetpack Security

Jetpack Security (JetSec) là thư viện được xây dựng từ Tink - dự án mã nguồn mở, bảo mật đa nền tảng của Google. Jetpack Security được sử dụng cho việc mã hoá File và SharedPreferences.

0 0 51

- vừa được xem lúc

Tái hiện vụ bị đánh cắp 2 triệu DAI (~2 triệu USD) của Akropolis

Tổng quan. .

0 0 96

- vừa được xem lúc

Bảo mật internet: HTTPS và SSL/TLS như giải thích cho trẻ 5 tuổi

(Mình chém gió đấy, trẻ 5 tuổi còn đang tập đọc mà hiểu được cái này thì là thần đồng, là thiên tài, là mình cũng lạy). . . Xin chào các bạn.

0 0 78

- vừa được xem lúc

Phân biệt server xịn và server pha ke bằng SSL Pinning

Xin chào các bạn, trong bài viết này mình muốn chia sẻ về một kĩ thuật rất nên dùng khi cần tăng tính bảo mật của kết nối internet: SSL Pinning. Trong bài viết trước, mình đã giải thích khá kĩ về SSL,

0 0 572