title: Simple heap overflow exploit with toy example on old glibc
body: <p>Consider this example of a heap buffer overflow vulnerable program in Linux, taken directly from the "Buffer Overflow Attacks" (p. 248) book:</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  
  int main(int argc, char **argv)
  {
      char *A, *B;
  
      A = malloc(128);
      B = malloc(32);
  
      strcpy(A, argv[1]);
  
      free(A);
      free(B);
  
      return 0;
  }
  </code></pre>
  
  <p>Since unlink() has been changed to prevent the most simple form of exploit using the FD and BK pointers with a sanity check, I'm using a very old system I have with an old version of glibc (version 2.3.2). I'm also setting MALLOC_CHECK_=0 for this testing.</p>
  
  <p>My goal of this toy example is to simply see if I can write 4 bytes to some arbitrary address I specify. The most simple test I can think of is to try write something to 0x41414141, which is an illegal address and should let the program crash to just confirm to me that it is indeed trying to write to this address (something I should be able to observe in GDB).</p>
  
  <p>So I try executing with the argument <code>perl -e 'print "A"x128 . "\xf8\xff\xff\xff" . "\xf8\xff\xff\xff" . "\x41\x41\x41\x41" . "\x41\x41\x41\x41" '</code></p>
  
  <p>So I have:</p>
  
  <pre><code>Buffer A: 128 bytes of 0x41.
  prev_size: 0xfffffff8
  size: 0xfffffff8
  FD: 0x41414141
  BK: 0x41414141
  </code></pre>
  
  <p>I'm using 0xfffffff8 instead of 0xfffffffc because there is a note that with glibc 2.3 the third lowest bit NON_MAIN_AREA is used for management purposes for the arenas and has to be 0.</p>
  
  <p>This should attempt to write 0x41414141 to 0x41414141 (+ 12 to be more correct, but still an illegal address), correct? However, when I execute this, the program simply terminates normally.</p>
  
  <p>What am I missing here? This seems simple enough that it shouldn't be that hard to get to work.</p>
  
  <p>I've tried various things such as using 0xfffffffc instead for prev_size and size, using legal addresses for FD (some address on the heap). I've tried swapping the order A and B are free()'d, I've tried to step into free() to see what happens in GDB but I got lost. Note that there shouldn't be any other security features on this system as it is very old and wouldn't have NX-bit, ASLR, etc (not that it should matter for the purpose of just writing 4 bytes to an illegal address).</p>
  
  <p>Any ideas for how to make this work?</p>
  
  <p>I could add that if using MALLOC_CHECK_=3 I get this:</p>
  
  <pre><code>malloc: using debugging hooks
  malloc: using debugging hooks
  free(): invalid pointer 0x8049688!
  
  Program received signal SIGABRT, Aborted.
  0x4004a1b1 in kill () from /lib/libc.so.6
  </code></pre>