Container isolation fundamentals and the exposed Docker API attack surface
From the host’s perspective, a container is just another process. It shares the same kernel. Two Linux mechanisms keep it isolated: namespaces and cgroups. Namespaces control what the container can see. Cgroups control how much it can use. By default, Docker imposes no memory limits, and the container process runs as root.
“a namespace limits what you can see and the croups limits how much you can use” — Bogdan Trufanda
The Docker daemon normally takes commands over a Unix socket. Expose it over TCP instead, and anyone who can reach that port can issue docker run with root-level privileges on the host. No password. No authentication. That single misconfiguration is the root cause behind every attack covered in this talk.
Kinsing: opportunistic mass scanning and multi-vector payload delivery
Kinsing has been active since 2019. The attack chain is simple: masscan finds exposed Docker APIs, the group deploys an Ubuntu container, then fetches d.sh, which downloads the Kinsing malware and miner. A second script, spre.sh, handles SSH-based lateral movement. The HTTP request still targets Docker API v1.24, meaning they are deliberately hunting older, unmaintained servers.
“half of the content from these scripts is just uh looking and killing other potential miners on your host” — Mihai Vasilescu
The payload scripts (d.sh, o.sh, pg.sh) are identical in content. The only difference is the name, which tags the entry point: d.sh script naming reveals initial access vector (10:23). The Kinsing binary phones home over RC4-encrypted HTTP, and Vasilescu found no public Suricata rules that catch it.
TeamTNT: credential exfiltration, custom Docker images, and Kubernetes pivoting
TeamTNT ran public Twitter and GitHub accounts and corrected analysts on their own blogs when researchers published incomplete kill chains. Starting in early 2020 with Redis, they added exposed Docker API abuse, then credential exfiltration, then Kubernetes scanning via massscan against kubelet endpoints. By 2024, they stopped using legitimate Alpine or Ubuntu images and pushed custom Docker images, XMRig bundled as the entry point, still on Docker Hub today.
The TeamTNT container escape via host filesystem mount and chroot (16:56) runs Alpine with the host filesystem mounted at /mnt, executes chroot /mnt, then pipes a curl-fetched init script into bash, leaving nothing on disk. Cloud metadata endpoints hand over AWS and GCP tokens, which get base64-encoded and sent out via curl. SSH keys found on disk go to pivoting. Sliver lands in /tmp, undisguised.
Outlaw/Haiduk: SSH brute force and commodity tooling bundled in a single archive
Outlaw, named after its original SSH scanner Haiduk, uses brute force or stolen credentials, no Docker API. Once in, the dropper is Dota33.tar.gz: three folders covering mining, persistence, and brute force. The miner is a UPX-packed XMRig binary named kswapd0. Persistence runs through Stealth Shellbot, a Perl-based IRC backdoor whose source literally contains the string “shellbot.” Lateral movement uses Kthread binaries packed with a newer UPX version the default Ubuntu toolchain cannot unpack.
That UPX version choice is the only real evasion effort. Profanity strings in authorized_keys serve as a reliable fingerprint. Active in 2025, mostly commodity tooling, unmodified.
Live demo: exposed Docker API to host root shell and lateral credential theft
The attack takes seconds. From the C2, a single docker run targeting the victim’s exposed TCP socket, with --privileged, --pid=host, and nsenter, drops a root shell on the host before the screen finishes scrolling. Root shell obtained on victim host via privileged container (30:25)
“Exposing your Docker API is like leaving your house door open with all your money on your table and with a sign come in and take them.” — Bogdan Trufanda
With root on the first machine, Hydra brute forces a private-subnet SSH server using a common-password wordlist, finds the Ubuntu user’s credentials, and pivots to a machine with no public IP. AWS and GCP credential files get POSTed to the attacker’s web server in the same pass. AWS and GCP credential exfiltration across private subnet machines (33:57)
Defensive hardening: closing the Docker API exposure gap
Every hardening guide online focuses on container-level controls: set CPU limits, set RAM limits, keep the engine updated. None of that matters once the Docker TCP socket is exposed. Anyone who reaches it runs containers with full privilege flags, no restrictions, no authentication. The fix starts with not exposing the socket. If you must expose it, mutual TLS authentication is the minimum. Rootless Docker adds another layer: a container escape lands you as an unprivileged user, not root on the host. Redis went through this same shift two years ago, restricting writable paths and disabling remote command execution by default. Attacks against it dropped. Docker is promising the same deprecation of unauthenticated TCP exposure, announced for version 26, still not shipped in version 29.
“It’s still kind of crazy that we’re 2025 AI and a lot of these other solutions that we have today and we’re still getting the SSH brute forcing.” — Mihai Vasilescu
Q&A
Did you look into the type of targets they hit — misconfigured corporate environments or hobbyist Docker instances? Both: CrowdStrike sees it in enterprise dev and test environments, and honeypot data confirms the scanning is indiscriminate — if the socket is exposed, attackers probe it regardless of who owns the host. ▶ 40:28
What makes you sure the problem will go away after Docker updates if older unmaintained versions will still be exposed? The speaker conceded it won’t cleanly go away, drawing the Redis parallel: newer Redis versions closed the misconfiguration but old unpatched endpoints still get hit today, and Docker will likely follow the same long tail with volume declining rather than stopping. ▶ 41:26
Have you looked at other container platforms like LXC or Podman from an attack surface perspective? Podman is meaningfully harder to exploit because it maps container root to an unprivileged host user via user namespaces by default, so a container escape lands without root access — Docker offers the same protection via rootless mode but does not enable it by default. ▶ 43:43
Notable Quotes
a namespace limits what you can see and the croups limits how much you can use Bogdan Trufanda · ▶ 2:39
half of the content from these scripts is just uh looking and killing other potential miners on your host Mihai Vasilescu · ▶ 9:59
exposing your docker API is like leaving your house door open with all your money on your table and with a sign come in and take them Bogdan Trufanda · ▶ 31:01
it’s still kind of crazy that we’re 2025 AI and a lot of these other solutions that we have today and we’re still getting the SSH brute forcing Mihai Vasilescu · ▶ 43:23
Key Takeaways
- Never expose the Docker daemon’s TCP socket unauthenticated — it grants root on the host to any caller.
- Script naming conventions in crypto-miner droppers fingerprint the initial access vector; hunt for d.sh, o.sh, and pg.sh on hosts.
- Automated attack chains compress the full kill chain — discovery, escape, mining, credential theft — into under 15 seconds.
About the Speakers
Bogdan Trufanda
Bogdan Trufanda is a Threat Hunter in CrowdStrike’s Cloud Runtime Security Team. Bogdan is responsible for gathering actionable application and security intelligence for CrowdStrike products, specialising in gathering Threat Intelligence and researching exploitation techniques involving containers and the cloud space.
Mihai Vasilescu
Mihai Vasilescu is a Threat Hunter in CrowdStrike’s Cloud Runtime Security Team. Mihai’s expertise lies in gathering Threat Intelligence on recent botnets and network attack exploitation techniques, including malware analysis and botnet tracking.