WWW2Exec - GOT/PLT
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)
La Tabla de Desplazamiento Global (GOT) es un mecanismo utilizado en binarios enlazados dinámicamente para gestionar las direcciones de funciones externas. Dado que estas direcciones no se conocen hasta 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 enlazador dinámico y almacenada en la GOT. 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.
La Tabla de Enlace de Procedimientos (PLT) trabaja estrechamente 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 enlazador dinámico para resolver la dirección de la función si aún no ha sido resuelta. Después de que la dirección es resuelta, 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 enlazador dinámico.
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:
En un binario, la GOT tiene las direcciones de las funciones o de 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 ejecutará más tarde con la dirección de la PLT de la función system
por ejemplo.
Idealmente, sobrescribirás la GOT de una función que 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, deberá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
La GOT de libc generalmente se compila con RELRO parcial, convirtiéndola en un buen objetivo suponiendo que sea posible averiguar su dirección (ASLR).
Las funciones comunes de 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í.
En CTFs de explotación de montón, es común poder controlar el contenido de los fragmentos y en algún momento incluso sobrescribir la tabla GOT. Un truco simple para obtener RCE si no se dispone de gadgets es sobrescribir la dirección GOT de free
para apuntar a system
y escribir dentro de un fragmento "/bin/sh"
. De esta manera, cuando se libere este fragmento, ejecutará system("/bin/sh")
.
Otra técnica común es sobrescribir la dirección strlen
GOT para apuntar a system
, por lo que si esta función es llamada con entrada de usuario es posible pasar la cadena "/bin/sh"
y obtener una shell.
Además, si puts
se utiliza con entrada de usuario, es posible sobrescribir la dirección GOT de strlen
para apuntar a system
y pasar la cadena "/bin/sh"
para obtener una shell porque puts
llamará a strlen
con la entrada de usuario.
Una forma común de obtener RCE desde una vulnerabilidad de montón es abusar de un fastbin para poder agregar la parte de la tabla GOT en el fast bin, por lo que cada vez que se asigne ese fragmento será posible sobrescribir el puntero de una función, generalmente free
.
Luego, apuntando free
a system
y liberando un fragmento donde se haya escrito /bin/sh\x00
ejecutará una shell.
Es posible encontrar un ejemplo aquí.
La protección Full RELRO está diseñada para protegerse contra este tipo de técnica al resolver todas las direcciones de las funciones cuando se inicia el binario y hacer que la tabla GOT sea de solo lectura después de eso:
RelroAprende 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)