Perché la posizione delle variabili di ambiente varia così tanto?


9

Leggendo il libro Hacking: The Art of Exploitation di Jon Erickson, sto cercando di approssimare l'indirizzo di una variabile d'ambiente SHELLCODEper sfruttare un programma.

Ogni volta che corro getenv("SHELLCODE");per ottenere la posizione, il risultato è completamente diverso.

Estratto dalla mia conchiglia:

> for i in $(seq 10); do ./a.out SHELLCODE; done
SHELLCODE is at 0xff9ab3a3
SHELLCODE is at 0xffcdb3a3
SHELLCODE is at 0xffb9a3a3
SHELLCODE is at 0xffa743a3
SHELLCODE is at 0xffdb43a3
SHELLCODE is at 0xfff683a3
SHELLCODE is at 0xffef03a3
SHELLCODE is at 0xffc1c3a3
SHELLCODE is at 0xff85a3a3
SHELLCODE is at 0xff8e03a3

Capisco che se il nome del programma viene modificato o vengono aggiunte nuove variabili d'ambiente, la posizione sarebbe leggermente diversa, ma perché la posizione varia così tanto?


Il getenvmanuale dice che restituisce un puntatore a una stringa contenente il valore della variabile. Tutto il resto non è specificato, quindi il kernel e / o il compilatore possono mantenere il valore dove vogliono, purché la promessa del puntatore rimanga vera. Immagino che la risposta esatta a questo possa essere una magia pesante e dipendere da vari dettagli di implementazione della mappatura della memoria e dalla fase della luna. (Non sono abbastanza mago da darti la risposta esatta.)
Anko,

"Capisco che se il nome del programma viene modificato o vengono aggiunte nuove variabili d'ambiente, la posizione sarebbe leggermente diversa, ma perché la posizione varia così tanto?" Questo è vero nella più semplice di tutte le implementazioni possibili, ma non è certamente necessario.
dmckee --- ex gattino moderatore

Risposte:


13

Quello che descrivi è una funzionalità anti-sfruttamento chiamata Randomization Layout dello spazio degli indirizzi (ASLR). Fondamentalmente, il kernel mette l'indirizzo molto in alto dello stack di chiamate di funzione di un programma a un indirizzo leggermente diverso ("casuale") ogni volta che il kernel carica il file ELF del programma dal disco. Gli indirizzi in argve le variabili di ambiente, di cui è uno il tuo shellcode, finiscono in un indirizzo variabile con ogni invocazione del programma.

L'ASLR dovrebbe rendere più difficile lo sfruttamento di buffer overflow e altre vulnerabilità legate allo stack. Lo sfruttatore deve scrivere codice o fare qualcosa per tenere conto degli indirizzi variabili di variabili e valori nello stack di chiamate delle funzioni.

Sembra che puoi disabilitare ASLR facendo qualcosa del tipo:

echo 0 > /proc/sys/kernel/randomize_va_space

come utente root. Poiché hai esplicitamente citato Ubuntu, il comando sopra è diverso:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

Sì, quello ha funzionato. Ho notato che l'autore del libro utilizza Ubuntu 10.04, che non aveva ancora ASLR.
Janman,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.