title: Writing a return-to-libc attack, but libc is loaded at 0x00 in memory
body: <p>I'm writing a return to libc attack for my systems security class. First, the vulnerable code:</p>
  
  <pre><code>//vuln.c
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  int loadconfig(void){
    char buf[1024];
    sprintf(buf, "%s/.config", getenv("HOME"));
    return 0;
  }
  
  int main(int argc, char **argv){
    loadconfig();
    return 0;
  }
  </code></pre>
  
  <p>I want to use a return to libc attack. Compiling and debugging the program:</p>
  
  <pre><code>$ gcc -g -fno-stack-protector -o vuln vuln.c
  $ gdb vuln
  (gdb) break loadconfig
  (gdb) run
  Reached breakpoint blah blah blah.
  (gdb) p $ebp
  $1 = (void *) 0xbfffefb0
  (gdb) p system
  $2 = {&lt;text variable, no debug info&gt;} 0x0016db20 &lt;system&gt;
  (gdb) p exit
  $3 = {&lt;text variable, no debug info&gt;} 0x001639e0 &lt;exit&gt;
  (gdb) x/2000s $esp
  ...
  0xbffff5af:    "SHELL=/bin/bash"
  </code></pre>
  
  <p>To execute the attack, I want to overflow the buffer into <code>loadconfig</code>'s return address (aka <code>$esp+4</code>), replacing it with the return address for <code>system</code>, then the return address for <code>exit</code> (since <code>system</code> expects a real return address), then the command name (the address of <code>SHELL=/bin/bash</code> plus 6, to trim the <code>SHELL=</code> part). This should be possible by crafting a <code>$HOME</code> environment variable of 1024 characters of crap, then the little-endian address of <code>system</code>, <code>exit</code>, and <code>/bin/bash</code>.</p>
  
  <p>However, with every computer I've tried, <code>system</code> gets loaded at an address that starts with 0x00, which will null terminate the string that <code>sprintf</code> is reading and stop the attack dead. Is there some way to force <code>libc</code> to load elsewhere in memory, or am I misinterpreting the attack?</p>
  
  <p>For reference, I'm running an Ubuntu Server 11.10 virtual machine in VirtualBox (Windows host), with <code>gcc</code> version 4.6.1 and <code>gdb</code> version 7.3-2011.08. edit: ASLR is disabled, and I compiled with <code>-fno-stack-protector</code> to remove the canary. Since I'm not executing anything from the stack, I don't need to <code>execstack</code> it.</p>