WWW2Exec - GOT/PLT
Reading time: 6 minutes
tip
Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a HackTricks y HackTricks Cloud repos de github.
Información Básica
GOT: Tabla de Desplazamiento Global
La Tabla de Desplazamiento Global (GOT) es un mecanismo utilizado en binarios vinculados dinámicamente para gestionar las direcciones de funciones externas. Dado que estas direcciones no se conocen hasta el tiempo de ejecución (debido al enlace dinámico), la GOT proporciona una forma de actualizar dinámicamente las direcciones de estos símbolos externos una vez que se resuelven.
Cada entrada en la GOT corresponde a un símbolo en las bibliotecas externas que el binario puede llamar. Cuando se llama a una función por primera vez, su dirección real es resuelta por el vinculador dinámico y almacenada en la GOT. Las llamadas posteriores a la misma función utilizan la dirección almacenada en la GOT, evitando así el costo de resolver la dirección nuevamente.
PLT: Tabla de Enlace de Procedimientos
La Tabla de Enlace de Procedimientos (PLT) trabaja en estrecha colaboración con la GOT y sirve como un trampolín para manejar llamadas a funciones externas. Cuando un binario llama a una función externa por primera vez, el control se pasa a una entrada en la PLT asociada con esa función. Esta entrada de la PLT es responsable de invocar al vinculador dinámico para resolver la dirección de la función si aún no se ha resuelto. Después de que se resuelve la dirección, se almacena en la GOT.
Por lo tanto, las entradas de la GOT se utilizan directamente una vez que se resuelve la dirección de una función o variable externa. Las entradas de la PLT se utilizan para facilitar la resolución inicial de estas direcciones a través del vinculador dinámico.
Obtener Ejecución
Verificar la GOT
Obtén la dirección de la tabla GOT con: objdump -s -j .got ./exec
Observa cómo después de cargar el ejecutable en GEF puedes ver las funciones que están en la GOT: gef➤ x/20x 0xADDR_GOT
Usando GEF puedes iniciar una sesión de depuración y ejecutar got
para ver la tabla got:
GOT2Exec
En un binario, la GOT tiene las direcciones a las funciones o a la sección PLT que cargará la dirección de la función. El objetivo de esta escritura arbitraria es sobrescribir una entrada de la GOT de una función que se va a ejecutar más tarde con la dirección de la PLT de la función system
por ejemplo.
Idealmente, deberías sobrescribir la GOT de una función que va a ser llamada con parámetros controlados por ti (así podrás controlar los parámetros enviados a la función del sistema).
Si system
no es utilizado por el binario, la función del sistema no tendrá una entrada en la PLT. En este escenario, necesitarás filtrar primero la dirección de la función system
y luego sobrescribir la GOT para apuntar a esta dirección.
Puedes ver las direcciones de la PLT con objdump -j .plt -d ./vuln_binary
Entradas de la GOT de libc
La GOT de libc generalmente se compila con RELRO parcial, lo que la convierte en un buen objetivo para esto suponiendo que sea posible averiguar su dirección (ASLR).
Las funciones comunes de la libc van a llamar a otras funciones internas cuya GOT podría ser sobrescrita para obtener ejecución de código.
Encuentra más información sobre esta técnica aquí.
Free2system
En la explotación de heap en CTFs es común poder controlar el contenido de los chunks y en algún momento incluso sobrescribir la tabla GOT. Un truco simple para obtener RCE si no hay gadgets disponibles es sobrescribir la dirección GOT de free
para apuntar a system
y escribir dentro de un chunk "/bin/sh"
. De esta manera, cuando este chunk se libera, ejecutará system("/bin/sh")
.
Strlen2system
Otra técnica común es sobrescribir la dirección GOT de strlen
para apuntar a system
, así si esta función es llamada con entrada del usuario es posible pasar la cadena "/bin/sh"
y obtener un shell.
Además, si puts
se utiliza con entrada del usuario, es posible sobrescribir la dirección GOT de strlen
para apuntar a system
y pasar la cadena "/bin/sh"
para obtener un shell porque puts
llamará a strlen
con la entrada del usuario.
One Gadget
Abusando de la GOT desde Heap
Una forma común de obtener RCE a partir de una vulnerabilidad de heap es abusar de un fastbin para que sea posible agregar la parte de la tabla GOT en el fast bin, de modo que cada vez que ese chunk se asigne será posible sobrescribir el puntero de una función, generalmente free
.
Luego, apuntando free
a system
y liberando un chunk donde se escribió /bin/sh\x00
se ejecutará un shell.
Es posible encontrar un ejemplo aquí.
Protecciones
La protección de Full RELRO está destinada a proteger contra este tipo de técnica resolviendo todas las direcciones de las funciones cuando se inicia el binario y haciendo que la tabla GOT sea de solo lectura después de eso:
Referencias
- https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite
- https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook
tip
Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a HackTricks y HackTricks Cloud repos de github.