Ci sono alcuni punti da notare:
1. La funzione strcpy interrompe la copia di roba nel buffer di destinazione non appena incontra un byte NULL. Un byte NULL è 0x00 o \ x00 . Nelle macchine a 64 bit, la lunghezza di un indirizzo è 8 byte. Prendiamo in considerazione pop_rdi_ret = 0x00000000004005cb . Questo ha byte NULL. Quindi, non appena strcpy incontra il primo byte NULL (il byte NULL accanto a 0x40), smette di copiare. Pertanto, il carico utile di exploit non viene iniettato correttamente a causa dei byte NULL.
2. Spero che tu abbia compilato il tuo programma vulnerabile senza StackGaurd o la protezione Stack Cookie. Se è lì, ucciderà il programma quando rileva uno scontro. Puoi utilizzare il flag del compilatore -fno-stack-protector per compilare senza StackGaurd.
3. Non so perché stai iniettando NOP nel buffer. Non c'è nulla di male nel farlo, ma non serve nemmeno perché W XOR X è abilitato.
And, please can anyone help me little to understand the concept of ROP stack frame in 64 bit, I mean 32 bit ROP stack frame is simple to understand as compared to 64 bit and available content on the internet about the 64 bit ROP didn't help me.
Quando si parla di ROP, non vi è alcuna differenza tra ROP a 32 bit e ROP a 64 bit. Questo perché in entrambi i casi, i Gadget ROP sono incatenati.
Se stai parlando di ReturnToLibc, ci sono delle differenze. ReturnToLibc è il nome di fantasia dato quello che stai facendo nell'exploit sopra. Stai tornando a una funzione di libc per ottenere l'accesso di dio.
La causa principale di questa differenza è il modo in cui vengono chiamate le funzioni. Il meccanismo di chiamata alle funzioni nei processi a 32 bit e 64 bit è diverso. In 32-bit, gli argomenti vengono passati alla funzione del callee usando lo stack. Ma a 64-bit, i primi 6 argomenti vengono passati usando i registri e se ci sono altri argomenti, viene usato lo stack.
Poiché stiamo chiamando le funzioni qui, gli exploit per 32-bit e 64-bit saranno diversi. Come hai detto bene, l'exploit ReturnToLibc per 64-bit è più o meno ROP perché dovrai trovare dei gadget che caricheranno roba in rdi, rsi, rdx ecc. Se non trovi i gadget giusti, dovrai incatenarli.
Because of that, I am also confused about creating stack frame via ROP for mprotect call for my another exploit code.
Lascia che ti aiuti con questo.
Dai un'occhiata alla pagina di manuale di mprotect.
MPROTECT(2) Linux Programmer's Manual MPROTECT(2)
NAME
mprotect - set protection on a region of memory
SYNOPSIS
#include <sys/mman.h>
int mprotect(void *addr, size_t len, int prot);
Per 32 bit:
Per prima cosa creiamo lo stackframe falso per 32-bit.
Supponiamo di voler rendere eseguibile lo spazio di indirizzamento dello stack.
Lasciare addr = 0xf1f2f3f4, size = 1000, prot = PROT_EXEC | PROT_WRITE | PROT_READ.
I valori di PROT_READ = 1, PROT_WRITE = 2, PROT_EXEC = 4. In riferimento a questo sourcefile .
Quindi, PROT_READ | PROT_WRITE | PROT_EXEC = 7.
La strategia è questa:
a. Sovrascrivi l'indirizzo di ritorno della funzione vulnerabile con l'indirizzo mprotect . Quando viene eseguita l'istruzione ret , il controllo viene trasferito alla funzione mprotect e lo stack viene spuntato. Per mprotect, l'istruzione stack before ret è eseguita nel modo seguente:
<mprotect's Address> // This is vulnerable function's return address
<mprotect's Return Address> // This can be exit libc function
<prot = 0x00000007>
<len = 1000>
<addr = 0xf1f2f3f4>
Quindi, ecco qua. hai lo stackframe che volevi.
Per 64 bit:
Per sfruttare una funzione vulnerabile a 64 bit, dobbiamo passare gli argomenti attraverso i registri. Questo non è facile come lo era per l'exploit a 32 bit. Questo è ciò di cui abbiamo bisogno.
rdi = Indirizzo dello stack = 0x00007ffff7123456 // solo un esempio
rsi = 1000
rdx = 0x7
Ora dobbiamo trovare i gadget che fanno direttamente questo o devono trovare i gadget e incatenarli. Questo è dove diventa un po 'difficile. Scrivere a mano catene ROP richiede tempo. Puoi provare ROPGadget o qualsiasi altro strumento ROP là fuori.
Supponendo di avere i gadget mobili corretti, continuerò la mia risposta.
0x400123: mov rdi, 0x00007ffff7123456; ret
0x401234: mov rsi, 1000; ret
0x412345: mov rdx, 0x7; ret
Il piano è che questi 3 dovrebbero essere eseguiti in fila e quindi mprotect dovrebbe essere eseguito. Quindi, lo stack dovrebbe apparire come questo prima che venga eseguito il ret della funzione vulnerabile.
<0x400123> // This is originally vulnerable function's return address
<0x401234>
<0x412345>
<mprotect's address>
<mprotect's return address>
In realtà, lo stack potrebbe essere molto più complesso di questo. Questo è solo un esempio.
Spero che tu veda la differenza tra lo stack di un exploit a 32 bit e un exploit a 64 bit.
Se qualcosa non è chiaro, lascia un commento qui sotto.