+13

Tìm cách RCE trên Manageengine ServiceDesk version cổ tới mức không bị affect bởi một CVE RCE nào

Chuyện là trong hệ thống công ty mình đang chạy 1 con server ManageEngine ServiceDesk gần chục năm tuổi (xin phép được giấu version). Lúc mới vào công ty khoảng 8 tháng trước cũng được giao việc check xem con này có lỗi gì không thì mình nhận thấy nó cổ đến mức không bị một cái CVE nào nghiêm trọng, vì thế cũng không chứng minh được impact để yêu cầu update.

Dạo gần đây công ty có triển khai thử nghiệm một số giải pháp SOC mới, mình được giao nhiệm vụ redteam vào những con được giám sát để test, trong đó có con này. Nghĩ lại vẫn có gì đó cay cay, và mình cũng muốn xem trình độ của mình sau 8 tháng có tăng thêm tí nào không nên mình đã quyết định focus vào nó. Đây là hành trình từ không có gì đến RCE được hệ thống.

1. Tìm lỗ hổng trong ServiceDesk

Tải version của con hàng này về, mình tập trung tìm các endpoint unauth trước. Ngày trước mình hay tìm lỗi dựa vào sink, cứ search string ví dụ Runtime.exec nhưng như thế sót khá nhiều nên dạo gần đây mình hay tìm theo source.

Nhanh chóng phát hiện ra 1 endpoint unauth dính LFI là /fosagent/repl/download-file?basedir=4&filepath=<file>

image.png

Servlet handle là com.zoho.clustering.agent.filerepl.api.DownloadFileServlet, nhận trực tiếp filepath mà không check gì cả, sau đó read file và trả về dưới dạng attachment

image.png

Mừng rơi nước mắt, mình nhanh chóng check xem trong folder install ServiceDesk (SD) có file nào nhạy cảm hay account admin không. Tuy nhiên cuộc đời không dễ dàng như vậy. Cũng có một số file log nhưng không có gì có thể lợi dụng.

Lúc này thử nmap IP thì phát hiện hệ thống public port 1433 của MS SQL ra ngoài.

image.png

Khi mình install local thì mình dùng Postgresql theo mặc định nhưng đọc document của SD thì có thể đổi sang MS SQL thông qua changeDBServer.bat command trong folder bin.

Vì thế mình thử xem có thể lợi dụng MS SQL không.

2. TÌm lỗ hổng để vào được MS SQL

Theo mặc định, MS SQL Server khi được cài sẽ nằm ở C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA, và database của SD tên là servicedesk

image.png

Hí hửng download file này về nhưng không

image.png

Bị access denied vì không có quyền đọc?? Ta thấy nó ghi FileNotFound nhưng thực tế nó access denied, vì nếu là FileNotFound thì nó sẽ như sau

image.png

Bỏ qua chuyện đó, mình tìm được chức năng backup trong SD. Khi chạy backUpData.bat

image.png

Một file backup được tạo ra ở trong folder backup (có thể custom)

image.png

Tên của file sẽ được gắn thêm thời gian chạy backup. Mình cũng không cần bruteforce để biết tên nó vì tên của nó đã được lưu trong log tại C:\ManageEngine\ServiceDesk\bin\SDPbackup.log

image.png

Nhìn tên thì mình thấy khá yên tâm khi nó được backup hàng ngày (nhưng cũng không yên tâm lắm vì backup nằm ngay trên server 🙄).

Bây giờ thì chỉ cần đọc file đó. Nhưng một lần nữa số phận lại trêu ngươi. Mình có thể đọc trên con server local của mình, nhưng như các bạn thấy, folder backup của con SD cần tấn công lại nằm ở ổ D. Trước giờ chưa từng gặp trường hợp như này nên cũng chưa thử, nhưng đến bây giờ mình mới biết trong Windows mặc định khi các bạn path traversal từ ổ C thì không thể ra được ổ D.

image.png

Kết quả không bất ngờ

image.png

Bây giờ chúng ta chỉ có 1 lỗi LFI đọc được các file ở ổ C, chúng ta có thể làm gì với nó?

Mình trở lại với việc tìm lỗi trên SD. Mình phát hiện thêm một endpoint mới khá tiềm năng là /fosagent/repl/take-snapshot, servlet com.zoho.clustering.agent.filerepl.api.TakeSnapshotServlet. Chức năng của nó là snap shot lại ổ đĩa sau đó zip và lưu lại vào C:\ManageEngine\ServiceDesk\server\default\deploy\fosagent.war\snapshots

image.png

Nếu kết hợp với lỗi LFI kia thì hoàn toàn có thể đọc được toàn bộ data.

Mình định sử dụng lỗi này để tải về cả ổ đĩa nhưng sau khi chạy được 1 lúc thì server mình báo run out of disk space mặc dù trước đó mình để thừa gần 100GB.

image.png

Full disk

image.png

Tình hình layoff đang khá căng, giờ mà bị đuổi việc thì chết đói, do vậy mình cũng không dám chạy trên server target, sợ nó lại sập.

Đến đây thì mình cũng đã sức cùng lực kiệt, tìm đến giải pháp cuối cùng là cố gắng crack sa password của MS SQL Server. Password được lưu tại C:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\Log\<time_of_something_random>\Datastore\ProductSettings_SqlEngine_Public.xml

image.png

Mình cũng không cần quan tâm cái chỗ folder kia là gì vì mình có thể đọc nó trong file C:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\Log\Summary.txt

image.png

Đã có được password

image.png

Lúc này đi hỏi ChatGPT nhưng cũng không biết đây là thuật toán gì

image.png

Trong document của Microsoft cũng nói rằng cách mã hóa SA password không được công khai vì lí do bảo mật. Chẳng lẽ lại reverse SQL Server. Kiệt sức vì nó, mình quay đi làm việc khác.

Trong quá trình đó mình cũng có một công việc khác là audit con SupportCenter của ManageEngine. Nhận thấy code khá giống nhau, và trong khi debug thì có 1 tính năng mình có thể extract raw password của SQL Server, mình quyết định tìm hiểu sâu hơn. (Sau này nhận được tin sét đánh từ đồng nghiệp là SupportCenter là tên khác bản mới của ServiceDesk).

3. Lấy password của MS SQL Server

Như mình đã nhắc ở trên, SD cho phép người dùng thay đổi database server bằng cách chạy changeDBServer.bat, giao diện của nó như thế này đây

image.png

Sau một hồi mày mò, mình nhận thấy khi save config, bật lên trở lại và test connection thì nó thành công luôn, nghĩa là nó đã lưu password ở đâu đó??? Đáng lẽ mình phải nghĩ tới điều này sớm hơn.

Thử debug vào quá trình nó check connection, mình nhận ra điều đó là đúng, hơn nữa nó đã load được cả password clear text.

image.png

Hàm thực hiện load config là com.adventnet.servicedesk.tools.ChangeDBServer#getDBDetails.

Hàm này thực hiện đọc file config như sau

image.png

Như vậy với MS SQL Server, file config sẽ nằm trong C:\ManageEngine\ServiceDesk\server\default\deploy\mssql-ds.xml

image.png

Tuy nhiên trong file này không có thông tin đăng nhập

image.png

Tiếp tục debug, mình thấy nơi nó get username và password là hàm com.adventnet.servicedesk.tools.ChangeDBServer#getDBUserNameAndPassword

image.png

Như vậy file lưu user và pass là C:\ManageEngine\ServiceDesk\server\default\conf\login-config.xml

image.png

Ngon luôn, đã tìm được user và password, tuy nhiên đang ở bản encryption.

Phía trên có password cleartext, vì vậy chắc chắn có đoạn decrypt ở đâu đó, tiếp tục debug mình thấy hàm giải mã là org.jboss.resource.security.SecureIdentityLoginModule#decode

image.png

Sau đó password về dạng clear text

image.png

Mừng rơi nước mắt một lần nữa, mình thực hiện đọc file lấy password encrypt trên server.

image.png

Không cần biết cái thuật toán mã hóa kia là gì, mình chỉ cần thay cái mật khẩu đã mã hóa vào trong file config của mình, sau đó run debug lại, để tự server của mình giải mã cái password của server target, kết quả decrypt thành công

image.png

Thành công login tới con này từ remote, đoạn này rõ ràng đội vận hành đã không cấu hình kĩ càng.

image.png

4. Leo quyền Admin, thực hiện RCE

Khi đã chọc được DB, lên admin khá đơn giản, chỉ mất hơi nhiều thời gian mày mò xem user, quyền các thứ ở trong bảng nào để sửa. Tạo hẳn 1 nick mới, up lên quyền Admin, mình thành công trở thành admin của SD. Đoạn này không có gì quá technical nên mình xin được skip, cũng là một bài test kiên trì cho độc giả muốn thử làm.

Khi đã là Admin, ta có thể thực hiện RCE thông qua chức năng Custom Trigger.

image.png

ServiceDesk có 2 chức năng để RCE cho admin là Custom Trigger và Custom Schedule. Khác với Custom Schedule là tạo một command chạy theo thời gian định sẵn, Custom Trigger chạy khi có một ticket được tạo / sửa match với điều kiện. Vì vậy cứ mỗi lần phải tạo / sửa request mới có thể RCE -> thông báo được gửi tới người quản lý ticket.

Lời kết

Qua lần này, bên mình cũng đã có thêm nhiều bài học về việc làm sao để cấu hình hệ thống chuẩn hơn, luôn luôn cập nhật hệ thống lên bản mới nhất cũng như tăng cường khả năng giám sát.

Ké tuyển dụng: Chuyên gia nào đọc đến đây mà muốn tìm kiếm môi trường làm việc mới thì có thể gửi CV về hi@shfsec.com. Bên mình vẫn đang tuyển Senior / Expert AppSec, Offensive và Defensive.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí