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**\):
Another way to bypass the canary is to **print it**.
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\).
With this info the attacker can **craft and send a new attack** knowing the canary \(in the same program session\)
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:
The last thing you need to defeat the PIE is to calculate **useful addresses from the leaked** addresses: 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:
```python
INI_SHELLCODE = RBP - 1152
```
From the **RIP** you can calculate the **base address of the PIE binary** which is what you are going to need to create a **valid ROP chain**.
To calculate the base address just do `objdump -d vunbinary` and check the disassemble latest addresses:
![](../../.gitbook/assets/image%20%2818%29.png)
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**_