Non può sovrascrivere EIP nell'esempio di sfruttamento di base

1

Sto tentando di replicare un semplice overflow del buffer per il quale ho il seguente codice (strcpy_ex.c):

#include <string.h>

int main( int argc, char** argv ) {
        char buffer[500];
        strcpy(buffer, argv[1]);
        return 0; 
}

che compilo usando:

gcc -m32 -z execstack strcpy_ex.c -fno-stack-protector -o strcpy

L'obiettivo è ottenere una shell sfruttando il difetto di overflow del buffer quando si riempie il buffer con più di 500 caratteri.

Dalla letteratura che ho letto, mi aspettavo di sovrascrivere l'EIP per modificare il flusso di esecuzione e puntare a un indirizzo di memoria in cui risiede il mio shellcode. Per raggiungere questo obiettivo, ho tentato di riempire il buffer con "A" seguito da "B" per individuare dove si verifica la sovrascrittura:

(gdb) r $(python -c "print 'A'*500+'B'*500")
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/Examples/Buffer Overflow/strcpy $(python -c "print 'A'*500+'B'*500")

Program received signal SIGSEGV, Segmentation fault.
0x565555ec in main ()

Purtroppo, non sono riuscito a sovrascrivere EIP. Mi aspettavo di trovare un valore 0x42424242 in EIP, ma non l'ho fatto.

(gdb) i r eip esp
eip            0x565555ec   0x565555ec <main+76>
esp            0x4242423e   0x4242423e

Ulteriori informazioni sulle istruzioni ASM:

(gdb) disas main
Dump of assembler code for function main:
   0x565555a0 <+0>: lea    0x4(%esp),%ecx
   0x565555a4 <+4>: and    $0xfffffff0,%esp
   0x565555a7 <+7>: pushl  -0x4(%ecx)
   0x565555aa <+10>:    push   %ebp
   0x565555ab <+11>:    mov    %esp,%ebp
   0x565555ad <+13>:    push   %ebx
   0x565555ae <+14>:    push   %ecx
   0x565555af <+15>:    sub    $0x200,%esp
   0x565555b5 <+21>:    call   0x565555ed <__x86.get_pc_thunk.ax>
   0x565555ba <+26>:    add    $0x1a46,%eax
   0x565555bf <+31>:    mov    %ecx,%edx
   0x565555c1 <+33>:    mov    0x4(%edx),%edx
   0x565555c4 <+36>:    add    $0x4,%edx
   0x565555c7 <+39>:    mov    (%edx),%edx
   0x565555c9 <+41>:    sub    $0x8,%esp
   0x565555cc <+44>:    push   %edx
   0x565555cd <+45>:    lea    -0x1fc(%ebp),%edx
   0x565555d3 <+51>:    push   %edx
   0x565555d4 <+52>:    mov    %eax,%ebx
   0x565555d6 <+54>:    call   0x56555400 <strcpy@plt>
   0x565555db <+59>:    add    $0x10,%esp
   0x565555de <+62>:    mov    $0x0,%eax
   0x565555e3 <+67>:    lea    -0x8(%ebp),%esp
   0x565555e6 <+70>:    pop    %ecx
   0x565555e7 <+71>:    pop    %ebx
   0x565555e8 <+72>:    pop    %ebp
   0x565555e9 <+73>:    lea    -0x4(%ecx),%esp
=> 0x565555ec <+76>:    ret    

A causa della semplicità del codice, l'EIP non dovrebbe essere sovrascritto immediatamente dopo il riempimento del buffer?

Anche se in questa situazione non dovrebbe fare alcuna differenza, vorrei chiarire che ASLR è disattivato.

Cosa mi manca?

Per quanto riguarda la piattaforma:

# uname -a
Linux kali 4.9.0-kali4-amd64 #1 SMP Debian 4.9.30-2kali1 (2017-06-22) x86_64 GNU/Linux
    
posta Jausk 28.07.2017 - 21:32
fonte

1 risposta

1

Potrei mancare qualcosa qui, ma il modo più semplice per sfruttarlo è che la chiamata strcpy () è in un'altra funzione. In questo modo, si sovrascrive l'indirizzo di ritorno memorizzato, essenzialmente dando il controllo a EIP.

La tua funzione principale in realtà non ritorna in uno spazio che controlli.

Rendi il codice simile a:

#include <string.h>

void vuln(char *arg) {
    char buffer[500];
    strcpy(buffer, arg);
}  

int main( int argc, char** argv ) {
    vuln(argv[1]);
    return 0; 
}

L'overflow avverrà quando vuln () viene terminato e recupera l'indirizzo di ritorno memorizzato (ma sovrascritto) per tornare indietro a main ().

Questo dovrebbe iniziare.

    
risposta data 28.07.2017 - 21:44
fonte

Leggi altre domande sui tag