Si efectivamente es la version de gcc
%gcc41 codigo.c -o codigo -ggdb -static
%gdb codigo
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-marcel-freebsd"...
(gdb) disas main
Dump of assembler code for function main:
0x080481b0 <main+0>: lea 0x4(%esp),%ecx
0x080481b4 <main+4>: and $0xfffffff0,%esp
0x080481b7 <main+7>: pushl 0xfffffffc(%ecx)
***************************
***************************
0x080481f2 <main+66>: mov 0xfffffffc(%ebp),%ecx
0x080481f5 <main+69>: leave
0x080481f6 <main+70>: lea 0xfffffffc(%ecx),%esp
0x080481f9 <main+73>: ret
End of assembler dump.
El problema es que salva esp en la pila (a traves de ecx), y lo restaura antes de hacer el ret. La forma de explotarlo seria sobreescribir ese valor con una direccion en la que controlemos el contenido. Ejemplo:
- Sobreescribimos esp guardado por 0xdededede (es un caso ficticio).
- 0xdededede es una direccion en la que controlamos su contenido, el cual es: 0xabababab
- En 0xabababab tambien controlamos su contenido, el cual es: la shellcode
Al sobreescribir el esp guardado, antes del ret: %esp = 0xdededede. Hace el ret y salta a 0xabababab, la cual es la direccion de la shellcode.
Cambiando de tema, en ese ejemplo no importa que el buffer sea pequeño. Puedes meter la shellcode en argv[2] por ejemplo, sin limite de tamaño.
Un saludo.