32bits Linux - Desbordamiento de pila simple - EIP nunca sobrescrito

5

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!

    
pregunta n3r0x 03.01.2017 - 16:25
fuente

3 respuestas

3

Esta diferencia puede estar ahí debido a la diferente alineación de pila utilizada en el lado del servidor. Para configurar la alineación de la pila, se utiliza la opción " mpreferred-stack-boundary ". Más: enlace

Espero que esto ayude!

    
respondido por el swatilaxmi28 04.01.2017 - 07:04
fuente
1

El comando hardening-check incluido en el paquete hardening-includes también le proporcionará información adicional sobre cualquier característica de seguridad dentro del ejecutable. Creo que el relro está incluido por defecto. Esto se puede desactivar con el siguiente indicador de gcc.

-Wl,-z,norelro
    
respondido por el deadlisting 03.01.2017 - 19:04
fuente
0

Hay un poco más de protección de un kernel de Linux moderno que las opciones de ASLR y GCC en los binarios compilados.

Parece que estás ejecutando Mint . No estoy muy familiarizado con Mint, pero sé que está basado en Ubuntu y Debian y parece estar ejecutando un kernel de Ubuntu.

El Kernel de Ubuntu tiene bastantes características de seguridad de forma predeterminada, es probable que algunas no se puedan desactivar.

La gente de seguridad en Ubuntu tiene un secuencia de comandos de prueba de regresión que está diseñada para garantizar que las características de seguridad estén funcionando. La ejecución local podría arrojar algo de luz sobre el problema o, al menos, señalarle la dirección correcta.

    
respondido por el Rob C 03.01.2017 - 18:38
fuente

Lea otras preguntas en las etiquetas