Si consideri il seguente codice vulnerabile/programma:Sfruttando un overflow stringhe basata su x86-64 con NX (DEP) e ASLR abilitato
#include <string.h>
int main(int argc, char *argv[]) {
char buf[16];
strcpy(buf, argv[1]);
return 0;
}
On IA-32 (x86, 32-bit) con Linux con NX e ASLR attivati, voglio sfruttare questa tecnica utilizzando GOT-sovrascrittura, che comprende essenzialmente i seguenti stadi:
- tampone Overflow sino RIP
- sovrascrittura RIP con l'indirizzo di
[email protected]
- Utilizzare un gadget pulito da
.text
, ad es.pop edi ; pop ebp ; ret
, come indirizzo di ritorno perstrcpy
- argomenti di scrittura per
strcpy
:&bss
-address come destinazione e un byte di/bin/sh
usando.text
- Ripetere i passaggi 2-4 fino a quando
/bin/sh
è completamente scritto a&bss
- sovrascrittura GOT-entry di
strcpy
consystem
(usando offset, richiede conoscenza sulla versione utilizzata di Libc - ignoriamolo qui) - Scrivi
[email protected]
nello stack, seguito da un chunk di 4 byte e infine l'indirizzo di&bss
whi punti CH Per/bin/sh
- Profit
mi vogliono sfruttare questo su x86-64 con le stesse misure di mitigazione abilitati. Ma questo è più difficile come immaginato. In sostanza per i seguenti motivi:
- x86-64 basato su registri convenzione di chiamata: argomenti della funzione sono passati usando registri, non lo stack. Pertanto alcuni gadget ROP aggiuntivi sono necessari per trasferire gli argomenti dallo stack nel registro appropriato. Questo è un problema minore, ma è influenzato anche dalla seguente problema: indirizzo di ritorno
64-bit: Il RIP in x86-64 punti
.text
che non è nemmeno 32 bit lungo. Pertanto, i byte NULL devono essere scritti nello stack per raggruppare le chiamate di funzione. Fondamentalmente si possono scrivere tanto NULL-byte come desiderato usando le chiamate concatenate astrcpy
e sfruttando il carattere di terminazione NULLstrcpy
scritture sempre. Ma si può chiamare solostrcpy
una volta solo sovrascrivendo i byte meno significativi del RIP.|0x00000000| (most significant bytes) |0x00deadbe| <- RIP (least significant bytes) |0x41414141| |0x41414141| <- SFP | ... |
Questi sono i principali problemi che ho avuto con sfruttando il programma su x86-64 con NX e ASLR abilitati. Esistono tecniche che risolvono questi problemi? O x86-64 impedisce davvero un exploit funzionante, che apre la shell?
Se RIP deve rappresentare l'indirizzo di ritorno, è necessaria una nuova terminologia per x86-64. Proprio come EAX è esteso a RAX, EIP (il puntatore di istruzioni corrente) viene esteso a RIP. Quindi in x86-64, RIP è un nome di registro, e non (da solo) crea un buon nome per l'indirizzo di ritorno che RET leggerà. –