¿Por qué la ubicación de las variables de entorno varía tanto?

9

Leyendo el libro Hacking: The Art of Exploitation de Jon Erickson, estoy tratando de aproximar la dirección de una variable de entorno SHELLCODEpara explotar un programa.

Cada vez que corro getenv("SHELLCODE");para obtener la ubicación, el resultado es completamente diferente.

Extracto de mi caparazón:

> 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

Entiendo que si se modifica el nombre del programa o se agregan nuevas variables de entorno, la posición sería ligeramente diferente, pero ¿por qué la ubicación varía tanto?

Janman
fuente
El getenvmanual dice que devuelve un puntero a una cadena que contiene el valor de la variable. Todo lo demás no está especificado, por lo que su kernel y / o compilador puede pegar el valor donde lo deseen, siempre que esa promesa de puntero se mantenga fiel. Supongo que la respuesta exacta a esto puede ser una gran magia y depender de varios detalles de implementación de mapeo de memoria y la fase de la luna. (No soy lo suficientemente mago como para darte la respuesta exacta.)
Anko el
"Entiendo que si se modifica el nombre del programa o se agregan nuevas variables de entorno, la posición sería ligeramente diferente, pero ¿por qué la ubicación varía tanto?" Eso es cierto en la más simple de todas las implementaciones posibles, pero ciertamente no es obligatorio.
dmckee --- ex-gatito moderador

Respuestas:

13

Lo que usted describe es una característica anti-explotación llamada Aleatorización del diseño del espacio de direcciones (ASLR). Básicamente, el kernel coloca la dirección superior de la pila de llamadas de función de un programa en una dirección ligeramente diferente ("aleatoria") cada vez que el kernel carga el archivo ELF del programa desde el disco. Las direcciones argvy las variables de entorno, de las cuales su shellcode es uno, terminan en una dirección variable con cada invocación del programa.

Se supone que ASLR dificultará la explotación de desbordamientos de búfer y otras vulnerabilidades relacionadas con la pila. El explotador tiene que escribir código o hacer algo para dar cuenta de las diferentes direcciones de variables y valores en la pila de llamadas de función.

Parece que puede deshabilitar ASLR haciendo algo como:

echo 0 > /proc/sys/kernel/randomize_va_space

como usuario root Como explícitamente cita a Ubuntu, el comando anterior es diferente:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Bruce Ediger
fuente
Sí, eso hizo el truco. Me di cuenta de que el autor del libro usa Ubuntu 10.04, que aún no tenía ASLR.
Janman