Come trovare il puntatore dello stack per il bug di overflow?

5

Ho letto che lo stack di solito inizia nello stesso indirizzo in modo che l'attaccante possa indovinare il punto di partenza del buffer da traboccare. È necessario conoscere questo indirizzo per eseguire il codice dannoso. Ho creato un programma con poche righe di codice per ottenere l'indirizzo del puntatore dello stack ogni volta che viene avviato e stampato sullo schermo:

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

E questo è lo smontaggio del programma:

<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 

Ma ogni volta che avvio il programma ottengo diversi indirizzi. Alcuni di questi sono i seguenti:

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

Quindi in questo caso come è possibile che l'attaccante esegua il suo codice sul programma vulnerabile? (il mio sistema operativo è Linux a 64 bit)

EDIT: ho creato un altro programma in assembly che include poche righe semplici. Ho appena controllato il valore di RSP ogni volta che si avvia con il debugger e vedo sempre che RSP ha lo stesso valore ma non il programma scritto in c.

    
posta user2808671 17.03.2015 - 18:29
fonte

1 risposta

5

Il tuo problema è ASLR scegliendo a caso dove viene caricato il tuo programma. Puoi disattivare ASLR in Linux usando sudo sysctl -w kernel.randomiz_va_space=0 .

Ecco il mio programma. Uso RAX anziché EAX e unsigned long * anziché 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;
}

Ecco il mio programma su 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

Ora eseguo: sudo sysctl -w kernel.randomize_va_space=0

Ecco il mio programma senza 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
    
risposta data 17.03.2015 - 19:53
fonte

Leggi altre domande sui tag