Correction ·
Revised 5 November 2026: replaced the archived roundup with reviewed historical analysis for the original reporting period.
The week's finding
Within the 2026-09-21 through 2026-09-27 UTC reporting week, BlackDome retained 10 matching Java XML request bodies received from 2026-09-25 through 2026-09-26 at 1 sensor. Three wrapper families carried ProcessBuilder command arrays: 8 requested curl with a destination argument, and 2 requested wget with --post-file, /etc/passwd and a destination argument. This analysis examines captured request instructions.
Follow the requested operation
The XML divides into 5 ImageIO ContainsFilter-related bodies, 2 Groovy Expando/MethodClosure bodies and 3 EventHandler proxy bodies. The common link is the ProcessBuilder object and its child command array. Eight arrays request curl with a destination argument. Two request wget with --post-file and /etc/passwd, specifying a local file as the outbound request body.
Those arguments change the investigation. Curl with a destination argument requests an outbound retrieval/callback. The --post-file form requests an account-file read and outward data transfer. A rule that says only “curl or wget appeared” loses that distinction; a rule tied to one wrapper class misses the other object forms.
MITRE ATT&CK's Exploit Public-Facing Application technique describes attempts to exploit weaknesses in exposed hosts or systems for initial access. In this case, use that only as background context: the directly supported pivot is from the HTTP/HTTPS request body and object construction to the ProcessBuilder command arguments when selecting host and network evidence. Primary-source document
Counts and variations
The current HTTP/HTTPS keyword-selected review cohort contains 901 retained event records in 251 daily source/input groups. This Java case accounts for 10 matching records, 10 daily source/input groups and 10 distinct body texts across 1 sensor.
The 2026-09-07 through 2026-09-13 retained Java cohort already contained 8 XML bodies spanning the same 3 wrapper families: 6 curl transfer requests and 2 Wget account-file upload requests. The current cohort contains 10 structured Java transfer-command records, split into 8 curl requests and 2 wget upload requests. The recurring detection target is the ProcessBuilder command relation and its arguments, not a single wrapper family.
Across the adjacent retained review windows, structured Java transfer-command records were 0 for 2026-08-31 to 2026-09-07, 8 for 2026-09-07 to 2026-09-14, 0 for 2026-09-14 to 2026-09-21 and 10 for 2026-09-21 to 2026-09-28, each end exclusive. Use that sequence to time-bound retained-body review and compare wrapper and command-argument shapes across weeks.
A practical local hunt
Run this local structural filter against retained XML bodies. It recognizes either representation of a ProcessBuilder object and checks its own command array, rather than matching disconnected class and tool names elsewhere in the document. The filter accepts a UTF-8 string up to 65536 bytes, reads it locally and performs no network request or submitted-code execution.
def matches_java_transfer(body):
from defusedxml import ElementTree
if not isinstance(body, str) or len(body.encode("utf-8")) > 65536:
return False
try:
root = ElementTree.fromstring(body, forbid_dtd=True,
forbid_entities=True, forbid_external=True)
except (ElementTree.ParseError, ValueError):
return False
except Exception:
return False
for node in root.iter():
if node.tag != "java.lang.ProcessBuilder" and node.get("class") != "java.lang.ProcessBuilder":
continue
command = node.find("command")
if command is not None:
args = [(item.text or "").strip() for item in command.findall("string")]
if args and args[0] in {"curl", "wget"}:
return True
return False
For a hit, preserve the original XML, identify the receiving route and owning Java service, then classify the command arguments before prioritizing follow-up. Where host telemetry is available, correlate the request time with Java child processes, relevant file reads and outbound traffic. For false-positive triage, confirm the caller, the workload owner, the requested operation and any approved change or test record.