Overflow buffer: indirizzi di memoria

4

Va bene, ho cercato traboccamenti di buffer ultimamente per curiosità. Quello che non capisco è quando sviluppi l'exploit con una macchina virtuale o qualsiasi altra cosa, trovi l'indirizzo di memoria che trabocca il puntatore dell'istruzione con e bam, il tuo exploit funziona. Quello che non capisco è come funziona quell'exploit su un'altra macchina? Questo indirizzo di memoria non sarebbe completamente diverso?

    
posta Genthorn 20.12.2016 - 01:45
fonte

1 risposta

5

Sì e no. Gli indirizzi di memoria che vedi da un processo non corrispondono direttamente alla memoria fisica (o anche virtuale). Uno dei compiti del kernel è mappare la memoria di ogni processo e dare a quel processo l'illusione di essere l'unico processo in esecuzione su una macchina.

Quindi tutti i processi iniziano la loro .text (e altre parti di codice e librerie statiche) dalla memoria vicina a 0x0 e il loro stack inizia dalla fine della memoria. (Questo è in realtà più complesso di così, ma è un'analogia abbastanza decente.Inoltre, dal momento che malloc() è una chiamata di sistema, il kernel dirà al processo un problema di memoria esaurita, indipendentemente dalla quantità di memoria che il processo vede). Se si avvia lo stesso processo con lo stesso input due volte, la sua memoria apparirà uguale su entrambi gli avvii.

La mappatura finale tra la memoria vista da un processo e la memoria fisica viene effettuata dalla CPU mediante l'uso di tabelle di mappatura (di cui la CPU viene detta tramite un registro).

D'altra parte non è così facile. Vedendo il problema con la possibilità dell'overflow usando la stessa randomizzazione dello stack dell'indirizzo di memoria (ASLR) è entrata in vita. Diversi sistemi operativi oggi abilitano la randomizzazione dello stack di default, in cui il kernel non avvia la memoria di un processo da 0x0 ma da un valore iniziale casuale. Ciò rende la memoria del processo da spostare di una manciata di byte anche quando lo stesso processo inizia due volte.

Esempio

Il seguente programma banale:

#include <stdio.h>

int main(void) {
    int i;
    printf("%p\n", &i);
    return 0;
}

Quando viene eseguito su una macchina con randomizzazione in pila (ASLR) abilitato stamperà indirizzi distinti, ma quando lo disattivo inizia a stampare gli stessi indirizzi (supponendo che il file con il programma sia denominato c.c ):

[~]$ gcc -o c c.c
[~]$ ./c
0x7ffd52d0aa3c
[~]$ ./c
0x7ffc27da904c
[~]$ sudo echo 0 > /proc/sys/kernel/randomize_va_space
[~]$ ./c
0x7fffffffe86c
[~]$ ./c
0x7fffffffe86c

Nota aggiuntiva

Dopo aver provato questo su due macchine simili molto (x86_64 linux 4.8.13) ho ottenuto esattamente lo stesso output delle ultime due righe. Questo perché il programma e il kernel sono deterministici.

Tuttavia, potrebbe non essere il caso di versioni molto diverse del kernel. Ad esempio, il kernel 2.x produrrà probabilmente un indirizzo diverso per i . Ciò significa che la VM in cui viene sviluppato un exploit deve rispecchiare il più possibile la macchina target (da qui il rischio di impronte digitali della macchina).

    
risposta data 20.12.2016 - 02:37
fonte

Leggi altre domande sui tag