ASLR
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Address Space Layout Randomization (ASLR) es una técnica de seguridad utilizada en sistemas operativos para aleatorizar las direcciones de memoria utilizadas por los procesos del sistema y de la aplicación. Al hacerlo, se dificulta significativamente que un atacante prediga la ubicación de procesos y datos específicos, como la pila, el montón y las bibliotecas, mitigando así ciertos tipos de exploits, particularmente desbordamientos de búfer.
Para verificar el estado de ASLR en un sistema Linux, puedes leer el valor del archivo /proc/sys/kernel/randomize_va_space
. El valor almacenado en este archivo determina el tipo de ASLR que se está aplicando:
0: Sin aleatorización. Todo es estático.
1: Aleatorización conservadora. Las bibliotecas compartidas, la pila, mmap(), la página VDSO están aleatorizadas.
2: Aleatorización completa. Además de los elementos aleatorizados por la aleatorización conservadora, la memoria gestionada a través de brk()
está aleatorizada.
Puedes verificar el estado de ASLR con el siguiente comando:
Para deshabilitar ASLR, debes establecer el valor de /proc/sys/kernel/randomize_va_space
en 0. Deshabilitar ASLR generalmente no se recomienda fuera de escenarios de prueba o depuración. Aquí te mostramos cómo puedes deshabilitarlo:
Puedes desactivar ASLR para una ejecución con:
Para habilitar ASLR, puedes escribir un valor de 2 en el archivo /proc/sys/kernel/randomize_va_space
. Esto generalmente requiere privilegios de root. Habilitar la aleatorización completa se puede hacer con el siguiente comando:
Los cambios realizados con los comandos echo
son temporales y se restablecerán al reiniciar. Para hacer que el cambio sea persistente, necesitas editar el archivo /etc/sysctl.conf
y agregar o modificar la siguiente línea:
Después de editar /etc/sysctl.conf
, aplica los cambios con:
Esto asegurará que la configuración de ASLR se mantenga a través de reinicios.
PaX divide el espacio de direcciones del proceso en 3 grupos:
Código y datos (inicializados y no inicializados): .text
, .data
y .bss
—> 16 bits de entropía en la variable delta_exec
. Esta variable se inicializa aleatoriamente con cada proceso y se suma a las direcciones iniciales.
Memoria asignada por mmap()
y bibliotecas compartidas —> 16 bits, llamada delta_mmap
.
La pila —> 24 bits, referida como delta_stack
. Sin embargo, utiliza efectivamente 11 bits (del 10º al 20º byte inclusive), alineados a 16 bytes —> Esto resulta en 524,288 posibles direcciones de pila reales.
Los datos anteriores son para sistemas de 32 bits y la entropía final reducida hace posible eludir ASLR al reintentar la ejecución una y otra vez hasta que el exploit se complete con éxito.
Si tienes un desbordamiento lo suficientemente grande para alojar un gran NOP sled antes del shellcode, podrías simplemente forzar direcciones en la pila hasta que el flujo salte sobre alguna parte del NOP sled.
Otra opción para esto en caso de que el desbordamiento no sea tan grande y el exploit se pueda ejecutar localmente es posible agregar el NOP sled y el shellcode en una variable de entorno.
Si el exploit es local, puedes intentar forzar la dirección base de libc (útil para sistemas de 32 bits):
Si atacas un servidor remoto, podrías intentar forzar la dirección de la función usleep
de libc
, pasando como argumento 10 (por ejemplo). Si en algún momento el servidor tarda 10s extra en responder, encontraste la dirección de esta función.
En sistemas de 64 bits, la entropía es mucho mayor y esto no debería ser posible.
Es posible ocupar una gran parte de la pila con variables de entorno y luego intentar abusar del binario cientos/miles de veces localmente para explotarlo. El siguiente código muestra cómo es posible simplemente seleccionar una dirección en la pila y cada pocas centenas de ejecuciones esa dirección contendrá la instrucción NOP:
/proc/[pid]/stat
)El archivo /proc/[pid]/stat
de un proceso siempre es legible por todos y contiene información interesante como:
startcode & endcode: Direcciones por encima y por debajo del TEXT del binario
startstack: La dirección del inicio de la pila
start_data & end_data: Direcciones por encima y por debajo donde está el BSS
kstkesp & kstkeip: Direcciones actuales de ESP y EIP
arg_start & arg_end: Direcciones por encima y por debajo donde están los argumentos cli.
env_start &env_end: Direcciones por encima y por debajo donde están las variables de entorno.
Por lo tanto, si el atacante está en la misma computadora que el binario que se está explotando y este binario no espera el desbordamiento de argumentos en bruto, sino de una entrada diferente que se puede crear después de leer este archivo. Es posible que un atacante obtenga algunas direcciones de este archivo y construya offsets a partir de ellas para la explotación.
Para más información sobre este archivo, consulta https://man7.org/linux/man-pages/man5/proc.5.html buscando /proc/pid/stat
El desafío es dar un leak
Si se te da un leak (desafíos CTF fáciles), puedes calcular offsets a partir de él (suponiendo, por ejemplo, que conoces la versión exacta de libc que se utiliza en el sistema que estás explotando). Este ejemplo de explotación se extrae de ejemplo de aquí (consulta esa página para más detalles):
ret2plt
Abusando de un desbordamiento de búfer, sería posible explotar un ret2plt para exfiltrar una dirección de una función de la libc. Ver:
Ret2pltFormat Strings Lectura Arbitraria
Al igual que en ret2plt, si tienes una lectura arbitraria a través de una vulnerabilidad de cadenas de formato, es posible exfiltrar la dirección de una función de libc desde el GOT. El siguiente ejemplo es de aquí:
Puedes encontrar más información sobre la lectura arbitraria de cadenas de formato en:
Format StringsIntenta eludir ASLR abusando de direcciones dentro de la pila:
Ret2ret & Reo2popEl mecanismo vsyscall
sirve para mejorar el rendimiento al permitir que ciertas llamadas al sistema se ejecuten en el espacio de usuario, aunque son fundamentalmente parte del núcleo. La ventaja crítica de vsyscalls radica en sus direcciones fijas, que no están sujetas a ASLR (Aleatorización del Diseño del Espacio de Direcciones). Esta naturaleza fija significa que los atacantes no requieren una vulnerabilidad de fuga de información para determinar sus direcciones y usarlas en un exploit.
Sin embargo, no se encontrarán gadgets super interesantes aquí (aunque, por ejemplo, es posible obtener un equivalente a ret;
)
(El siguiente ejemplo y código es de este informe)
Por ejemplo, un atacante podría usar la dirección 0xffffffffff600800
dentro de un exploit. Mientras que intentar saltar directamente a una instrucción ret
podría llevar a inestabilidad o bloqueos después de ejecutar un par de gadgets, saltar al inicio de una syscall
proporcionada por la sección vsyscall puede resultar exitoso. Al colocar cuidadosamente un gadget ROP que dirija la ejecución a esta dirección vsyscall, un atacante puede lograr la ejecución de código sin necesidad de eludir ASLR para esta parte del exploit.
Note cómo podría ser posible eludir ASLR abusando del vdso si el kernel está compilado con CONFIG_COMPAT_VDSO, ya que la dirección del vdso no será aleatorizada. Para más información, consulta:
Ret2vDSOLearn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)