Correction ·
Revised 3 November 2026: tightened analysis and practical hunting guidance. Observations unchanged.
Watch the mount configuration
From 2026-10-26 through 2026-11-01 UTC, BlackDome retained 108 deduplicated Docker container-create input records requesting a writable bind of the host root filesystem. They contained 24 distinct input contents across 6 reporting sources. The normalized privileged value was false in 46 records and true in 62: a rule requiring true would not select those 46 false-valued records. The emulated Docker Engine API honeypot listens on port 2375, records submitted container-create configurations and returns an emulated response without running a container.
Why check the bind independently
The facade records Privileged as a boolean, and a missing client Privileged option is normalized to false. For this hunt, inspect the mount configuration independently instead of making a true privileged value a precondition.
MITRE ATT&CK T1611 describes mounting the host filesystem through a bind parameter as one container-to-host access mechanism. Primary-source document
A second pivot: the requested command
On 2026-10-27 UTC, 10 retained container-create input records across 5 reporting sources requested append-redirection to an SSH authorized-key path under their requested writable host-root mount. All 10 had a normalized privileged value of true. Inspecting retained command input alongside the mount gives an additional triage pivot for environments that keep those request fields.
Hunt locally, then check ownership
Apply this local predicate to parsed Linux Docker container-create request bodies in logs that retain HostConfig.Binds. It checks writable host-root bind configuration independently of the privileged flag.
def writable_host_root(body):
if not isinstance(body, dict):
return False
host = body.get("HostConfig")
if not isinstance(host, dict):
return False
binds = host.get("Binds")
if not isinstance(binds, list):
return False
for bind in binds:
if not isinstance(bind, str):
continue
source, _, tail = bind.partition(":")
target, _, options = tail.partition(":")
if (source == "/" and target.startswith("/")
and ":" not in options and "ro" not in options.split(",")):
return True
return False
Check the API caller, workload owner, requested mount and approved change record before escalating a match. Where local logs retain command input, inspect it for an authorized-key append request beneath the mounted host root. Where host telemetry is available, correlate the request time with relevant file changes and process activity.