CVE-2022-43473
A blind XML External Entity (XXE) vulnerability exists in the Add UCS Device functionality of ManageEngine OpManager 12.6.168. A specially crafted XML file can lead to SSRF. An attacker can serve a malicious XML payload to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
ManageEngine OpManager 12.6.168
OpManager - https://www.manageengine.com/network-monitoring/
5.8 - CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:L/A:L
CWE-611 - Improper Restriction of XML External Entity Reference (‘XXE’)
OpManager is a network management solution that gathers hardware and software information of computers and other devices on a computer network for management, compliance and audit purposes.
An exploitable XML External Entity (XXE) injection vulnerability is related with an action: Devices -> Add UCS
.
That action triggers a call to API as follows:
REQUEST
POST /client/api/json/discovery/addDevice HTTP/1.1
Host: 192.168.0.11:8060
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0
Accept: */*
Accept-Language: pl,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-ZCSRF-TOKEN: opmcsrftoken=8c3015c780ad62974562e85cc6e8f72cf76dbced7cb80f9c56c76ecb8c088e39f2c9bdaed98e1fbec5f7f7b93e4dbeafb0a7d145d0313254c7a1ce475a822931
X-Requested-With: XMLHttpRequest
Content-Length: 95
Origin: http://192.168.0.11:8060
Connection: close
Referer: http://192.168.0.11:8060/apiclient/ember/index.jsp
Cookie: JSESSIONID=C30BF01AD5299032268FF60F8AC31943; (...)
deviceName=192.168.0.20&netmask=255.255.255.0&credentialName=MagicCredentials&addDeviceType=UCS
Parameter device points to deviceName
, and a backend server will make a special HTTP request and will expect a response in an XML form.
Let us see such a request:
BACKEND REQUEST
POST /nuova HTTP/1.1
content-type: application/x-www-form-urlencoded
User-Agent: Java/1.8.0_345
Host: 192.168.0.20
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 47
<aaaLogin inName="root" inPassword="Pass123" />
If an attacker is able to trigger that Add UCS
action or convince an OpManager user to add a “device” under attacker control, they will be able to fully control the response for the backend request and serve a response in the following form:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://SOME_INTERNAL_IP/important_param=harmful_value"> %xxe;]>
<xml>&xxe;</xml>
Such XML, with defined external entity field, will force vulnerable backend code to perfom additional HTTP requests to the controller by an attacker internal device with given parameters.
Vulnerable code is located inside the com/adventnet/me/opmanager/server/api/handler/RestAPIDiscoveryHandler.java
file.
Let us take a close look at the vulnerable source code:
Line 1 private int addDevice(APIRequestParams params, HttpServletRequest request, Properties auditProps) throws Exception {
Line 2 String deviceName = request.getParameter("deviceName");
Line 3 String netmask = request.getParameter("netmask");
Line 4 String credName = request.getParameter("credentialName");
Line 5 String deviceType = request.getParameter("type");
Line 6 String displayName = request.getParameter("displayName");
Line 7 String networkAddr = request.getParameter("networkAddress");
Line 8 String isOpUSPM = request.getParameter("isOpUSPM");
Line 9 (...)
Line 10
Line 11 if (addDeviceType != null && !addDeviceType.equals("") && addDeviceType.equals("UCS")) {
Line 12 Properties userProp = this.util.getUserDetailsForKey(request.getParameter("apiKey"));
Line 13 String userID = userProp.getProperty("USERID");
Line 14 UCSDiscovery ucsdis = new UCSDiscovery();
Line 15 String resultStr = ucsdis.discover(deviceName, netmask, credNames, userID);
Getting inside ucsdis.discover
method:
/src/com/adventnet/me/opmanager/server/ucs/UCSDiscovery.java
Line 150 public Document getDetails(String deviceName, String protocol, Integer port, String inputXml) throws Exception {
Line 151 (...)
Line 152 String urlAddress = protocol.toLowerCase() + "://" + collectMachineName + ":" + port + "/nuova";
Line 153 URL url = new URL(urlAddress);
Line 154 conn = (HttpURLConnection)url.openConnection();
Line 155 conn.setRequestMethod("POST");
Line 156 conn.setDoOutput(true);
Line 157 conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
Line 158 conn.setReadTimeout(25000);
Line 159 OutputStream out = conn.getOutputStream();
Line 160 out.write(inputXml.getBytes());
Line 161 conn.connect();
Line 162 out.close();
Line 163 (...)
Line 164 in = conn.getInputStream();
Line 165 Document doc = XmlUtil.createDocument(in, false);
We can see code responsible for executing BACKEND REQUEST
. Response data of this request is passed to the createDocument
in line 165
.
Line 320 public static Document createDocument(InputStream is, boolean validating) {
Line 321 try {
Line 322 DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
Line 323 dbfactory.setValidating(validating);
Line 324 DocumentBuilder builder = dbfactory.newDocumentBuilder();
Line 325 builder.setErrorHandler((ErrorHandler)new SAXErrorHandler());
Line 326 return builder.parse(is);
Attacker-controlled XML data is being parsed by DocumentBuilder
line 326
with default settings, which allows for XXE attack.
2022-12-07 - Initial Vendor Contact
2022-12-15 - Vendor Disclosure
2022-12-30 - Vendor Patch Release
2023-03-30 - Public Release
Discovered by Marcin 'Icewall' Noga of Cisco Talos.