WWW2Exec - GOT/PLT

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Basic Information

GOT: Global Offset Table

The Global Offset Table (GOT) is a mechanism used in dynamically linked binaries to manage the addresses of external functions. Since these addresses are not known until runtime (due to dynamic linking), the GOT provides a way to dynamically update the addresses of these external symbols once they are resolved.

Each entry in the GOT corresponds to a symbol in the external libraries that the binary may call. When a function is first called, its actual address is resolved by the dynamic linker and stored in the GOT. Subsequent calls to the same function use the address stored in the GOT, thus avoiding the overhead of resolving the address again.

PLT: Procedure Linkage Table

The Procedure Linkage Table (PLT) works closely with the GOT and serves as a trampoline to handle calls to external functions. When a binary calls an external function for the first time, control is passed to an entry in the PLT associated with that function. This PLT entry is responsible for invoking the dynamic linker to resolve the function's address if it has not already been resolved. After the address is resolved, it is stored in the GOT.

Therefore, GOT entries are used directly once the address of an external function or variable is resolved. PLT entries are used to facilitate the initial resolution of these addresses via the dynamic linker.

Get Execution

Check the GOT

Get the address to the GOT table with: objdump -s -j .got ./exec

Observe how after loading the executable in GEF you can see the functions that are in the GOT: gef➤ x/20x 0xDIR_GOT

Using GEF you can start a debugging session and execute got to see the got table:

GOT2Exec

In a binary the GOT has the addresses to the functions or to the PLT section that will load the function address. The goal of this arbitrary write is to override a GOT entry of a function that is going to be executed later with the address of the PLT of the system function for example.

Ideally, you will override the GOT of a function that is going to be called with parameters controlled by you (so you will be able to control the parameters sent to the system function).

If system isn't used by the script, the system function won't have an entry in the PLT. In this scenario, you will need to leak first the address of the system function and then overwrite the GOT to point to this address.

You can see the PLT addresses with objdump -j .plt -d ./vuln_binary

libc GOT entries

The GOT of libc is usually compiled with partial RELRO, making it a nice target for this supposing it's possible to figure out its address (ASLR).

Common functions of the libc are going to call other internal functions whose GOT could be overwritten in order to get code execution.

Find more information about this tachnique here.

One Gadget

Protections

The Full RELRO protection is meant to protect agains this kind of technique by resolving all the addresses of the functions when the binary is started and making the GOT table read only after it:

References

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Last updated