Desbordamiento de búfer basado en pila en R 3.4.4. Explotación completa en x86, pero solo control de RIP con análisis de gadgets en x64 debido a restricciones del programa. La misma vulnerabilidad en dos arquitecturas, lo que lleva a diferentes rutas de explotación.
Desbordamiento de búfer basado en pila en R 3.4.4. Explotación completa en x86, pero solo control de RIP con análisis de gadgets en x64 debido a restricciones del programa. La misma vulnerabilidad en dos arquitecturas, lo que conduce a diferentes rutas de explotación.
Este repositorio es parte del material que utilizo cuando enseño explotación de corrupción de memoria (además de mi trabajo habitual, también enseño en diferentes cursos de ciberseguridad donde ayudo a formar a la próxima generación de ingenieros inversos).
CVE-2019-25485 es el caso que uso cuando quiero que los estudiantes trabajen con la misma vulnerabilidad en dos arquitecturas diferentes y vean de primera mano qué cambia entre ellas. R 3.4.4 se distribuye tanto en versiones x86 como x64, y el mismo desbordamiento exacto existe en ambas, el mismo campo GUI, el mismo manejador de entrada, el mismo fallo. Ambos están documentados y explotados aquí como ejercicios separados:
R 3.4.4 es una aplicación de computación estadística, no un servicio de red o un navegador. El desbordamiento se desencadena a través de un campo GUI de escritorio, lo que significa que la superficie de ataque es completamente diferente de cualquier otro caso que enseño. Lo que hace que este caso sea útil para la enseñanza:
R es un entorno de computación estadística y gráficos disponible para Windows, macOS y Linux. La vulnerabilidad está en el diálogo de Preferencias GUI, específicamente en el campo Idioma para menús y mensajes, que copia la entrada del usuario en un búfer de pila de tamaño fijo sin validar su longitud.
Detalles técnicos clave:
R 3.4.4 procesa el campo Idioma para menús y mensajes copiando la cadena suministrada en un búfer de pila de tamaño fijo sin verificar su longitud. Una versión simplificada de la lógica vulnerable se ve así:
char language_buffer[256];
strcpy(language_buffer, user_input);
Enviar una cadena suficientemente larga hace que la copia escriba más allá del final del búfer, corrompiendo la pila hasta que la dirección de retorno guardada se sobrescribe. Cuando la función retorna, la CPU carga el valor controlado por el atacante desde la pila en RIP e intenta saltar a él.
En x64, Windows impone la validación de direcciones canónicas antes de que se realice cualquier salto. Un valor no canónico como 0x4141414141414141 desencadena una violación de acceso inmediata antes de que se cargue RIP, lo que significa que el fallo se ve diferente de x86, sin un RIP limpio = 4141414141414141. El offset debe encontrarse leyendo el patrón cíclico de la pila después del fallo en lugar de directamente desde RIP.
El fallo se puede reproducir pegando una cadena larga en el campo de idioma. No se requiere autenticación. Ejemplo usando Python para generar la carga útil:
import struct
payload = b'A' * 400
with open('payload.txt', 'wb') as f:
f.write(payload)
Abrir R 3.4.4 x64
Editar -> Preferencias GUI
Pegar el contenido de payload.txt en Idioma para menús y mensajes
Hacer clic en Aceptar
El objetivo de este repositorio no es solo demostrar el fallo, sino recorrer el proceso completo de explotación en ambas arquitecturas, documentando qué funciona en x86, qué falla en x64 y, más importante, por qué.
Para mantener el README principal limpio, las notas detalladas de explotación, scripts y pasos del depurador se colocan dentro de la carpeta Vulnerability 📂 de este repositorio, organizados en subcarpetas separadas para x86 y x64.
Allí encontrarás el flujo de trabajo completo para ambas arquitecturas:
x86 - Explotación completa:
x64 - Control de RIP y análisis de explotación: