Mấy nay đầu óc đang rối ren, bộn bề trong biển việc, ngồi nghĩ mãi mà ko ra cái tên nào hợp lý cho cái blog này cả, không có tên thì lại không được, thôi đành để vậy cho nó xúc tích!
Cách đây vài ngày, mấy ae trong group có than thở là dạo này giới CyberSec yên bình quá: không có drama hay CVSS 9.8/10 nào cả,
Vừa dứt lời thì mấy tiếng sau, VMware release advisory về mấy quả bug CVSS 9.8 trên vCenter (ಥ _ ಥ)
Khi đọc cái tên của bug này mình cũng hơi có chút confuse: “Trên một product lớn như vậy mà cũng có lỗ hổng “arbitrary file upload” được à ?”
Mang theo câu hỏi lớn đó, mình bắt tay vào phân tích bản vá để xem lỗi ở đâu!
Phần setup debugging thì trong bài trước (https://testbnull.medium.com/a-quick-look-at-cve-2021-21985-vcenter-pre-auth-rce-9ecd459150a5) mình cũng đã nói rõ về cách sửa file config để có thể debug được rồi, các bạn có thể tham khảo lại guide cũ và chỉnh sửa một chút xíu để có thể debug như ý muốn!
#THE PATCH
Trong advisory của Vmware, họ có cung cấp cả một cái P̶o̶C̶ Workarounds khá là chi tiết,
Chi tiết đến nỗi mà có thể sử dụng nguyên cái request đó để làm PoC luôn ¯\_(ツ)_/¯
.
.
Thực ra đó là nói vui thôi, chứ để RCE được thì câu chuyện không phải là một đường thẳng như vậy.
Hướng đi ban đầu của mình là xem cái script Workarounds, tuy nhiên ngay sau đó đã nhận ra đây là một hướng đi sai lầm. Đường đi ngắn ko có nghĩa là sẽ tới đích, script workaround chỉ thực hiện xóa các endpoint liên quan tới service vmware-analytics như sau:
- /analytics/telemetry/ph/api/hyper/send
- /analytics/ph/api/dataapp/agent
Dựa vào những thông tin từ workarounds, có thể nhìn ra ngay được bug đầu tiên trong bản vá này!
#BUG 1 — Arbitrary File Creation (Required CEIP enabled)
Dựa vào workaround, có thể thấy được tại các endpoint “/analytics/telemetry/ph/api/hyper/send” và “/analytics/ph/api/dataapp/agent” có điều gì đó nguy hiểm, trong số này chỉ có endpoint “/analytics/telemetry” là có thể access trực tiếp do config của service RhttpProxy:
Endpoint “/analytics/telemetry” được handle bởi class AsyncTelemetryController
Khi gọi tới endpoint /analytics/telemetry, một “TelemetryRequest” được tạo từ các tham số đã truyền vào qua HTTP, bao gồm: collectorId, collectorInstanceId, …
Tiếp tục đi vào TelemetryService.processTelemetry(), tại đây TelemetryRequest vừa được tạo ở trên sẽ được submit vào một hàng chờ và execute ngay sau đó, tại TelemetryRequestProcessorRunnable.run():
Sau khi đi vào TelemetryLevelBasedTelemetryServiceWrapper.processTelemetry(), server thực hiện getTelemetryLevel() từ các tham số collectorId, collectorInstanceId được truyền vào:
Theo flow hiện tại của chương trình, DefaultTelemetryLevelService.getTelemetryService() sẽ tiếp tục được gọi để lấy TelemtryLevel. Đoạn code xử lý như sau: