Basic Stack Binary Exploitation Methodology
Last updated
Last updated
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Antes de comenzar a explotar cualquier cosa, es interesante entender parte de la estructura de un binario ELF:
ELF Basic InformationCon tantas técnicas, es bueno tener un esquema de cuándo cada técnica será útil. Ten en cuenta que las mismas protecciones afectarán diferentes técnicas. Puedes encontrar formas de eludir las protecciones en cada sección de protección, pero no en esta metodología.
Hay diferentes formas en las que podrías terminar controlando el flujo de un programa:
Desbordamientos de Pila sobrescribiendo el puntero de retorno desde la pila o el EBP -> ESP -> EIP.
Podría ser necesario abusar de un Desbordamiento de Entero para causar el desbordamiento.
O a través de Escrituras Arbitrarias + Escribir Qué Dónde para Ejecución.
Cadenas de Formato: Abusar de printf
para escribir contenido arbitrario en direcciones arbitrarias.
Indexación de Arreglos: Abusar de una indexación mal diseñada para poder controlar algunos arreglos y obtener una escritura arbitraria.
Podría ser necesario abusar de un Desbordamiento de Entero para causar el desbordamiento.
bof a WWW a través de ROP: Abusar de un desbordamiento de búfer para construir un ROP y poder obtener un WWW.
Puedes encontrar las técnicas de Escribir Qué Dónde para Ejecución en:
Write What Where 2 ExecAlgo a tener en cuenta es que generalmente solo una explotación de una vulnerabilidad puede no ser suficiente para ejecutar un exploit exitoso, especialmente algunas protecciones necesitan ser eludidas. Por lo tanto, es interesante discutir algunas opciones para hacer que una sola vulnerabilidad sea explotable varias veces en la misma ejecución del binario:
Escribir en una cadena ROP la dirección de la función main
o la dirección donde está ocurriendo la vulnerabilidad.
Controlando una cadena ROP adecuada, podrías ser capaz de realizar todas las acciones en esa cadena.
Escribir en la dirección exit
en GOT (o cualquier otra función utilizada por el binario antes de finalizar) la dirección para volver a la vulnerabilidad.
Como se explicó en .fini_array, almacenar 2 funciones aquí, una para llamar a la vulnerabilidad nuevamente y otra para llamar a __libc_csu_fini
que volverá a llamar a la función de .fini_array
.
ret2win: Hay una función en el código que necesitas llamar (quizás con algunos parámetros específicos) para obtener la bandera.
En un bof con PIE, necesitarás eludirlo.
En un bof con canary, necesitarás eludirlo.
Si necesitas establecer varios parámetros para llamar correctamente a la función ret2win, puedes usar:
Una cadena ROP si hay suficientes gadgets para preparar todos los parámetros.
SROP (en caso de que puedas llamar a esta syscall) para controlar muchos registros.
A través de un Escribir Qué Dónde podrías abusar de otras vulnerabilidades (no bof) para llamar a la función win
.
Redireccionamiento de Punteros: En caso de que la pila contenga punteros a una función que se va a llamar o a una cadena que se va a usar por una función interesante (system o printf), es posible sobrescribir esa dirección.
Variables No Inicializadas: Nunca se sabe.
(Stack) Shellcode: Esto es útil para almacenar un shellcode en la pila antes o después de sobrescribir el puntero de retorno y luego saltar a él para ejecutarlo:
En cualquier caso, si hay un canary, en un bof regular necesitarás eludirlo (leak).
Con ASLR necesitarás técnicas como ret2esp/ret2reg para saltar a ella.
Esto mezclará shellcode con una cadena ROP.
Ret2syscall: Útil para llamar a execve
para ejecutar comandos arbitrarios. Necesitas ser capaz de encontrar los gadgets para llamar a la syscall específica con los parámetros.
SROP puede ser útil para preparar el ret2execve.
Ret2lib: Útil para llamar a una función de una biblioteca (generalmente de libc
) como system
con algunos argumentos preparados (por ejemplo, '/bin/sh'
). Necesitas que el binario cargue la biblioteca con la función que te gustaría llamar (libc generalmente).
Si compilado estáticamente y sin PIE, la dirección de system
y /bin/sh
no van a cambiar, por lo que es posible usarlas estáticamente.
Sin ASLR y conociendo la versión de libc cargada, la dirección de system
y /bin/sh
no van a cambiar, por lo que es posible usarlas estáticamente.
Usa ret2dlresolve
para resolver la dirección de system
y llamarla.
Eludir ASLR y calcular la dirección de system
y '/bin/sh'
en memoria.
Eludir PIE.
Encontrar la versión de libc
utilizada (filtrar un par de direcciones de funciones).
Revisar los escenarios anteriores con ASLR para continuar.
Pivotar la Pila / EBP2Ret / Encadenamiento de EBP: Controlar el ESP para controlar RET a través del EBP almacenado en la pila.
Útil para desbordamientos de pila off-by-one.
Útil como una forma alternativa de terminar controlando EIP mientras se abusa de EIP para construir la carga útil en memoria y luego saltar a ella a través de EBP.
Redireccionamiento de Punteros: En caso de que la pila contenga punteros a una función que se va a llamar o a una cadena que se va a usar por una función interesante (system o printf), es posible sobrescribir esa dirección.
Variables No Inicializadas: Nunca se sabe.
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)