Basic Stack Binary Exploitation Methodology
Last updated
Last updated
Learn & practice AWS Hacking: Learn & practice GCP Hacking:
Before start exploiting anything it's interesting to understand part of the structure of an ELF binary:
With so many techniques it's good to have a scheme when each technique will be useful. Note that the same protections will affect different techniques. You can find ways to bypass the protections on each protection section but not in this methodology.
There are different was you could end controlling the flow of a program:
Or via Arbitrary Writes + Write What Where to Execution
bof to WWW via ROP: Abuse a buffer overflow to construct a ROP and be able to get a WWW.
You can find the Write What Where to Execution techniques in:
Something to take into account is that usually just one exploitation of a vulnerability might not be enough to execute a successful exploit, specially some protections need to be bypassed. Therefore, it's interesting discuss some options to make a single vulnerability exploitable several times in the same execution of the binary:
Write in a ROP chain the address of the main
function or to the address where the vulnerability is occurring.
Controlling a proper ROP chain you might be able to perform all the actions in that chain
Write in the exit
address in GOT (or any other function used by the binary before ending) the address to go back to the vulnerability
If you need to set several parameter to correctly call the ret2win function you can use:
This will mix shellcode with a ROP chain.
Find the libc
version used (leak a couple of function addresses)
Check the previous scenarios with ASLR to continue.
Useful for off-by-one stack overflows
Useful as an alternate way to end controlling EIP while abusing EIP to construct the payload in memory and then jumping to it via EBP
overwriting the return pointer from the stack or the EBP -> ESP -> EIP.
Might need to abuse an to cause the overflow
: Abuse printf
to write arbitrary content in arbitrary addresses.
: Abuse a poorly designed indexing to be able to control some arrays and get an arbitrary write.
Might need to abuse an to cause the overflow
As explained in , store 2 functions here, one to call the vuln again and another to call**__libc_csu_fini
** which will call again the function from .fini_array
.
: There is a function in the code you need to call (maybe with some specific params) in order to get the flag.
In a regular bof without and you just need to write the address in the return address stored in the stack.
In a bof with , you will need to bypass it
In a bof with , you will need to bypass it
A chain if there are enough gadgets to prepare all the params
(in case you can call this syscall) to control a lot of registers
Gadgets from and to control several registers
Via a you could abuse other vulns (not bof) to call the win
function.
: In case the stack contains pointers to a function that is going to be called or to a string that is going to be used by an interesting function (system or printf), it's possible to overwrite that address.
or might affect the addresses.
: You never know.
: This is useful to store a shellcode in the stack before of after overwriting the return pointer and then jump to it to execute it:
In any case, if there is a , in a regular bof you will need to bypass (leak) it
Without and it's possible to jump to the address of the stack as it won't never change
With you will need techniques such as to jump to it
With , you will need to use some to call memprotect
and make some page rwx
, in order to then store the shellcode in there (calling read for example) and then jump there.
: Useful to call execve
to run arbitrary commands. You need to be able to find the gadgets to call the specific syscall with the parameters.
If or are enabled you'll need to defeat them in order to use ROP gadgets from the binary or libraries.
can be useful to prepare the ret2execve
Gadgets from and to control several registers
: Useful to call a function from a library (usually from libc
) like system
with some prepared arguments (e.g. '/bin/sh'
). You need the binary to load the library with the function you would like to call (libc usually).
If statically compiled and no , the address of system
and /bin/sh
are not going to change, so it's possible to use them statically.
Without and knowing the libc version loaded, the address of system
and /bin/sh
are not going to change, so it's possible to use them statically.
With but no , knowing the libc and with the binary using the system
function it's possible to ret
to the address of system in the GOT with the address of '/bin/sh'
in the param (you will need to figure this out).
With but no , knowing the libc and without the binary using the system
:
Use to resolve the address of system
and call it
Bypass and calculate the address of system
and '/bin/sh'
in memory.
With and and not knowing the libc: You need to:
Bypass
: Control the ESP to control RET through the stored EBP in the stack.
: In case the stack contains pointers to a function that is going to be called or to a string that is going to be used by an interesting function (system or printf), it's possible to overwrite that address.
or might affect the addresses.
: You never know
Learn & practice AWS Hacking: Learn & practice GCP Hacking:
Check the !
Join the 💬 or the or follow us on Twitter 🐦 .
Share hacking tricks by submitting PRs to the and github repos.