¿Cómo encontrar el puntero de la pila para el error de desbordamiento?

5

He leído que la pila generalmente comienza en la misma dirección para que el atacante pueda adivinar el punto de inicio del búfer para desbordarse. Esto es necesario para conocer esta dirección para que se ejecute el código malicioso. Hice un programa con unas pocas líneas de código para obtener la dirección del puntero de la pila cada vez que se inicia e imprimirlo en la pantalla:

int * get_stack_pointer(){
    __asm__("mov %esp,%eax");
}
void main(){
  printf("Address: %p\n",get_stack_pointer());
}

Y esto es desmontaje del programa:

<get_stack_pointer>:
push   %rbp
mov    %rsp,%rbp
mov    %esp,%eax
pop    %rbp
retq   

<main>:
push   %rbp
mov    %rsp,%rbp
mov    $0x0,%eax
callq  40050c <get_stack_pointer>
mov    %rax,%rsi
mov    $0x4005ec,%edi
mov    $0x0,%eax
callq  4003e0 <printf@plt>
pop    %rbp
retq 

Pero cada vez que comienzo el programa obtengo diferentes direcciones. Algunos de estos son los siguientes:

Address: 0xc31b2c80
Address: 0x2e041e0
Address: 0x7b003190
Address: 0xb3fd1350

Entonces, en este caso, ¿cómo es posible que el atacante ejecute su código en el programa vulnerable? (Mi sistema operativo es Linux 64bit)

EDITAR: Hice otro programa en ensamblaje que incluye algunas líneas simples. Solo reviso el valor de RSP cada vez que comienza con el depurador y veo que siempre RSP tiene el mismo valor pero no el programa escrito en c.

    
pregunta user2808671 17.03.2015 - 18:29
fuente

1 respuesta

5

Su problema es ASLR al azar donde se carga su programa. Puedes desactivar ASLR en Linux usando sudo sysctl -w kernel.randomiz_va_space=0 .

Aquí está mi programa. Estoy usando RAX en lugar de EAX, y un unsigned long * en lugar de un int * .

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

unsigned long *get_stack_ptr(void) {
  __asm__(
    "mov %rsp, %rax"
  );
}

int main(int argc, char **argv) {
  unsigned long *stack_ptr = get_stack_ptr();

  printf("Size Of Ptr: %d bytes\n", sizeof(unsigned long *));
  printf("Stack Pointer: %llX\n", stack_ptr);

  return 0;
}

Aquí está mi programa en ASLR:

@narrator:$ ./stackptr 
Size Of Ptr: 8 bytes
Stack Pointer: 7FFD328233D0
@narrator:$ ./stackptr 
Size Of Ptr: 8 bytes
Stack Pointer: 7FFC2B5F07E0
@narrator:$ ./stackptr 
Size Of Ptr: 8 bytes
Stack Pointer: 7FFFE3A2FF10
@narrator:$ ./stackptr 
Size Of Ptr: 8 bytes
Stack Pointer: 7FFE5F0795F0

Ahora realizo: sudo sysctl -w kernel.randomize_va_space=0

Aquí está mi programa sin ASLR:

@narrator:$ ./stackptr 
Size Of Ptr: 8 bytes
Stack Pointer: 7FFFFFFFDF70
@narrator:$ ./stackptr 
Size Of Ptr: 8 bytes
Stack Pointer: 7FFFFFFFDF70
@narrator:$ ./stackptr 
Size Of Ptr: 8 bytes
Stack Pointer: 7FFFFFFFDF70
@narrator:$ ./stackptr 
Size Of Ptr: 8 bytes
Stack Pointer: 7FFFFFFFDF70
    
respondido por el RoraΖ 17.03.2015 - 19:53
fuente

Lea otras preguntas en las etiquetas