読者です 読者をやめる 読者になる 読者になる

ブログ未満のなにか

ブログなのか誰にも分からない

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'
...