CODEGATE 2017 CTF EasyCrack 101
はじめに
101個のバイナリファイルのkeyを当てるだけ。
angr使って解いた。
チーメメンバがcurl使って自動送信するコードを書いてくれたので、途中からは、そのコードを使って分担してた。
そのコードは載せてない。
solve.py
keyはコマンドライン引数にて指定するので、コマンドライン引数を解析対象にするようにしている。
keyの長さは、最初適当に120とかにしていた。その後は解析結果を眺めながら、この程度が妥当だろうという長さに設定し直した。
import angr import claripy from pwn import * import sys for i in range(1, 102): fname = "prob"+str(i) binf = open(fname, 'rb').read() addr_main = u32(binf[0x5b0:0x5b4]) addr_succeeded = addr_main+0x50 addr_failed = addr_main+0x5c #key_length = 120 key_length = 50 p = angr.Project(fname) arg1 = claripy.BVS('arg1', key_length*8) com = "./" + fname initial_state = p.factory.entry_state(args=[com, arg1], add_options={"BYPASS_UNSUPPORTED_SYSCALL"}) for b in arg1.chop(key_length): initial_state.add_constraints(b != 0) pg = p.factory.path_group(initial_state, immutable=False) e = pg.explore(find=addr_succeeded, avoid=addr_failed) for path in pg.found: key = path.state.se.any_str(arg1) print fname, repr(key)
1ファイルあたり15秒程度で解析できていた。
ASCIIのprintableな文字がkeyなので、それを送信していた。
% python solve.py prob1 'T}gTRvNZAK_Exv^vqpDwCW\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' prob2 '}hGafk~acCtypkaEoi||f}tzsr\x00\x00\x00\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' prob3 'ELFT[^MYLINQMI_FQFYKOOZ^U\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' ...