This is a loaded nail gun left on the lobby table, not a bomb hidden in every Tomcat install
Tenable plugin 103697 maps to CVE-2017-12617 in Apache Tomcat. On the 8.0 branch, versions 8.0.0.RC1 through 8.0.46 are affected and fixed in 8.0.47; Apache also lists affected ranges on other branches as 7.0.0–7.0.81, 8.5.0–8.5.22, and 9.0.0.M1–9.0.0. The bug allows an unauthenticated remote attacker to upload a JSP via HTTP PUT, then request it back for server-side execution, but only when the target servlet context allows writes such as readonly=false on the Default servlet and PUT is reachable.
The raw technical impact is real RCE, so Apache/NVD calling it HIGH is reasonable for an actually exposed host. But for enterprise patch prioritization, a version-only finding materially overstates fleet risk because the exploit chain depends on a non-default, deployment-specific configuration gate; most stock Tomcat installs are not writable this way. That makes this a downgrade to MEDIUM for broad patch scheduling, while still treating confirmed exposed internet-facing nodes as urgent because the CVE is KEV-listed and heavily probed.
4 steps from start to impact.
Find a Tomcat endpoint with PUT reachable
curl requests or scanner modules. The goal is not just version detection; they need a servlet context where HTTP PUT is accepted and mapped to a writable resource path.- Unauthenticated network reachability to the Tomcat HTTP service
- A Tomcat branch/version in the affected range
- A context or servlet path that accepts
PUT
- Many enterprises front Tomcat with reverse proxies or WAFs that block
PUTto application paths - A large share of Tomcat deployments are internal-only, cutting reachable population hard
PUT.Abuse writable DefaultServlet behavior
PUT request to upload a JSP payload. The exploit works because the target context is configured to permit writes, commonly by readonly=false on the Default servlet.- Target context is writable
- Default servlet or equivalent path stores the uploaded file under web-accessible content
- No auth gate on the upload path
readonly=trueis the safer common state and blocks the write- App-specific routing often bypasses DefaultServlet entirely, so the PoC fails on many real deployments
PUT requests creating .jsp or .jspx files, especially to static-content paths. Web logs, WAFs, and reverse proxies usually see this step if logging is intact.Trigger the uploaded JSP webshell
GET for the new JSP to execute arbitrary server-side code. This is the point where a tiny upload turns into full command execution inside the Tomcat process.- Uploaded file is reachable over HTTP
- JSP execution is enabled for that path
- The server did not sanitize or rename the payload
- Some storage layouts or handlers will save content without making it executable as a JSP
- Process-level confinement, filesystem permissions, or containerization can limit post-exec blast radius
java, but only after code execution starts. Access logs will show a suspicious first-time request for the newly written JSP.Establish persistence or pivot
- Tomcat service account has useful filesystem or network access
- Outbound access or internal lateral movement paths exist
- Least-privilege service accounts and segmented app tiers reduce impact materially
- Modern EDR often catches commodity post-exploitation from
java-spawned shells
The supporting signals.
| Primary CVE | CVE-2017-12617; Tenable 103697 is a version-based check for Tomcat 8.0.x prior to 8.0.47. |
|---|---|
| In-the-wild status | Yes. CISA lists it in the Known Exploited Vulnerabilities catalog. |
| KEV details | Added to KEV on 2022-03-25 with due date 2022-04-15; CISA describes it as Apache Tomcat RCE and notes ransomware usage as unknown. |
| PoC availability | Public and mature. NVD/MITRE reference Exploit-DB 42966, and public GitHub PoCs are widespread. |
| EPSS | Shodan CVEDB surfaces FIRST EPSS at roughly 0.944 with 100th percentile ranking, which is consistent with a long-lived, broadly weaponized internet CVE. |
| CVSS interpretation | CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H = 8.1 HIGH. The AC:H is doing real work here: exploitation depends on a specific writable-PUT configuration, not on a difficult exploit primitive. |
| Affected versions | Apache lists 8.0.0.RC1 through 8.0.46 on the 8.0 branch; broader affected ranges are 7.0.0–7.0.81, 8.5.0–8.5.22, and 9.0.0.M1–9.0.0. |
| Fixed versions | Upstream fixes are 7.0.82, 8.0.47, 8.5.23, and 9.0.1. Distro backports also exist, e.g. Debian tomcat7 fixed in 7.0.28-4+deb7u16 and Ubuntu lists fixes such as 8.5.21-1ubuntu1.1 for 17.10. |
| Scanning and exposure data | GreyNoise has observed coordinated cloud scanning specifically for Apache Tomcat WebDAV Webshell RCE CVE-2017-12617 Attempt. That is evidence of active internet probing, not proof your node is actually writable. |
| Disclosure | Apache announced the issue on 2017-10-03 / 2017-10-04 depending on source timezone and publication system; NVD published on 2017-10-03. |
noisgate verdict.
The single biggest downward pressure is the configuration gate: this is only exploitable when Tomcat is set up to accept writable PUT into a JSP-executable context, which is not the normal safe baseline. It stays out of LOW because, when that gate is open, the attacker gets unauthenticated remote code execution and there is strong evidence of real-world exploitation and internet scanning.
Why this verdict
- Downgrade for config friction: vendor/NVD start at
8.1 HIGH, but the exploit requiresPUTplus a writable servlet context such asreadonly=false; that sharply narrows the reachable population. - Posture matters more than version here: a version-only Nessus hit does not prove exploitability. In modern estates, reverse proxies, WAFs, and method restrictions often stop the chain before file write.
- Not a paper tiger: KEV listing, public PoCs, and GreyNoise scanning keep this above LOW because confirmed exposed nodes are straightforward RCE opportunities for unauthenticated attackers.
Why not higher?
It is not higher because this is not universal RCE across all vulnerable versions. The attack needs a specific writable-PUT deployment state that many enterprises do not expose, and that prerequisite compounds with internet reachability requirements. In other words: strong impact, but narrower real-world blast radius than the version string suggests.
Why not lower?
It is not lower because the pre-auth path is still remote and the payoff is full server-side code execution. CISA has enough exploitation evidence to KEV-list it, and public PoCs mean defenders should assume commodity scanning will continue to find the few misconfigured servers that remain.
What to do — in priority order.
- Block HTTP PUT to Tomcat content paths — Enforce this at the reverse proxy, WAF, load balancer, or connector layer and deploy immediately, within hours because the CVE is KEV-listed. If your application truly needs
PUT, scope it to explicit authenticated endpoints rather than broad static or default servlet paths. - Verify
readonly=truefor DefaultServlet — Auditconf/web.xml, applicationWEB-INF/web.xml, and any context overrides so writable static content is not enabled unintentionally. Do this immediately, within hours on internet-facing and DMZ Tomcat first. - Constrain internet exposure — Move non-public Tomcat instances behind VPN, private ingress, or application gateways and limit direct access to only necessary paths. Apply this immediately, within hours for externally reachable systems while remediation is queued.
- Hunt for suspicious JSP drops — Search web roots and deployment directories for newly created
.jspor.jspxfiles, then correlate withPUTrequests in access logs. Start this immediately, within hours because compromise artifacts can persist even after config changes.
- Relying on EDR alone does not stop the initial upload and first webshell execution; it may only catch noisy post-exploitation after the server is already compromised.
- Assuming internal-only exposure makes it safe is weak comfort; once an attacker lands anywhere inside a flat network, this becomes a convenient lateral-movement foothold.
- Treating every version hit as definitely exploitable wastes patch cycles; this finding needs config validation, not blind panic.
Crowdsourced verification payload.
Run this on the target Tomcat host as a local auditor or via SSH. Invoke it as bash tomcat_cve_2017_12617_check.sh /opt/tomcat or point it at CATALINA_BASE; no root is required unless Tomcat config files are restricted. The script checks whether the installed 8.0.x version is below 8.0.47 and then looks for obvious readonly=false servlet settings; because app-specific overrides can hide elsewhere, a clean result on config returns UNKNOWN, not false reassurance.
#!/usr/bin/env bash
# tomcat_cve_2017_12617_check.sh
# Check Apache Tomcat 8.0.x for CVE-2017-12617 exposure indicators.
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN
set -u
TARGET="${1:-${CATALINA_BASE:-}}"
if [[ -z "$TARGET" ]]; then
echo "UNKNOWN - provide CATALINA_BASE/TOMCAT_HOME as argument, e.g. bash $0 /opt/tomcat"
exit 2
fi
if [[ ! -d "$TARGET" ]]; then
echo "UNKNOWN - target path not found: $TARGET"
exit 2
fi
version=""
for f in \
"$TARGET/RELEASE-NOTES" \
"$TARGET/RUNNING.txt" \
"$TARGET/lib/catalina.jar"; do
if [[ -f "$f" ]]; then
if [[ "$f" == *.jar ]]; then
if command -v unzip >/dev/null 2>&1; then
v=$(unzip -p "$f" org/apache/catalina/util/ServerInfo.properties 2>/dev/null | awk -F= '/server.info=Apache Tomcat\//{print $2}' | sed 's/Apache Tomcat\///')
[[ -n "$v" ]] && version="$v" && break
fi
else
v=$(grep -Eo 'Apache Tomcat Version [0-9]+\.[0-9]+\.[A-Za-z0-9.-]+' "$f" 2>/dev/null | head -n1 | awk '{print $4}')
[[ -n "$v" ]] && version="$v" && break
v=$(grep -Eo 'Apache Tomcat/[0-9]+\.[0-9]+\.[A-Za-z0-9.-]+' "$f" 2>/dev/null | head -n1 | cut -d/ -f2)
[[ -n "$v" ]] && version="$v" && break
fi
fi
done
if [[ -z "$version" ]]; then
echo "UNKNOWN - could not determine Tomcat version under $TARGET"
exit 2
fi
# Normalize versions like 8.0.46, 8.0.0.RC1 not handled numerically.
# This plugin is specifically for 8.0.0.RC1 < 8.0.47.
if [[ ! "$version" =~ ^8\.0\. ]]; then
echo "UNKNOWN - detected version $version, but this check is scoped to Tomcat 8.0.x"
exit 2
fi
is_vuln_version=1
if [[ "$version" =~ ^8\.0\.([0-9]+)$ ]]; then
patch="${BASH_REMATCH[1]}"
if (( patch >= 47 )); then
is_vuln_version=0
fi
else
# Covers pre-release strings like 8.0.0.RC1 as vulnerable to this plugin range.
is_vuln_version=1
fi
if (( is_vuln_version == 0 )); then
echo "PATCHED - Tomcat version $version is not in the affected 8.0.x range before 8.0.47"
exit 0
fi
found_cfg=0
found_readonly_false=0
declare -a files
files=(
"$TARGET/conf/web.xml"
)
while IFS= read -r -d '' file; do
files+=("$file")
done < <(find "$TARGET" -type f \( -path '*/WEB-INF/web.xml' -o -name 'web.xml' -o -name 'context.xml' \) -print0 2>/dev/null)
for file in "${files[@]}"; do
[[ -f "$file" ]] || continue
found_cfg=1
if grep -Eiq '(<param-name>\s*readonly\s*</param-name>.*<param-value>\s*false\s*</param-value>)|(<param-value>\s*false\s*</param-value>.*<param-name>\s*readonly\s*</param-name>)|readonly\s*=\s*false' "$file"; then
echo "VULNERABLE - Tomcat $version and writable servlet setting detected in $file"
found_readonly_false=1
exit 1
fi
done
if (( found_cfg == 0 )); then
echo "UNKNOWN - Tomcat $version found, but no config files were readable to confirm writable PUT exposure"
exit 2
fi
echo "UNKNOWN - Tomcat $version is in the affected version range, but no obvious readonly=false setting was found. Version-only scanners may overstate risk; manually verify PUT reachability and per-app overrides."
exit 2
If you remember one thing.
PUT blocking and readonly=true immediately, within hours as an override to the noisgate mitigation SLA, then apply the vendor fix or supported distro backport on every truly affected instance as fast as operationally possible, within hours for exposed systems and no later than the noisgate remediation SLA of 365 days for residual internal-only version hits that are not actually writable.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.