CVE-2026-34486 — Apache Tomcat Tribes EncryptInterceptor Fail-Open
Executive Summary
Attacker objective: unauthenticated code execution as the Tomcat service account on a clustered Java application server, then hands-on-keyboard expansion — reverse shells, a lightweight Linux dropper, tunnelling tooling and persistence.
Root cause (get this right, it drives every detection below): the February 2026 fix for CVE-2026-29146 — a padding-oracle weakness in the Tribes EncryptInterceptor — restructured the encryption manager and, in doing so, moved the super.messageReceived(msg) call from inside the try/catch that handles decryption to outside it. Before the change a decryption failure threw, the catch block logged it, and the message was dropped. After the change the failure is logged and the original attacker-controlled bytes are forwarded up the chain anyway, into a bare ObjectInputStream.readObject() with no class filtering. Fail-closed became fail-open. Anyone who can reach the Tribes receiver (default TCP/4000, no authentication) can send a raw unencrypted serialized Java gadget payload; with Commons Collections 3.x or a comparable gadget library on the classpath — routine in Spring and Hibernate applications — that payload runs commands as the Tomcat user.
The only local trace is a single SEVERE: Failed to decrypt message line. No deserialization error is raised. That log line is the single highest-value native artefact in this pack.
Am I even exposed? This is the question that matters most here, and it is genuinely narrow. The Tribes receiver only listens when clustering is enabled, and the vulnerable path only exists when EncryptInterceptor is configured in the channel. A single-node Tomcat is not affected at all. Exactly three builds carry the regression: 11.0.20, 10.1.53 and 9.0.116. Scoping exposure is cheaper and more decisive than any of the behavioural queries below — do section 7 first, then hunt.
Highest-value defensive angle: a Java/Tomcat process spawning a shell or interpreter. Deserialization RCE has no distinctive payload on the wire that endpoint telemetry sees, but the child process it creates is unmistakable — a JVM serving HTTP has no business executing /bin/sh, curl or cmd.exe. Queries Q1 and Q2 carry most of the detection weight in this pack.
Defender priority for 2026-08-07: the CISA KEV federal remediation deadline is today. Patch to 11.0.21 / 10.1.54 / 9.0.117 or later on any of the three affected builds; if you cannot patch this hour, block TCP/4000 at the network edge and between Kubernetes namespaces, because the receiver requires no authentication and a public PoC has been circulating since mid-April 2026.
Source Review & Web Hunter Notes
Ten sources were fetched and snapshotted verbatim on 2026-08-07 into Tomcat-Tribes-CVE-2026-34486-Hunt-sources/. Every claim in this pack traces to one of them.
| Tier | Source | Key finding | Carry forward |
|---|---|---|---|
| 1 · Vendor | Apache Tomcat security-11 / security-10 / security-9 | Rated Important. "An error in the fix for CVE-2026-29146 allowed the EncryptInterceptor to be bypassed." Affects 11.0.20, 10.1.53, 9.0.116 only. Fixed in 11.0.21 (2026-04-04), 10.1.54 (2026-04-02), 9.0.117 (2026-04-03). Reported 26 Mar 2026, public 9 Apr 2026. Fix commits 1fab40cc / 55f3eb91 / 776e12b3. | Yes — authoritative version scope |
| 1 · Gov | CISA KEV alert, 2026-08-04 | Added as "Apache Tomcat Missing Encryption of Sensitive Data Vulnerability" alongside CVE-2026-9198 (Langflow) and CVE-2026-18556 (N-able N-central). BOD 26-04 applies. | Yes — exploitation status |
| 1 · Gov | NVD CVE-2026-34486 | CWE-311 (Missing Encryption of Sensitive Data) and CWE-807. CISA-ADP scored it 9.8 (C:H/I:H/A:H) on 2026-08-05, then revised down to 7.5 (C:H/I:N/A:N) on 2026-08-06. SSVC: exploitation=active, automatable=yes, technicalImpact revised total → partial. | Yes — with the caveat noted below |
| 1 · Vendor | Red Hat CVE database | Important. 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N. Technical impact: "Bypass Protection Mechanism… may lead to exposure or modification of sensitive data, system crash, or execution of arbitrary code." Affects RHEL and JBoss Web Server shipping the vulnerable Tomcat. | Yes |
| 2 · Unit 42 | Unit 42, autonomous AI attack campaign (2026-07-30) | Chinese-speaking actor (knaithe / KnYuan, Zhuhai) ran DeepSeek via the Hermes Agent framework. CVE-2026-34486 was worked manually, not autonomously: "Java deserialization reverse shell attempts against nine Apache Tomcat servers". Over 460 targets attempted overall. | Yes — confirms the reverse-shell TTP |
| 2 · Press | The Hacker News, 2026-08-05 | Corroborates the KEV addition and the FCEB deadline of 2026-08-07. Relays SOCRadar's SNOWLIGHT findings: China-nexus actor, government and commercial infrastructure in 100+ countries, late April to early June 2026, staging server with nine weaponized CVEs, eleven exploit chains, two tunnelling tools, four C2/RAT families including a verified SNOWLIGHT instance and a cracked Cobalt Strike derivative ("GoCobaltStrike"). 107 endpoints breached across nine CVEs. | Partial — narrative only, see note |
| 2 · Technical | Cyber Kendra, 2026-04 | The only source that explains the mechanism: super.messageReceived(msg) moved outside the try block in the 13 March fix; failed decryption now forwards attacker bytes into a bare ObjectInputStream.readObject() with zero class filtering. Port 4000 unauthenticated, bound to the primary interface. Only trace is SEVERE: Failed to decrypt message. Notes that in Kubernetes without NetworkPolicy, any pod in the namespace reaches port 4000 on every node. Credits Bartłomiej Dmitruk (striga.ai). | Yes — root cause and hunt angles |
| 2 · Analysis | kkm-mako, updated 2026-08-05 | Independent confirmation of the three-build scope and the fix versions. EPSS 0.426 as of 2026-08-04 (top 1.5%). Flags that a public repository billing itself as unauthenticated RCE overstates NVD's confidentiality-only assessment. Notes 9.0.121 / 10.1.58 / 11.0.25 clear this plus the July issues. | Yes — exposure framing |
| Dropped | socradar.io (two URLs: the CVE analysis and the SNOWLIGHT campaign report) | Both returned HTTP 403 to automated fetch. No snapshot exists, so nothing is cited from them directly and no indicator in this pack is sourced from them. The SNOWLIGHT narrative in this pack comes only from The Hacker News summarising SOCRadar. | No |
Honest note on the severity disagreement. Apache, NVD and Red Hat all frame this as a confidentiality issue — an encryption bypass, CVSS 7.5, C:H/I:N/A:N. The unauthenticated-RCE framing comes from the mechanism analysis (Cyber Kendra) plus observed exploitation (Unit 42's "Java deserialization reverse shell attempts"). Both are true and they are not in conflict: the CVE as scored is a protection-mechanism bypass, and the practical consequence of that bypass on a classpath carrying deserialization gadgets is code execution. CISA-ADP itself scored it 9.8 then walked it back to 7.5 within 24 hours. Treat the RCE path as real but conditional on gadget availability, and say so to stakeholders rather than quoting a single number.
Prompt-injection check: none of the ten fetched pages contained instructions directed at an automated reader — no attempts to redirect fetching, alter these instructions, or steer indicator selection. The Unit 42 article quotes an attacker's LLM session verbatim (for example "Search for larger-scale vulns"); those quotes are reported attacker output being analysed, not instructions to this pipeline, and were treated as data.
Hunt Brief & Attack Chain
Hunt hypotheses (ordered by fidelity)
| # | Hypothesis | MITRE | Falcon events | Expected FP | Conf |
|---|---|---|---|---|---|
| H1 | A Tomcat/Java process on Linux spawned a shell or interpreter child, indicating deserialization code execution. | T1190, T1059.004 | ProcessRollup2, SyntheticProcessRollup2 | CI/CD agents, deployment scripts that shell out from the JVM | High |
| H2 | The Windows equivalent: java.exe or javaw.exe spawned cmd.exe, powershell.exe or a script host. | T1190, T1059.001/.003 | ProcessRollup2 | Java installers, build agents, admin scripts | High |
| H3 | A host accepted an inbound connection on TCP/4000 from a source outside the cluster's own node set. | T1190, T1210 | NetworkReceiveAcceptIP4 | Load balancers, monitoring probes, legitimate peers | Medium |
| H4 | An ELF binary was written to /tmp or /dev/shm on a Tomcat host, made executable, run, then removed — SNOWLIGHT-style dropper behaviour. | T1105, T1222.002, T1070.004 | ELFFileWritten, ProcessRollup2 | Package managers, container image extraction | Medium |
| H5 | A JSP or JAR was written under webapps/ or work/Catalina outside a change window — webshell drop. | T1505.003 | JarFileWritten, ELFFileWritten | Legitimate WAR deployment, JSP precompilation | Medium |
| H6 | The tomcat service account established persistence via cron, a systemd unit, or authorized_keys. | T1053.003, T1543.002, T1098.004 | ProcessRollup2 | Configuration management running as the service account | High |
| H7 | Tunnelling or reverse-shell tooling executed on a Tomcat host (frp, chisel, gost, socat, ncat, ssh -R). | T1572, T1090 | ProcessRollup2 | Sanctioned admin tunnels, jump-host workflows | Medium |
| H8 | Exposure scoping: which hosts run an affected build, and which bind TCP/4000 at all. | T1190 (scoping) | NetworkListenIP4, ProcessRollup2 | Unrelated services on 4000 | High |
Attack chain
| Step | Behaviour | Telemetry | Hunt angle |
|---|---|---|---|
| 1 · Discovery | Internet-wide scan for exposed Tribes receivers on TCP/4000. The knaithe actor used FOFA-driven enumeration; the SNOWLIGHT campaign used a "spray-and-check" model. | Perimeter firewall / NetFlow; NetworkReceiveAcceptIP4 | Q3 — accepted inbound on 4000 from outside the node set |
| 2 · Exploitation | Raw unencrypted Tribes message carrying a serialized Java gadget chain sent to the receiver. EncryptInterceptor fails to decrypt, logs SEVERE, forwards the bytes anyway into ObjectInputStream.readObject(). | Tomcat catalina.out (SEVERE: Failed to decrypt message) | Native hunt N1 — the single reliable local artefact |
| 3 · Execution | Gadget chain runs a command as the Tomcat user. Unit 42 observed reverse-shell attempts against nine Tomcat servers. | ProcessRollup2 / SyntheticProcessRollup2 | Q1 (Linux), Q2 (Windows) — JVM spawning a shell |
| 4 · Payload staging | SNOWLIGHT-class C-based dropper written to a world-writable path, chmod +x, executed, self-deleted; follow-on loaded in memory. | ELFFileWritten, ProcessRollup2 | Q7, Q8 |
| 5 · Persistence | Webshell into webapps/ or work/Catalina; cron entry, systemd unit, or authorized_keys addition as the tomcat account. | JarFileWritten, ProcessRollup2 | Q6, Q9 |
| 6 · C2 / tunnelling | Reverse shell callback; tunnelling tools and a cracked Cobalt Strike derivative reported on the staging server. | ProcessRollup2, NetworkConnectIP4 | Q10 |
| 7 · Lateral movement | Cluster session state is shared; a compromised node is trusted by its peers. In Kubernetes without NetworkPolicy, any pod in the namespace can reach 4000 on every node. | NetworkConnectIP4 to peer 4000 | Coverage gap — see section 15 |
Consolidated IOC Table
This pack ships zero atomic indicators, and that is the correct outcome. No hash, IP address or domain tied to the CVE-2026-34486 exploitation vector appears in any of the ten sources snapshotted for this pack. Unit 42 published no infrastructure for the Tomcat vector (their indicators cover the actor's own AI-tooling proxies, which never appear victim-side). The SNOWLIGHT sample hashes sit behind SOCRadar's 403, so they were not retrieved and are not reproduced here on faith. Everything below is behavioural and is what the queries in section 8 actually key on.
| Type | Indicator | Confidence | Action | Context | Expiry |
|---|---|---|---|---|---|
| Behaviour | Tomcat/Java process spawning /bin/sh, bash, curl, wget, python, perl, nc | High | detect | The deserialization-RCE tell. A JVM serving HTTP does not shell out in normal operation. | Durable |
| Behaviour | java.exe / javaw.exe spawning cmd.exe, powershell.exe, wscript.exe, certutil.exe | High | detect | Windows equivalent of the same chain. | Durable |
| Log string | SEVERE: Failed to decrypt message in catalina.out | High | hunt | The only local trace of an exploitation attempt. Present on both failed and successful attempts. | Durable |
| Port | TCP/4000 inbound, accepted, source outside the cluster node set | Medium | hunt | Default Tribes receiver port, unauthenticated, bound to the primary interface. Cluster membership traffic should never originate on the internet. | Durable |
| Behaviour | Short-lived ELF in /tmp, /dev/shm or /var/tmp: written, chmod +x, executed, deleted | Medium | hunt | SNOWLIGHT-class dropper pattern per the reporting relayed by The Hacker News. | Durable |
| Behaviour | JSP or JAR written under webapps/ or work/Catalina outside a change window | Medium | hunt | Webshell drop as the tomcat service account. | Durable |
| Tooling | Named in reporting: SNOWLIGHT (C-based Linux dropper/loader), GoCobaltStrike (cracked Cobalt Strike derivative), unspecified tunnelling tools | Medium | hunt | Family names only. No samples or hashes were retrievable from a citable source. | 2026-11-07 |
| Version | Apache Tomcat 11.0.20, 10.1.53, 9.0.116 | High | pivot | The exact and only affected builds, per Apache's own advisories. Use for exposure scoping, not alerting. | Durable |
Affected Surface & Telemetry Matrix
| Surface | Exposure condition | Required telemetry | Priority | Gap risk |
|---|---|---|---|---|
| Linux Tomcat cluster node | Build 11.0.20 / 10.1.53 / 9.0.116, clustering enabled, EncryptInterceptor in the channel | Falcon Linux sensor: process, ELF file write, network | Critical | Low — process telemetry is the strong signal |
| Windows Tomcat cluster node | Same builds, same config, service running as a dedicated account | Falcon Windows sensor: process, network | High | Low |
| Kubernetes-hosted Tomcat | Pods in one namespace with no NetworkPolicy — any pod reaches 4000 on every node | Falcon Container sensor; K8s audit + NetworkPolicy inventory | High | High — east-west pod traffic often unseen by EDR |
| Tomcat application logs | catalina.out reachable by a log shipper | Syslog / NGSIEM ingest of catalina.out | Critical | Medium — app logs are frequently not shipped |
| Perimeter / east-west network | TCP/4000 reachable from anything outside the node set | Firewall logs, NetFlow, NetworkReceiveAcceptIP4 | High | Medium |
| Single-node Tomcat | Not affected. No Cluster element means no Tribes receiver and no vulnerable path. | None required | N/A | None |
| Tomcat 8.5 and earlier | Not affected. The branch does not include the component. (It is end-of-life regardless.) | None required | N/A | None |
Be honest about hit likelihood. The population of hosts that satisfy every exposure condition — one of exactly three builds, clustering on, EncryptInterceptor configured, port 4000 reachable — is small in most estates. A clean hunt here is the expected result and is not evidence the hunt was ineffective. The value of this pack is disproportionately in section 7 (scoping) rather than in a query firing.
ATT&CK Mapping
| Tactic | Technique | Observed behaviour | Query / control |
|---|---|---|---|
| Reconnaissance | T1595.002 — Active Scanning: Vulnerability Scanning | Internet-wide enumeration of exposed services; FOFA-driven target selection. | Q3 · perimeter ACL |
| Initial Access | T1190 — Exploit Public-Facing Application | Unauthenticated serialized payload to the Tribes receiver on TCP/4000. | Q3, Q4, N1 · patch |
| Execution | T1059.004 — Unix Shell | Gadget chain runs a shell command as the Tomcat user. | Q1 |
| Execution | T1059.001 / T1059.003 — PowerShell / Windows Command Shell | java.exe spawning cmd.exe or powershell.exe on Windows nodes. | Q2 |
| Persistence | T1505.003 — Server Software Component: Web Shell | JSP or JAR dropped under webapps/ or work/Catalina. | Q6 · N3 |
| Persistence | T1053.003 — Scheduled Task/Job: Cron | Cron entry added by the tomcat service account. | Q9 |
| Persistence | T1543.002 — Create or Modify System Process: Systemd Service | New systemd unit written and enabled post-exploitation. | Q9 |
| Persistence | T1098.004 — Account Manipulation: SSH Authorized Keys | authorized_keys modified for the service account. | Q9 |
| Defense Evasion | T1070.004 — Indicator Removal: File Deletion | Dropper deletes itself after execution; the actor emptied exploit directories after use. | Q7 · gap, see s15 |
| Defense Evasion | T1222.002 — File and Directory Permissions Modification | chmod +x on a staged binary in a temp path. | Q8 |
| Command and Control | T1572 — Protocol Tunneling | Tunnelling tools staged on the adversary infrastructure and used on compromised hosts. | Q10 |
| Command and Control | T1090 — Proxy | Proxy anonymization used on repeat visits to a high-intent target. | Q10 |
| Command and Control | T1105 — Ingress Tool Transfer | Dropper and follow-on payload pulled to the host after execution. | Q1, Q7 |
| Lateral Movement | T1210 — Exploitation of Remote Services | Peer cluster nodes trust replicated session state from a compromised member. | Q3 · NetworkPolicy |
Native Audit-Log Hunts (non-CQL)
Run these first. They answer "am I exposed?" in minutes and cost nothing, and N1 is the highest-fidelity artefact in the entire pack.
N1 · The exploitation artefact in catalina.out
Failed decryption is logged at SEVERE and then the message is forwarded anyway. This line is present for both failed and successful exploitation, and it should be extremely rare in a healthy cluster (a genuine key mismatch produces it too, which is itself worth knowing about).
grep -rn "Failed to decrypt message" /opt/tomcat/logs/ /var/log/tomcat*/ 2>/dev/null # Ship it to the SIEM as a standing rule. Any occurrence on a build of # 11.0.20, 10.1.53 or 9.0.116 is an exploitation attempt until proven otherwise. # On a patched build the same line means a real key/config mismatch -- still # worth a ticket, but not an incident.
N2 · Exposure scoping — is the Tribes receiver even listening?
# Linux: who is bound to 4000, and is it a JVM? ss -lntp | grep -w 4000 lsof -nP -iTCP:4000 -sTCP:LISTEN # Windows: netstat -ano | findstr ":4000"
N3 · Configuration scoping — clustering and EncryptInterceptor
# Is a Cluster configured at all? No Cluster element = not affected. grep -rn "Cluster" /opt/tomcat/conf/server.xml # Is EncryptInterceptor in the channel? This is the vulnerable component. grep -rn "EncryptInterceptor" /opt/tomcat/conf/server.xml # Which build is running? Only 11.0.20, 10.1.53 and 9.0.116 are affected. /opt/tomcat/bin/version.sh | grep -i "server number"
N4 · Webshell sweep under the Tomcat tree
# JSP/JSPX written in the last 30 days outside a known release window.
find /opt/tomcat/webapps /opt/tomcat/work/Catalina -type f \
\( -name "*.jsp" -o -name "*.jspx" -o -name "*.war" \) -mtime -30 -ls
# Files owned by the tomcat account in unexpected places.
find /tmp /dev/shm /var/tmp -user tomcat -type f -ls 2>/dev/null
N5 · Kubernetes east-west exposure
Cyber Kendra's analysis is explicit that in a namespace with no NetworkPolicy, any pod can reach port 4000 on every Tomcat node. Confirm whether a default-deny policy exists before assuming the cluster port is internal.
kubectl get networkpolicy --all-namespaces kubectl get pods -n YOUR_NAMESPACE -o wide # Absence of any NetworkPolicy in a namespace running clustered Tomcat means # the Tribes receiver is reachable by every workload in that namespace.
N6 · Persistence review on any host that scoped in
crontab -l -u tomcat ls -la /etc/cron.d/ /etc/cron.daily/ systemctl list-unit-files --state=enabled | tail -40 cat /home/tomcat/.ssh/authorized_keys 2>/dev/null stat /home/tomcat/.ssh/authorized_keys 2>/dev/null
CrowdStrike LogScale CQL Hunt Queries
No query below carries an in-query time filter. Set the window in the Falcon console instead — @timestamp compared against an expression does not parse in CQL, and a broken first line silently kills the whole query.
Looks for: the classic Java-deserialization RCE tell — a JVM or Tomcat wrapper process becoming the parent of a shell, downloader or scripting interpreter. This is the highest-weight query in the pack because deserialization leaves no distinctive payload artefact on the endpoint, only its children. FP: CI/CD build agents and deployment tooling legitimately shell out from a JVM; exclude those hosts by aid before promoting.
// HUNT: Tomcat/Java parent spawning a shell or interpreter (Linux) // MITRE: T1190, T1059.004, T1105 | CONF: high FP: medium COST: low // REQUIRES: Falcon Linux sensor, process execution telemetry // FALSE POSITIVES: Jenkins/GitLab runners, Ansible deploys, JMX health checks that fork // TUNING: exclude build and packaging hosts by aid, then exclude FileName=/^(sh|bash)$/i // TUNING: where CommandLine matches your own deployment wrapper script name #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ParentBaseFileName=/^(java|javaw|jsvc|catalina\.sh|tomcat)$/i | FileName=/^(sh|bash|dash|zsh|ksh|curl|wget|python3?|perl|ruby|nc|ncat|socat|busybox)$/i | table([ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine, ProcessStartTime])
Looks for: the Windows half of the same chain. Tomcat on Windows usually runs via a service wrapper, so both the JVM and the wrapper are covered as parents. FP: Java installers and application-server admin scripts invoke cmd.exe legitimately; exclude by ParentCommandLine matching your installer or agent jar path.
// HUNT: java.exe / javaw.exe spawning a Windows command shell or script host // MITRE: T1190, T1059.001, T1059.003 | CONF: high FP: medium COST: low // REQUIRES: Falcon Windows sensor, process execution telemetry // FALSE POSITIVES: Java/JRE installers, Jenkins agent JVMs, Tomcat service wrapper restarts // TUNING: exclude ParentCommandLine matching your agent jar path and your patching tool, // TUNING: and drop certutil/bitsadmin from FileName if a legacy deploy job uses them #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ParentBaseFileName=/^(java|javaw|jsvc|tomcat\d*|tomcat\d*w)(\.exe)?$/i | FileName=/^(cmd|powershell|pwsh|wscript|cscript|mshta|certutil|bitsadmin|curl)(\.exe)?$/i | table([ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine, ParentCommandLine])
Looks for: a host accepting a connection on the default Tribes receiver port from a non-internal source. Cluster membership traffic should only ever come from sibling nodes; anything arriving from the internet is either a scanner or an exploitation attempt. FP: internet-facing monitoring probes and any unrelated service that happens to bind 4000; confirm the listening process is a JVM using Q4 before escalating.
// HUNT: Inbound connection accepted on the Tribes receiver port (TCP/4000) // MITRE: T1190, T1210 | CONF: medium FP: medium COST: medium // REQUIRES: Falcon network telemetry (NetworkReceiveAcceptIP4) // FALSE POSITIVES: legitimate cluster peers inside RFC1918, load-balancer health checks // TUNING: the cidr exclusion below is a first pass. Once you know your node set, // TUNING: replace it with an explicit allowlist of your own cluster node addresses, // TUNING: because a compromised peer inside RFC1918 is exactly what this must still catch. #event_simpleName=/^NetworkReceiveAcceptIP4$/ | LocalPort = 4000 | !cidr(RemoteAddressIP4, subnet=["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "127.0.0.0/8", "169.254.0.0/16", "100.64.0.0/10"]) | groupBy([ComputerName, aid, LocalAddressIP4, LocalPort, RemoteAddressIP4], function=count(as=Accepts))
Looks for: the exposed-asset inventory. The Tribes receiver only listens when clustering is enabled, so this query is the exposure answer for most estates. Run it before anything else and use the result to scope the rest of the hunt. FP: unrelated software also binds 4000; the ContextBaseFileName column tells you whether the owning process is a JVM.
// HUNT: EXPOSURE SCOPING -- hosts with a listener bound on the Tribes receiver port // MITRE: T1190 (scoping) | CONF: medium FP: low COST: low // REQUIRES: Falcon network telemetry (NetworkListenIP4) // FALSE POSITIVES: non-Tomcat services that also bind 4000 // TUNING: confirm ContextBaseFileName is a JVM before treating a row as a Tomcat cluster node #event_simpleName=/^NetworkListenIP4$/ | LocalPort = 4000 | groupBy([ComputerName, aid, LocalAddressIP4, LocalPort, ContextBaseFileName], function=count(as=Binds))
Looks for: every running Tomcat JVM, with its full command line so you can read the install path. Most packaged installs embed the version in catalina.home (for example an apache-tomcat-9.0.116 directory), which turns this into a version inventory. FP: non-Tomcat JVMs that reference Catalina classes on a shared classpath; the CommandLine column resolves it by eye.
// HUNT: EXPOSURE SCOPING -- running Tomcat JVMs and their install paths // MITRE: T1190 (scoping) | CONF: medium FP: medium COST: medium // REQUIRES: Falcon process telemetry on all platforms // FALSE POSITIVES: embedded Tomcat in Spring Boot fat jars, non-Tomcat JVMs on a shared classpath // TUNING: to jump straight to the affected builds, append this stage -- // TUNING: | CommandLine=/apache-tomcat-(11\.0\.20|10\.1\.53|9\.0\.116)/i // TUNING: only those three builds carry the regression; 8.5 and earlier lack the component #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^(java|javaw|jsvc)(\.exe)?$/i | CommandLine=/(catalina\.home|catalina\.base|org\.apache\.catalina\.startup\.Bootstrap)/i | groupBy([ComputerName, aid, UserName, FileName, CommandLine], function=count(as=Starts))
Looks for: a payload or backdoored archive landing inside the Tomcat install — webapps/, work/Catalina, or the install root. FP: ordinary WAR deployment and JSP precompilation write here constantly; correlate against your release calendar and exclude the ContextBaseFileName of your deployment tooling. Note that plain .jsp text files are not covered by these events — see native hunt N4 and the coverage gap in section 15.
// HUNT: executable or JAR written under a Tomcat webapps / work / install path // MITRE: T1505.003, T1105 | CONF: medium FP: medium COST: low // REQUIRES: file-write telemetry (ELFFileWritten, JarFileWritten, PeFileWritten) // FALSE POSITIVES: WAR deployment, JSP precompilation into work/Catalina, patching runs // TUNING: exclude ContextBaseFileName of your deployment tooling (ansible, mvn, unzip, rsync) // TUNING: and suppress the query entirely during scheduled release windows #event_simpleName=/^(ELFFileWritten|JarFileWritten|PeFileWritten|NewExecutableWritten)$/ | TargetFileName=/(tomcat|catalina|webapps|work\/Catalina)/i | table([ComputerName, aid, UserName, TargetFileName, ContextBaseFileName, SHA256HashData])
Looks for: the staging half of the reported dropper pattern — a small C-based ELF written into /tmp, /dev/shm or /var/tmp. Pair with Q8 (the chmod) and Q1 (the JVM parent) to reconstruct the chain; a hit on all three within a short window on the same host is close to conclusive. FP: package managers, container runtimes and installers unpack to these paths constantly.
// HUNT: SNOWLIGHT-style dropper -- ELF binary written to a world-writable temp path // MITRE: T1105, T1059.004 | CONF: medium FP: medium COST: low // REQUIRES: Falcon Linux sensor, ELFFileWritten telemetry // FALSE POSITIVES: dpkg/rpm/dnf/apt unpacking, containerd image extraction, self-extracting installers // TUNING: exclude ContextBaseFileName=/^(dpkg|rpm|yum|dnf|apt|apt-get|containerd|dockerd|snapd)$/i // TUNING: then rank what remains by shortest file lifetime -- a self-deleting binary is the signal #event_simpleName=/^ELFFileWritten$/ | TargetFileName=/^\/(tmp|dev\/shm|var\/tmp|run\/shm)\// | table([ComputerName, aid, UserName, TargetFileName, ContextBaseFileName, SHA256HashData])
Looks for: chmod or chattr executed against a path under /tmp, /dev/shm or /var/tmp. On its own this is noisy; as the middle link between Q7 and Q1 on the same host inside a few seconds, it is the dropper being armed. FP: shell scripts and installers routinely chmod their own temp files — filter to hosts that also appear in Q4 or Q5 output before triaging.
// HUNT: chmod/chattr against a world-writable temp path (dropper being armed) // MITRE: T1222.002 | CONF: medium FP: medium COST: low // REQUIRES: Falcon Linux sensor, process execution telemetry // FALSE POSITIVES: installer and build scripts chmod'ing their own extracted temp files // TUNING: intersect with the host list from Q4/Q5 -- outside the Tomcat cluster this is pure noise // TUNING: and exclude ParentBaseFileName of your configuration-management agent #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^(chmod|chattr)$/i | CommandLine=/\/(tmp|dev\/shm|var\/tmp|run\/shm)\// | table([ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
Looks for: cron, systemd or authorized_keys manipulation performed as the Tomcat service account. A web application server account has no legitimate reason to touch any of these. This is the lowest-noise query in the pack after Q4 and is a strong candidate for promotion to a Custom IOA.
// HUNT: persistence written by a Tomcat-owned process -- cron, systemd unit, authorized_keys // MITRE: T1053.003, T1543.002, T1098.004 | CONF: high FP: low COST: low // REQUIRES: Falcon Linux sensor, process execution telemetry with UserName resolution // FALSE POSITIVES: configuration management (Ansible, Puppet, Chef) running as the service account // TUNING: exclude ParentBaseFileName of your config-management agent; if that agent legitimately // TUNING: manages tomcat cron entries, scope this query to authorized_keys and systemd only #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | UserName=/^(tomcat\d*|catalina|jboss|www-data)$/i | CommandLine=/(crontab|systemctl\s+enable|systemctl\s+daemon-reload|authorized_keys|\/etc\/cron|\/etc\/systemd\/system)/i | table([ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine, ProcessStartTime])
Looks for: the C2 stage. Reporting relayed by The Hacker News describes two tunnelling tools and four C2/RAT families on the adversary staging server, including a cracked Cobalt Strike derivative. This query keys on the tool families rather than on any sample, because no hashes were retrievable from a citable source. FP: high — ssh -R and socat are legitimate admin tools in many estates. Run this scoped to the host list from Q4/Q5, never estate-wide as an alert.
// HUNT: tunnelling / reverse-shell tooling executed on a Tomcat host // MITRE: T1572, T1090, T1059.004 | CONF: medium FP: high COST: medium // REQUIRES: Falcon process execution telemetry // FALSE POSITIVES: sanctioned admin tunnels, jump-host workflows, monitoring agents using socat // TUNING: MANDATORY -- scope to the aid list produced by Q4/Q5 before triaging, and allowlist // TUNING: your break-glass jump hosts by aid. Estate-wide this query is noise, not detection. #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^(frpc|frps|chisel|ngrok|gost|socat|nc|ncat|netcat|iox|ew|stowaway)$/i | CommandLine=/(-R\s|-L\s|-e\s*\/bin\/|reverse|remote_port|server_addr|listen)/i | table([ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
CrowdStrike Custom IOA Recommendations
Three queries are clean enough to promote to a Custom IOA. The rest stay Investigate-only.
| IOA name | From | Pattern | Exclusions | Severity | Action |
|---|---|---|---|---|---|
| IOA — Java Application Server Spawns Unix Shell | Q1 | Process creation. Parent image name matches java|javaw|jsvc|catalina.sh; child image name matches sh|bash|dash|curl|wget|python|perl|nc|ncat|socat. | Exclude host groups for CI/CD runners and packaging hosts. Exclude any child whose command line matches your own deployment wrapper. | Critical | Detect (move to Prevent after a two-week clean baseline) |
| IOA — Java Application Server Spawns Windows Shell | Q2 | Process creation. Parent image name matches java.exe|javaw.exe|tomcat*.exe; child image name matches cmd.exe|powershell.exe|pwsh.exe|wscript.exe|cscript.exe|mshta.exe. | Exclude the Java installer path and your patch-management agent as grandparent. | Critical | Detect |
| IOA — Tomcat Service Account Persistence | Q9 | Process creation where the user matches tomcat* and the command line references crontab, systemctl enable, or authorized_keys. | Exclude the configuration-management agent by parent image if it legitimately manages the account. | High | Detect |
Investigate-only (do not promote)
- Q3, Q4, Q5 — scoping and inventory queries. They are meant to produce rows, not alerts. Q4 in particular should be run once and turned into an asset list.
- Q6, Q7, Q8 — medium FP by nature; useful as correlation legs inside an investigation, not as standalone triggers. Their value is the intersection with Q1 on the same host in the same window.
- Q10 — high FP. Never promote. Scope to the Q4/Q5 host list and run it manually during an investigation.
Deployment path: Falcon console → Endpoint security → Custom IOA rule groups → new Process Creation rule group scoped to a host group containing only the assets Q4 and Q5 identified. Scoping the IOA to the Tomcat cluster rather than the whole estate is what keeps Q1 and Q2 at a workable alert volume.
Machine-Readable IOC Appendix
Read before importing. The CSV block below contains placeholders only. This threat is IOC-light in public reporting and no atomic indicator for the Tomcat vector appears in any source snapshot saved for this pack. Do not import placeholder rows, and do not populate them from an uncited blog — replace them only with indicators you recover from your own incident or from a vendor report you have read yourself.
type,value,action,severity,expiration,description,tags # BEHAVIOUR-LED PACK. No atomic indicator for CVE-2026-34486 exploitation is # published in any source snapshotted on 2026-08-07. The rows below are shaped # placeholders so the import format is ready when you have real values. # Delete any row you cannot source. Never import a REPLACE_WITH value. sha256,REPLACE_WITH_DROPPER_SHA256,detect,critical,2027-02-07,SNOWLIGHT-class dropper recovered from your own incident,cve:CVE-2026-34486 sha256,REPLACE_WITH_WEBSHELL_SHA256,detect,critical,2027-02-07,Webshell recovered from webapps or work/Catalina,cve:CVE-2026-34486 ipv4,REPLACE_WITH_TRIBES_SCANNER_IP,hunt,high,2026-11-07,Source seen connecting to TCP/4000 from outside the cluster node set,cve:CVE-2026-34486 domain,REPLACE_WITH_C2_DOMAIN,detect,high,2027-02-07,C2 recovered from a compromised Tomcat host,cve:CVE-2026-34486
BEHAVIOUR parent=java|javaw|jsvc|catalina.sh child=sh|bash|curl|wget|python|perl|nc BEHAVIOUR parent=java.exe|javaw.exe child=cmd.exe|powershell.exe|wscript.exe BEHAVIOUR accepted inbound TCP/4000 from a source outside the cluster node set BEHAVIOUR ELF written to /tmp, /dev/shm, /var/tmp then chmod +x then executed then deleted BEHAVIOUR JSP / JAR written under webapps/ or work/Catalina outside a release window BEHAVIOUR user=tomcat* running crontab, systemctl enable, or editing authorized_keys BEHAVIOUR tunnelling binary (frpc, chisel, gost, socat, ncat) on a host that binds 4000 LOGSTRING "SEVERE: Failed to decrypt message" in catalina.out -- the exploitation artefact CONFIG server.xml contains both a Cluster element and EncryptInterceptor VERSION Apache Tomcat 11.0.20 or 10.1.53 or 9.0.116 -- the only affected builds
MALWARE SNOWLIGHT lightweight C-based Linux dropper / loader TOOL GoCobaltStrike cracked Chinese Cobalt Strike derivative TOOL (unnamed) two tunnelling tools on the adversary staging server ACTOR knaithe / KnYuan Chinese-speaking operator, Zhuhai; DeepSeek via Hermes Agent ACTOR (unattributed) China-nexus SNOWLIGHT operator, 100+ countries, Apr-Jun 2026 FRAMEWORK Hermes Agent autonomous orchestration with Telegram-based C2 # No hashes, IPs or domains are listed here on purpose. The SNOWLIGHT sample # details sit behind a source that returned HTTP 403 and were never retrieved. # Family names are safe to record; unverified indicators are not.
# 1. Which build? Affected: 11.0.20, 10.1.53, 9.0.116 Fixed: 11.0.21, 10.1.54, 9.0.117 /opt/tomcat/bin/version.sh | grep -i "server number" # 2. Clustering on? No Cluster element means you are NOT affected. grep -c "Cluster" /opt/tomcat/conf/server.xml # 3. EncryptInterceptor configured? This is the vulnerable component. grep -c "EncryptInterceptor" /opt/tomcat/conf/server.xml # 4. Receiver listening? ss -lntp | grep -w 4000 # 5. Exploitation artefact present? grep -c "Failed to decrypt message" /opt/tomcat/logs/catalina.out # Any host answering yes to 1+2+3 is in scope. Patch to 11.0.21 / 10.1.54 / # 9.0.117 or later. Going to 11.0.25 / 10.1.58 / 9.0.121 also clears the # July 2026 Tomcat issues in the same maintenance window.
Detection Validation Gates
| Gate | Check | Pass condition |
|---|---|---|
| 1 · Telemetry ready | Do the candidate hosts report ProcessRollup2, NetworkListenIP4 and ELFFileWritten at all? Run Q4 and Q5 with no additional filters. | Q5 returns at least one row per known Tomcat host. If it returns nothing, the sensor is not reporting and every other query is vacuously clean. |
| 2 · Log ingest | Is catalina.out shipped to the SIEM? Search for any SEVERE line from the Tomcat hosts. | At least one Tomcat log line is searchable. If not, native hunt N1 must be run on-host and the coverage map gap in section 15 stands. |
| 3 · Benign baseline | Run Q1 and Q2 over 14 days on the scoped host group. Record every hit. | Every hit is explained and attributed to a named deployment or monitoring process before promotion. Unexplained hits are incidents, not tuning candidates. |
| 4 · Positive test (safe) | On a non-production node, from an interactive shell as the tomcat account, run /bin/sh -c id with the JVM as the parent via your app server's own admin console if it offers script execution. Do not build or run exploit code. | Q1 fires within the search window. If it does not, the parent-name regex needs your wrapper's actual process name added. |
| 5 · Positive test (network) | From an allowed test host outside the node set, open a TCP connection to 4000 on a scoped node and close it immediately. | Q3 or Q4 records the event. Confirms network telemetry reaches the repository. |
| 6 · Promotion | Only after gates 1, 3 and 4 pass, create the Custom IOA rule group from section 9 scoped to the Q4/Q5 host group. | Two weeks in Detect mode with zero unexplained alerts before considering Prevent. |
Hardening — Tiered
- Patch the three affected builds. 11.0.20 → 11.0.21, 10.1.53 → 10.1.54, 9.0.116 → 9.0.117 at minimum. Going to 11.0.25 / 10.1.58 / 9.0.121 clears the July 2026 Tomcat issues in the same window. MITRE M1051 (Update Software); Apache Tomcat security advisories.
- Block TCP/4000 at the perimeter and between segments. The receiver requires no authentication and a public PoC has circulated since 2026-04-15. Only sibling cluster nodes should reach it. MITRE M1030 (Network Segmentation), M1037 (Filter Network Traffic); CIS Benchmark host-firewall controls.
- Bind the receiver to a dedicated cluster interface rather than the primary one. Cyber Kendra's analysis notes the default binds to the primary network interface, which is what puts it on the internet-facing address on a single-NIC host. MITRE M1030; Apache Tomcat clustering documentation.
- Grep every Tomcat host for
Failed to decrypt messageand treat any occurrence on an affected build as an incident until disproven. MITRE M1047 (Audit).
- Apply a default-deny NetworkPolicy in every namespace running clustered Tomcat, then allow 4000 only between the cluster's own pods. Without a policy, any pod in the namespace reaches 4000 on every node. MITRE M1030; CIS Kubernetes Benchmark 5.3.2 (network policies defined for all namespaces).
- Run Tomcat as a dedicated unprivileged account with a nologin shell and no write access to its own webapps/ directory in production. This turns the webshell-drop step into a failure. MITRE M1026 (Privileged Account Management), M1022 (Restrict File and Directory Permissions); CIS Apache Tomcat Benchmark.
- Prune deserialization gadget libraries from the classpath. The RCE is conditional on gadgets being present — Commons Collections 3.x is the classic. Inventory with a dependency scanner and remove or upgrade what the application does not need. MITRE M1042 (Disable or Remove Feature or Program). ⚠ best-practice, no formal benchmark
- Ship catalina.out to the SIEM with a standing rule on the SEVERE decrypt-failure string. MITRE M1047 (Audit).
- Deploy the Custom IOAs from section 9 in Detect mode, scoped to the host group derived from Q4 and Q5.
- Question whether you need Tribes session clustering at all. Sticky sessions at the load balancer, or an external session store, remove the receiver and the entire attack surface. This is the only control that makes the class of bug irrelevant rather than patched. MITRE M1042. ⚠ best-practice, no formal benchmark
- Adopt a JVM-wide deserialization filter (
jdk.serialFilter) with an allowlist for the classes your application legitimately deserializes. This is the generic defence against every future gadget-chain bug, not just this one. MITRE M1042; JEP 290 serialization filtering. ⚠ best-practice, no formal benchmark - Establish a KEV-driven patch SLA that treats a KEV listing as the trigger rather than the CVSS number. This CVE scored 7.5 and was walked from 9.8 to 7.5 mid-week; the number was never the useful signal, active exploitation was. CISA BOD 26-04.
- Baseline every application-server host for child-process behaviour so that "a JVM forked a shell" becomes a preventable event estate-wide rather than a Tomcat-specific rule. MITRE M1040 (Behavior Prevention on Endpoint).
Deployable Playbooks
Playbook 1 — Emergency network containment of the Tribes receiver (Linux)
Prerequisites: root or sudo on the Tomcat host; the address list of your legitimate cluster peers; a maintenance note filed, because a wrong peer list breaks session replication. Reboot required: no. Rollback: stated inline at each step.
# STEP 1 -- record the current state so rollback is exact. sudo iptables-save > /root/iptables.backup.2026-08-07 # Rollback for the whole playbook: sudo iptables-restore < /root/iptables.backup.2026-08-07 # STEP 2 -- allow only your own cluster peers to reach 4000. # Replace PEER_ADDR with each real node address, one rule per peer. sudo iptables -A INPUT -p tcp --dport 4000 -s PEER_ADDR -j ACCEPT # STEP 3 -- drop everything else to 4000. sudo iptables -A INPUT -p tcp --dport 4000 -j DROP # Rollback: sudo iptables -D INPUT -p tcp --dport 4000 -j DROP # STEP 4 -- verify the cluster still replicates before you walk away. sudo iptables -L INPUT -n --line-numbers | grep 4000 grep -i "member added\|memberDisappeared" /opt/tomcat/logs/catalina.out | tail -20 # If peers start disappearing, the peer list in STEP 2 is wrong. Roll back # STEP 3 immediately, fix the list, then re-apply.
Playbook 2 — Patch to a fixed build (Linux, package or tarball)
Prerequisites: a tested rollback artefact (the current Tomcat directory or package version pinned); a maintenance window; confirmation from Q4/Q5 that this host is genuinely in scope. Reboot required: no — a Tomcat service restart only. Rollback: restore the saved directory and restart, detailed below.
# STEP 1 -- confirm the running build is one of the three affected. /opt/tomcat/bin/version.sh | grep -i "server number" # Affected: 11.0.20, 10.1.53, 9.0.116. Anything else -- stop, you are not in scope. # STEP 2 -- snapshot the current install and config. This IS the rollback artefact. sudo systemctl stop tomcat sudo tar czf /root/tomcat-preupgrade-2026-08-07.tgz /opt/tomcat # STEP 3 -- deploy the fixed build. # Minimum: 11.0.21 / 10.1.54 / 9.0.117 # Preferred: 11.0.25 / 10.1.58 / 9.0.121 (also clears the July 2026 issues) # Use your package manager where the distro ships Tomcat, otherwise unpack the # release tarball alongside and repoint the symlink. # STEP 4 -- restore conf/ and start. sudo systemctl start tomcat /opt/tomcat/bin/version.sh | grep -i "server number" grep -i "server startup" /opt/tomcat/logs/catalina.out | tail -3 # Rollback: sudo systemctl stop tomcat # sudo rm -rf /opt/tomcat # sudo tar xzf /root/tomcat-preupgrade-2026-08-07.tgz -C / # sudo systemctl start tomcat
Playbook 3 — Default-deny NetworkPolicy for a clustered Tomcat namespace
Prerequisites: a CNI that enforces NetworkPolicy (Calico, Cilium, or equivalent — with a non-enforcing CNI this manifest applies cleanly and does nothing); the pod label selector for your Tomcat deployment; apply to a non-production namespace first. Reboot required: no. Rollback: kubectl delete networkpolicy for both objects, shown below.
# STEP 1 -- confirm the namespace currently has NO policy (this is the exposure).
kubectl get networkpolicy -n YOUR_NAMESPACE
# STEP 2 -- default-deny all ingress in the namespace.
cat <<'EOF' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: YOUR_NAMESPACE
spec:
podSelector: {}
policyTypes: ["Ingress"]
EOF
# STEP 3 -- allow 4000 ONLY between the Tomcat pods themselves.
cat <<'EOF' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-tribes-intra-cluster
namespace: YOUR_NAMESPACE
spec:
podSelector:
matchLabels: {app: tomcat}
policyTypes: ["Ingress"]
ingress:
- from:
- podSelector:
matchLabels: {app: tomcat}
ports:
- protocol: TCP
port: 4000
EOF
# STEP 4 -- verify replication survived.
kubectl logs -n YOUR_NAMESPACE -l app=tomcat --tail=50 | grep -i member
# Rollback: kubectl delete networkpolicy allow-tribes-intra-cluster -n YOUR_NAMESPACE
# kubectl delete networkpolicy default-deny-ingress -n YOUR_NAMESPACE
# Delete the allow policy FIRST is wrong -- delete default-deny first if the
# app is down, since that is the object that can black-hole traffic.
Playbook 4 — JVM-wide deserialization filter (defence in depth)
Prerequisites: a JDK supporting JEP 290 serialization filtering (JDK 9 or later, and backported into later 8u releases); a non-production node; an inventory of the classes your application legitimately deserializes. Reboot required: no — a Tomcat restart only. Rollback: remove the line from setenv.sh and restart, shown below.
# STEP 1 -- start in REPORT-ONLY posture on a test node. Do not go straight to # a blocking filter in production; an over-tight filter breaks session # replication in a way that looks like a network fault. sudo cp /opt/tomcat/bin/setenv.sh /root/setenv.sh.backup.2026-08-07 # STEP 2 -- add a conservative reject-list filter. Start by rejecting the # best-known gadget packages, keeping everything else allowed. echo 'CATALINA_OPTS="$CATALINA_OPTS -Djdk.serialFilter=!org.apache.commons.collections.functors.*;!org.apache.commons.collections4.functors.*;!com.sun.org.apache.xalan.**;*"' \ | sudo tee -a /opt/tomcat/bin/setenv.sh # STEP 3 -- restart and soak for a full business cycle on the test node. sudo systemctl restart tomcat grep -i "serialfilter\|filter status: REJECTED" /opt/tomcat/logs/catalina.out | tail -20 # STEP 4 -- only after a clean soak, tighten toward an allowlist of the classes # your application actually needs, and roll to the rest of the cluster one node # at a time. # Rollback: sudo cp /root/setenv.sh.backup.2026-08-07 /opt/tomcat/bin/setenv.sh # sudo systemctl restart tomcat
Containment Runbook
| Phase | Actions | Owner | Evidence to preserve |
|---|---|---|---|
| 0 · Scope (0–1h) | Run Q4, Q5 and native hunts N2/N3 across the estate. Produce the definitive list of hosts that are (a) an affected build, (b) clustered, (c) binding 4000. Everything downstream is scoped to that list. | Threat hunting | Q4/Q5 result export; server.xml and version output per host |
| 1 · Triage (1–4h) | Grep catalina.out on every in-scope host for the SEVERE decrypt-failure string (N1). Run Q1 and Q2 over the in-scope host group for the full retention window, not just today. | SOC L2 | catalina.out copies (do not truncate); Q1/Q2 exports |
| 2 · Isolate (immediate on a confirmed hit) | Falcon network-contain any host where a JVM parented a shell. Do not power off — the SNOWLIGHT-class loader is described as operating in memory and a shutdown destroys that evidence. Apply Playbook 1 to the remaining cluster members. | Incident response | Memory image before any reboot; Falcon process tree export |
| 3 · Eradicate (4–24h) | Patch to a fixed build (Playbook 2). Remove webshells found by N4 and Q6. Remove persistence found by N6 and Q9. Rotate the cluster pre-shared key and every credential readable by the Tomcat account, including datasource passwords in context.xml. | Platform engineering + IR | Removed artefacts hashed and stored; credential rotation log |
| 4 · Recover (24–72h) | Rebuild rather than clean any host with confirmed code execution. Restore from a known-good image predating the earliest decrypt-failure log line. Re-enable clustering only after the peer allowlist from Playbook 1 is in place. | Platform engineering | Rebuild record with the restore point justified by log timeline |
| 5 · Verify (72h+) | Re-run Q1–Q10 across the rebuilt cluster. Confirm N1 returns nothing on patched builds. Deploy the Custom IOAs in Detect mode. Confirm the perimeter no longer accepts 4000 from outside the node set. | Threat hunting | Clean-run evidence; IOA deployment record |
Do not skip phase 0. On most estates it will conclude that nothing is in scope, and that conclusion — documented, with the query output attached — is a legitimate and complete answer to the KEV deadline. Running phases 1 through 5 against hosts that were never clustered burns the response budget on hosts that were never reachable.
Detection Coverage Map
| Technique | Behaviour | CQL | IOA | Coverage |
|---|---|---|---|---|
| T1595.002 | Internet scanning for exposed Tribes receivers | Q3 | — | Partial — only where Falcon sees the accept; perimeter logs are the primary source |
| T1190 | Serialized payload to the unauthenticated receiver | Q3, Q4 | — | GAP — the payload itself is invisible to endpoint telemetry. Native hunt N1 (catalina.out) is the only direct artefact, and it is not CQL unless the log is shipped. |
| T1059.004 | Unix shell spawned by the JVM | Q1 | Yes | Good |
| T1059.001 / .003 | Windows shell spawned by the JVM | Q2 | Yes | Good |
| T1105 | Dropper written to a temp path | Q7 | — | Partial — ELF writes only; a script or in-memory-only stage is not covered |
| T1222.002 | chmod +x on the staged binary | Q8 | — | Partial — noisy alone, strong only in correlation with Q7 and Q1 |
| T1505.003 | Webshell dropped under webapps/ or work/Catalina | Q6 | — | GAP — the file-write events cover executables and JARs. A plain .jsp text file is not an ELF, PE or JAR and will not appear. Native hunt N4 covers this and there is no CQL substitute. |
| T1053.003 / T1543.002 / T1098.004 | Persistence as the tomcat account | Q9 | Yes | Good |
| T1070.004 | Dropper deletes itself after execution | — | — | GAP — no file-delete query in this pack. Q7 catches the write; the deletion is inferred from the file's absence at triage time, not detected. |
| T1572 / T1090 | Tunnelling and reverse-shell C2 | Q10 | — | Partial — name-based only. No hashes or C2 infrastructure were retrievable from a citable source, so a renamed binary evades this entirely. |
| T1210 | Lateral movement to peer cluster nodes | Q3 | — | GAP — Q3's RFC1918 exclusion deliberately hides internal sources, which is exactly where peer-to-peer movement lives. Close this by replacing the cidr exclusion with an explicit node allowlist once you know your node set (see Q3's TUNING lines). |
| Kubernetes east-west | Pod-to-pod reach on 4000 within a namespace | — | — | GAP — intra-namespace pod traffic frequently does not reach EDR. Native hunt N5 plus the Playbook 3 NetworkPolicy is the control, not a detection. |
Validation gates summary. Four of the twelve rows above are outright gaps and three more are partial, which is an honest reflection of a vulnerability whose exploitation leaves almost nothing on the endpoint until the payload runs. The pack's strength is concentrated in the post-exploitation rows (T1059.*, T1053/T1543/T1098) where coverage is genuinely good, and in the scoping queries that tell you whether any of it applies. Work section 11's gates in order before promoting anything: telemetry ready, log ingest, benign baseline, then the two safe positive tests. A pack that fires nothing on an estate with no clustered Tomcat has not failed — it has answered the question.
Hunt Summary Ticket
TITLE: CVE-2026-34486 -- Apache Tomcat Tribes EncryptInterceptor fail-open
deserialization RCE (CISA KEV, deadline 2026-08-07)
SEVERITY: High. Unauthenticated, network-reachable, actively exploited.
CVSS 7.5 (confidentiality-scored) but code execution is the
observed real-world outcome where gadgets are on the classpath.
EPSS 0.426 as of 2026-08-04 -- top 1.5% of all CVEs.
SCOPE: Apache Tomcat 11.0.20, 10.1.53, 9.0.116 ONLY, with clustering
enabled AND EncryptInterceptor configured in the channel.
Single-node Tomcat: not affected. Tomcat 8.5 and earlier: not
affected (component absent). Fixed in 11.0.21 / 10.1.54 / 9.0.117.
HYPOTHESIS: An attacker reached the unauthenticated Tribes receiver on TCP/4000,
sent a raw serialized Java gadget payload, and obtained command
execution as the Tomcat service account -- then dropped a
SNOWLIGHT-class loader, established persistence, and tunnelled out.
QUERIES: Q1 java/tomcat parent spawns Unix shell CONF high FP med
Q2 java.exe parent spawns Windows shell CONF high FP med
Q3 inbound accept on TCP/4000 from outside CONF med FP med
Q4 hosts binding a listener on TCP/4000 CONF med FP low
Q5 running Tomcat JVMs and install paths CONF med FP med
Q6 executable/JAR written into the Tomcat tree CONF med FP med
Q7 ELF written to /tmp or /dev/shm CONF med FP med
Q8 chmod on a temp-path file CONF med FP med
Q9 persistence by the tomcat account CONF high FP low
Q10 tunnelling / reverse-shell tooling CONF med FP high
DO FIRST: 1. Q4 + Q5 -- build the in-scope host list. Most estates stop here.
2. Native N3 -- confirm Cluster AND EncryptInterceptor in server.xml.
3. Native N1 -- grep catalina.out for "Failed to decrypt message".
4. Q1 + Q2 over the in-scope hosts for the full retention window.
5. Patch to 11.0.21 / 10.1.54 / 9.0.117 or later.
FINDINGS: [ ] In-scope host count: ______
[ ] Decrypt-failure log hits: ______
[ ] Q1/Q2 unexplained hits: ______
[ ] Persistence artefacts found: ______
GAPS: - Exploit payload itself is invisible to endpoint telemetry.
- Plain .jsp webshell writes are not covered by CQL (use N4).
- Dropper self-deletion is not detected, only inferred.
- Q3 hides internal sources by design, so peer-to-peer lateral
movement inside RFC1918 is uncovered until you swap the cidr
exclusion for an explicit cluster-node allowlist.
- Kubernetes intra-namespace pod traffic on 4000 is usually unseen.
- ZERO atomic IOCs shipped. No hash, IP or domain for this vector
exists in any source snapshotted for this pack. This is correct,
not incomplete.
ACTIONS: [ ] Patch all in-scope hosts (Playbook 2)
[ ] Restrict TCP/4000 to cluster peers (Playbook 1)
[ ] NetworkPolicy for Kubernetes namespaces (Playbook 3)
[ ] Ship catalina.out to SIEM with a standing SEVERE rule
[ ] Deploy 3 Custom IOAs in Detect mode, scoped to Q4/Q5 hosts
[ ] Evaluate jdk.serialFilter as strategic defence (Playbook 4)
OWNER: HuntPack
VERSION: v0.1 · 2026-08-07
Changelog
References
| Tier | Source | Used for | Accessed |
|---|---|---|---|
| 1 | Apache Tomcat — Security 11 | Advisory text, affected build 11.0.20, fix 11.0.21 (2026-04-04), commit 1fab40cc | 2026-08-07 |
| 1 | Apache Tomcat — Security 10 | Affected build 10.1.53, fix 10.1.54 (2026-04-02), commit 55f3eb91 | 2026-08-07 |
| 1 | Apache Tomcat — Security 9 | Affected build 9.0.116, fix 9.0.117 (2026-04-03), commit 776e12b3 | 2026-08-07 |
| 1 | CISA — Adds Three Known Exploited Vulnerabilities to Catalog | KEV listing 2026-08-04, BOD 26-04 applicability | 2026-08-07 |
| 1 | NVD — CVE-2026-34486 | CWE-311 / CWE-807, the CISA-ADP 9.8-to-7.5 revision on 2026-08-06, SSVC exploitation=active | 2026-08-07 |
| 1 | Red Hat — CVE-2026-34486 | Vendor impact statement, CVSS vector, RHEL and JBoss Web Server exposure | 2026-08-07 |
| 2 | Unit 42 — Autonomous AI cyber attack campaign | knaithe / KnYuan attribution; "Java deserialization reverse shell attempts against nine Apache Tomcat servers" | 2026-08-07 |
| 2 | The Hacker News — CISA Flags Langflow RCE, Tomcat, and N-central Flaws | KEV corroboration, FCEB deadline 2026-08-07, SNOWLIGHT campaign narrative relayed from SOCRadar | 2026-08-07 |
| 2 | Cyber Kendra — Apache Tomcat's Security Fix Opened the Door to Unauthenticated RCE | Root-cause mechanism, the SEVERE log artefact, port 4000 binding, Kubernetes namespace exposure | 2026-08-07 |
| 2 | kkm-mako — Tomcat CVE-2026-34486 Is Under Attack | Three-build scope confirmation, EPSS 0.426, caution on the overstated public-repo RCE claim | 2026-08-07 |
| — | socradar.io (CVE analysis and SNOWLIGHT campaign posts) | Not cited. Both URLs returned HTTP 403 to automated fetch, so no snapshot exists and nothing in this pack is sourced from them. | 2026-08-07 (failed) |
Defensive content only. This pack deliberately contains no exploit code and no link to any proof-of-concept repository. Public PoCs for this CVE exist and are offensive tooling; they were not fetched, run or reproduced. The mechanism is described at the level needed to build detections and nothing further.
HuntPack · CVE-2026-34486 Apache Tomcat Tribes EncryptInterceptor Fail-Open · v0.1 · Generated 2026-08-07 by HuntPack · 10 source snapshots · behaviour-led, zero atomic indicators · defensive content only.