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 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 una función se llama por primera vez, su dirección real es resuelta por el enlazador 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.
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 enlazador 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 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 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 system).
Si system
no es utilizado por el binario, la función system 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
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 cuyas GOT podrían ser sobrescritas para obtener ejecución de código.
Encuentra más información sobre esta técnica aquí.
En las explotaciones 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")
.
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.
Una forma común de obtener RCE a partir de una vulnerabilidad en el 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í.
La protección 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:
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)