Tìm hiểu CVE-2020-15394 - Manage Engine Application Manager unauth RCE
Preface
CVE-2020-15394 - Unauthenticated Remote Code Execution via SQL injection in REST API module: https://www.manageengine.com/products/applications_manager/security-updates/security-updates-cve-2020-15394.html
Affected Builds: builds < 14684; 14689 < builds < 14740
Recommended Fix: Upgrade Applications Manager to version 14740 or above
.
Setup step
Application Manager installation archives: https://archives.manageengine.com/applications_manager/
Restricted installation: MangeEngine hạn chế cho phép tải các phiên bản cũ (<=14700) để hạn chế bugs: https://pitstop.manageengine.com/portal/en/community/topic/license-file-might-be-missing
Release Notes: https://www.manageengine.com/products/applications_manager/release-notes.html?utm_source=set3
Đầu tiên setup remode debug bằng Intellij:
-
Từ Intellij mở folder
Application Manager
và đợi nó index các file. Tìm tất cả file.jar
sau đóAdd as library
để intellj index nốt. -
Tìm đến
AppManager_path\working\conf\wrapper.conf
và xóa comment các dòng sau để enable remote debug mode. -
Intellij RemoteJVMDebug kết nối đến
Tracing
Theo report, lỗ hổng Unauthentication SQL Injection của Manage Engine Application Manager nằm ở ở REST API
module. Review source code thì thấy module này nằm ở Rest API Servlet bới url mapping là /AppManager/*
:
Luồng tới sink dính SQLi như sau:
APIServlet.doGet() / APIServlet.doPost()
-->APIServlet.process()
--> APIServlet.validateMethod()
--> APIServlet.validateAndGenerateJSONFeed()
--> DependentDeviceUtil.getInstance().checkResourceIDAndGetListToBeRemoved()
Đầu tiên các GET/POST requests đến APIServlet đều gọi chung đến method APIServlet.process()
, servlet này kiểm tra request có thỏa mãn điều kiện bỏ qua kiểm tra apikey
, nếu không thỏa mãn thì yêu cầu authenticate cũng như cung cấp apikey
:
Method CommonAPIUtil.skipRESTAPIKeyValidation()
:
Ở đây url được split thành các node dựa vào ký tự /
, nếu node thứ 3 là ApmAdminServices
thì sẽ thỏa mãn điều kiện bỏ qua kiểm tra apikey
và trả về true
, ví dụ: /AppManager/json/ApmAdminServices/*
sẽ thỏa mãn.
Nếu điều kiện đúng sẽ gọi đến method APIServlet.validateMethod()
:
Nếu node 3
là ApmAdminServices
thì method name sẽ được gán bằng node 4
, method này lấy method name cần gọi rồi gọi đến APIServlet.validateAndGatherData()
.
Method này kiểm tra lại request hiện tại có quyền truy cập hay không cũng như gọi đến service tương ứng với method name. Nếu không tìm thấy service nào ứng với method name mà node 2
là json
(isJsonFormat==true) thì gọi đến APIServlet.validateAndGenerateJSONFeed()
:
Tiếp tục luồng, nếu method name match với checkResourceID
sẽ lấy value resourceids
từ request parameter và gọi đến DependentDeviceUtil.getInstance().checkResourceIDAndGetListToBeRemoved()
:
Tại đây là sink của lỗ hổng SQLi khi thực hiện nối chuối với tham số resourceids
mà ta có thể kiếm soát.
Method kiểm tra EnterpriseUtil.isManagedServer()
kiểm tra xem liệu đây có phải là remote server, nếu đúng thì tạo request tương tự đến địa chỉ server đó, không thì đơn giản là execute query trên:
Đến đây ta có thể exec sql command mà không cần authenticated.
RCE
Application Manager là phần mềm dùng để quản trị các application servers, resources, databases,… và với quyền tài khoản là quản trị viên(admin) thì ứng dụng này cho phép thực thi command trực tiếp từ ứng dụng với tính năng Actions --> Execute Program
.
Để RCE ta đơn giản lợi dụng lỗ hổng Unauth SQLi trên tạo 1 tài khoản quản trị rồi login vào thực thi command, các step:
- Tạo tài khoản sau đó add vào group admin, request sqli như sau:
http://localhost:9090/AppManager/json/ApmAdminServices/checkResourceID?resourceIds=1);insert into AM_UserPasswordTable (userid,username,password) values ($$191202$$,$$super_admin$$,$$21232f297a57a5a743894a0e4a801fc3$$);insert into Am_UserGroupTable (username,groupname) values ($$super_admin$$,$$ADMIN$$);-- -
. Trong đó:21232f297a57a5a743894a0e4a801fc3
: là md5 hash củaadmin
.$$
: thay thế cho"
- Login với
username/password
làsuper_admin/admin
mà ta đã Inject rồi vào tính năngCreate Action
của AM:
Sau khi tạo Action
, ta exec program rồi lưu kết quả vào file, nơi mà có thể thể truy cập được, ở đây mình chọn thư mục blog.
- Exec