2013-07-11 18 views
6

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:

  1. tampone Overflow sino RIP
  2. sovrascrittura RIP con l'indirizzo di [email protected]
  3. Utilizzare un gadget pulito da .text, ad es. pop edi ; pop ebp ; ret, come indirizzo di ritorno per strcpy
  4. argomenti di scrittura per strcpy: &bss -address come destinazione e un byte di /bin/sh usando .text
  5. Ripetere i passaggi 2-4 fino a quando /bin/sh è completamente scritto a &bss
  6. sovrascrittura GOT-entry di strcpy con system (usando offset, richiede conoscenza sulla versione utilizzata di Libc - ignoriamolo qui)
  7. Scrivi [email protected] nello stack, seguito da un chunk di 4 byte e infine l'indirizzo di &bss whi punti CH Per /bin/sh
  8. 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:

  1. 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
  2. 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 a strcpy e sfruttando il carattere di terminazione NULL strcpy scritture sempre. Ma si può chiamare solo strcpy 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?

+1

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à. –

risposta

0

x86-64 non impedisce questo tipo di exploit. Vedi questo tutorial.

+1

Poiché questa domanda presuppone x86-64 sia con ASLR sia con NX abilitato, il collegamento non fornisce una soluzione: "Ho dovuto imbrogliare su questo un po 'disattivando l'ASLR. A causa della natura dell'indirizzamento su 64-bit i sistemi, i byte null diventano un problema molto grande.Per questa particolare sfida, è facile sovrascrivere RIP, ma potrei tornare a un singolo gadget a causa dei byte null. " – Propantriol