Docker
Last updated
Last updated
Related Sites:
Tools:
Dockscan is security vulnerability and audit scanner for Docker installations
dockscan unix:///var/run/docker.sock
dockscan -r html -o myreport -v tcp://example.com:5422
Docker Enumeration, Escalation of Privileges and Container Escapes (DEEPCE)
./deepce.sh
./deepce.sh --no-enumeration --exploit PRIVILEGED --username deepce --password deepce
./deepce.sh --no-enumeration --exploit SOCK --shadow
./deepce.sh --no-enumeration --exploit DOCKER --command "whoami>/tmp/hacked"
Docker is a set of platform as a service (PaaS) products that uses OS-level virtualization to deliver software in packages called containers.
Prerequisite: * Socket mounted as volume : -
"/var/run/docker.sock:/var/run/docker.sock"
Usually found in /var/run/docker.sock
, for example for Portainer.
Prerequisite: * Docker run with -H tcp://0.0.0.0:XXXX
Mount the current system inside a new "temporary" Ubuntu container, you will gain root access to the filesystem in /mnt
.
From there you can backdoor the filesystem by adding an ssh key in /root/.ssh
or adding a new root user in /etc/passwd
.
Docker Registry’s fingerprint is Docker-Distribution-Api-Version
header. Then connect to Registry API endpoint: /v2/_catalog
.
Access a private registry and start a container with one of its image
Access a private registry using OAuth Token from Google
Prerequisite (at least one): --privileged
--security-opt apparmor=unconfined --cap-add=SYS_ADMIN
flags.
Find the mounting point using mount
Create an evil binary at the root of the filesystem: cp /tmp/poc /poc
Set the program to be executed on the coredumps
Generate a coredump with a faulty program: gcc -o crash crash.c && ./crash
Your payload should have been executed on the host.
The vulnerability allows a malicious container to (with minimal user interaction) overwrite the host runc binary and thus gain root-level code execution on the host. The level of user interaction is being able to run any command ... as root within a container in either of these contexts: Creating a new container using an attacker-controlled image. Attaching (docker exec) into an existing container which the attacker had previous write access to. - Vulnerability overview by the runC team
When privileged Linux containers attempt to load kernel modules, the modules are loaded into the host's kernel (because there is only one kernel, unlike VMs). This provides a route to an easy container escape.
Exploitation: Clone the repository : git clone https://github.com/xcellerator/linux_kernel_hacking/tree/master/3_RootkitTechniques/3.8_privileged_container_escaping
Build with make
Start a privileged docker container with docker run -it --privileged --hostname docker --mount "type=bind,src=$PWD,dst=/root" ubuntu
cd /root
in the new container Insert the kernel module with ./escape
Run ./execute
!
Unlike other techniques, this module doesn't contain any syscalls hooks, but merely creates two new proc files; /proc/escape
and /proc/output
.
/proc/output
just takes input and stores it in a buffer when written to, then returns that buffer when it's read from - essentially acting a like a file that both the container and the host can read/write to.
The clever part is that anything we write to /proc/escape
gets sandwiched into /bin/sh -c <INPUT> > /proc/output
. This means that the command is run under /bin/sh
and the output is redirected to /proc/output
, which we can then read from within the container.
Once the module is loaded, you can simply echo "cat /etc/passwd" > /proc/escape
and then get the result via cat /proc/output
. Alternatively, you can use the execute
program to give yourself a makeshift shell (albeit an extraordinarily basic one).
The only caveat is that we cannot be sure that the container has kmod
installed (which provides insmod
and rmmod
). To overcome this, after building the kernel module, we load it's byte array into a C program, which then uses the init_module()
syscall to load the module into the kernel without needing insmod
. If you're interested, take a look at the Makefile.
Running linpeas or other script to identify vulnerabilities if there is evidence of being in a docker environment, or being able to run docker, or being a member of the docker group we can check:
If we have a shell it can be used to break out from restricted environments by spawning an interactive system shell. The resulting is a root shell.
The first thing to check are the docker images that we can use:
In this example the bash image identified above will be used. We can break out of the shell with:
And we are able to successfully escape and are root
It writes data to files, it may be used to do privileged writes or write files outside a restricted file system.
Write a file by copying it to a temporary container and back to the target destination on the host:
It reads data from files, it may be used to do privileged reads or disclose files outside a restricted file system.
Read a file by copying it to a temporary container and back to a new location on the host.
If the binary has the SUID bit set, it does not drop the elevated privileges and may be abused to access the file system, escalate or maintain privileged access as a SUID backdoor. If it is used to run sh -p
, omit the -p
argument on systems like Debian (<= Stretch) that allow the default sh
shell to run with SUID privileges.
This example creates a local SUID copy of the binary and runs it to maintain elevated privileges. To interact with an existing SUID binary skip the first command and run the program using its original path.
The resulting is a root shell.
If the binary is allowed to run as superuser by sudo, it does not drop the elevated privileges and may be used to access the file system, escalate or maintain privileged access.
The resulting is a root shell.
Exploit using
Exploit for CVE-2019-5736 :
/proc/escape
only answers to write requests and simply executes anything that's passed to it via .