= Cheer of CPU (binary 300) = Swiftで書かれたバイナリであり、最初はMacOS上でも動作しなかった。 エラーメッセージを見るとXCode6がないとライブラリ不足で動作しないようなので、インストールしたがやはり起動せず。 エラーメッセージで検索すると、Yosemiteなら動くという話があったので、Yosemiteにアップグレードしたら動くようになった。 次に逆アセンブルを試みた。Mach-Oなのでmetasmやobjdump(on linux)で出来るかと思いきや、どちらも失敗し、最終的にMac上のgobjdumpで逆アセンブルすることが出来た。関数名が`__TF Ss7printlnU__FQ_T_$stub`のように分かりにくいため、以下のプログラムを用いてdemangleを行なった。 {{{#!highlight ruby # need root require 'shellwords' hash = {} puts $<.read.gsub(/<(.+?)>/){ f = $1 next '<%s>' % hash[f] if hash[f] if f.end_with?('stub') '<' + `xcrun swift-demangle #{Shellwords.escape(f[0..-6])}`.split('-->', 2)[1].strip + '>' else '<%s>' % f end } }}} 逆アセンブルを読むと、引数が2個より少なかった時の処理でメッセージを表示した後、exitを呼び出していることから、パスワードを間違えた時もexit(1)を呼び出してると推測した。 `lldb`を用いてexitにブレークポイントを仕掛けて実行することにした。 まず、引数に`a`を与えて実行した所、0x10001f73bでexitが呼び出された。直前の分岐にブレークポイントを貼って、rax, rsiの値の変化を確かめて、引数の長さが6かどうか判定している処理であることを特定した。 {{{ 10001f6ec: 48 39 f0 cmp rax,rsi 10001f6ef: 74 4f je 10001f740 <__mh_execute_header+0x1f740> (なんらかの処理) 10001f739: 89 c7 mov edi,eax 10001f73b: e8 60 25 00 00 call 100021ca0 <_exit> }}} 次に、引数に`abcdef`を与えて実行したところ、0x10001fbc0でexitが呼び出された。直前の分岐にブレークポイントを仕掛けた所、引数の文字と別の文字を比較している処理だということが分かったので、引数を1文字ずつ確定させていくことが出来た。 {{{ 10001fb71: 45 38 c8 cmp r8b,r9b 10001fb74: 74 4f je 10001fbc5 <__mh_execute_header+0x1fbc5> (なんらかの処理) 10001fbc0: e8 db 20 00 00 call 100021ca0 <_exit> # exit(-1) }}} 出力結果をSHA256して、フラグを取得した。 {{{ $ ruby -rdigest/sha2 -e 'puts Digest::SHA256.hexdigest(`./cheer kogasa`.strip).downcase' }}}