Note that **`checksec`** might not find that a binary is protected by a canary if this was statically compiled and it's not capable to identify the function.\
However, you can manually notice this if you find that a value is saved in the stack at the begging of a function call and this value is checked before exiting.
The best way to bypass a simple canary is if the binary is a program **forking child processes every time you establish a new connection** with it (network service), because every time you connect to it **the same canary will be used**.
Then, the best way to bypass the canary is just to** brute-force it char by char**, and you can figure out if the guessed canary byte was correct checking if the program has crashed or continues its regular flow. In this example the function **brute-forces an 8 Bytes canary (x64) **and distinguish between a correct guessed byte and a bad byte just **checking **if a **response **is sent back by the server (another way in **other situation **could be using a **try/except**):
Imagine a situation where a **program vulnerable **to stack overflow can execute a **puts** function **pointing **to **part **of the **stack overflow**. The attacker knows that the** first byte of the canary is a null byte** (`\x00`) and the rest of the canary are **random **bytes. Then, the attacker may create an overflow that **overwrites the stack until just the first byte of the canary**.\
Then, the attacker** calls the puts functionalit**y on the middle of the payload which will **print all the canary** (except from the first null byte).\
Obviously, this tactic is very **restricted **as the attacker needs to be able to **print **the **content **of his **payload **to **exfiltrate **the **canary **and then be able to create a new payload (in the **same program session**) and **send **the **real buffer overflow**.\
In order to bypass the PIE you need to **leak some address**. And if the binary is not leaking any addresses the best to do it is to **brute-force the RBP and RIP saved in the stack** in the vulnerable function.\
For example, if a binary is protected using both a **canary **and **PIE**, you can start brute-forcing the canary, then the **next **8 Bytes (x64) will be the saved **RBP **and the **next **8 Bytes will be the saved **RIP.**
To brute-force the RBP and the RIP from the binary you can figure out that a valid guessed byte is correct if the program output something or it just doesn't crash. The **same function** as the provided for brute-forcing the canary can be used to brute-force the RBP and the RIP:
From the **RBP **you can calculate **where are you writing your shell in the stack**. This can be very useful to know where are you going to write the string _"/bin/sh\x00" _inside the stack. To calculate the distance between the leaked RBP and your shellcode you can just put a **breakpoint after leaking the RBP **an check **where is your shellcode located**, then, you can calculate the distance between the shellcode and the RBP:
In that example you can see that only **1 Byte and a half is needed **to locate all the code, then, the base address in this situation will be the **leaked RIP but finishing on "000"**. For example if you leaked _0x562002970**ecf** _the base address is _0x562002970**000**_