Estoy tratando de entender cómo funciona el desbordamiento de pila simple (en Linux de 32 bits) pero estoy frente a un problema extraño.
Estoy usando enlace para probar mi código. Todo funciona muy bien. Mi shellcode está ejecutado perfectamente, así que creo que entiendo (un poco) lo que estoy haciendo.
PERO, cuando intento lo mismo en mi computadora (el mismo código, las mismas opciones de GCC, ASLR desactivado), me enfrento a un problema extraño. Simplemente no puedo sobrescribir EIP: /
En primer lugar, este es el código:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char*argv[])
{
char buffer[256];
if(argc < 2) {
perror("Usage: ./pwnme twitt\n");
return 1;
}
strcpy(buffer,argv[1]);
printf("%s", buffer);
return 0;
}
En el servidor del desafío, se sobrescribe el EIP (¡Buenas noticias!):
$> lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.6 (jessie)
Release: 8.6
Codename: jessie
$> uname -a
Linux binary-challenges-pwnerrank-com 3.2.0-4-amd64 #1 SMP Debian 3.2.82-1 x86_64 GNU/Linux
$> file ./pwnme
./pwnme: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=b49c31fc047654c28f93910c8e04cecb6a19ac30, not stripped
$> gdb -q ./pwnme
(gdb) r 'python -c 'print "A" * 280''
[SEGFAULT]
(gdb) i r
eax 0x0 0
ecx 0x0 0
edx 0xf7fc9878 -134440840
ebx 0xf7fc8000 -134447104
esp 0xffffd5e0 0xffffd5e0
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x41414141 0x41414141
eflags 0x10286 [ PF SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb)
=============================================== ======================
Ahora, lo probaré en mi propio Linux (con el mismo código C):
$> lsb_release -a
No LSB modules are available.
Distributor ID: LinuxMint
Description: Linux Mint 18 Sarah
Release: 18
Codename: sarah
$> uname -a
Linux 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
Compilación:
$> gcc bof.c -o pwnme -fno-stack-protector -z execstack -m32
ASLR desactivado:
$> $ sudo cat /proc/sys/kernel/randomize_va_space
0
$> file pwnme
pwnme: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=bf0e63dc240cb7a8e72fd656677a2d03a93588ed, not stripped
$ gdb -q ./pwnme
Reading symbols from ./pwnme...(no debugging symbols found)...done.
(gdb) r 'python -c 'print "A" * 280''
Starting program: /home/n3r0x/Documents/BoF/pwnme 'python -c 'print "A" * 280''
Program received signal SIGSEGV, Segmentation fault.
0x080484db in main ()
(gdb) i r
eax 0x0 0
ecx 0x41414141 1094795585
edx 0xf7fac870 -134559632
ebx 0x0 0
esp 0x4141413d 0x4141413d
ebp 0x41414141 0x41414141
esi 0xf7fab000 -134565888
edi 0xf7fab000 -134565888
eip 0x80484db 0x80484db <main+112>
eflags 0x10286 [ PF SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb)
Como puede ver, esta vez solo se sobrescribe EBP. Y no entiendo por qué: / ¿Quizás otra característica de seguridad en algún lugar? Tienes una idea ? Y por supuesto, si sustituyo 280 'A' por 300 o más 'A', es lo mismo.
Muchas gracias :)
[EDITAR] - Lo siento, encontré la respuesta en este foro. Era solo una cuestión de alineación de pila. Todo está aquí: ¿Compilando un ejemplo de desbordamiento de búfer en Linux moderno?
Moví el strcpy en una función diferente, funciona muy bien. Y la última respuesta da una buena explicación.
¡Gracias por tu ayuda!