更新日時で差をつけろ

もはや更新日時でしか差を付けられない

34C3 CTFに参加した

2017年最後のCTF, 34C3 CTFにHarekazeから参加しました。
結果として1問しか解けなかった、難しい〜〜
vimは惜しいところまで行ってたけど時間と賢さが足りなかった。

m0rph (rev easy)

49点。一番スコアが低い問題。
ある.tar.gzが渡されて、解凍するとx86-64なELFが出てくる。

Gyazo

せっかくなので使い始めたradare2で見てみる。画像はs mainからのVVのあと、後述するループの部分まで移動したところ。

まず.rodataの領域からヒープにコピーする。(PIEが有効なためセクションのアドレスはわからないのでbreak *0info filereadelf -Sでがんばる)
その後、コマンドライン引数として0x17サイズの文字列が渡されたときに中身の処理に移っている。(mainが初めにediをローカル変数として$ebp-0x24に保存している。これはmainの第1引数argcのこと。また、rsiも同様に第2引数argvへのポインタを保存している)

そのあと0x17回ループを行い、うまくループが終わればWhat are you waiting for, go submit that flag!と表示される。
とりあえず適当に$ ./morph 34C3_hogehogeと渡すと何も言わずexitしてしまう。call raxあたりでexitに飛んでしまうのだろう。

画像の上の四角でローカル変数に値を取り出している。
が、これだけだと何がしたいのかよくわからないので0x00202020の中身を表示してみる(表示してみればよい、というそれだけのことに気づかず無限に時間溶けた)。
これとコード(とセクションのアドレス)を照らし合わせるとなんとなくわかったような、わからんような…

gdb-peda$ x/128gx 0x555555757260
0x555555757260: 0x0000555555757330  0x0000555555757350
0x555555757270: 0x00005555557574f0  0x00005555557575f0
0x555555757280: 0x00005555557573d0  0x00005555557575b0
0x555555757290: 0x0000555555757530  0x00005555557574d0
0x5555557572a0: 0x0000555555757490  0x0000555555757410
0x5555557572b0: 0x0000555555757570  0x00005555557575d0
0x5555557572c0: 0x0000555555757510  0x00005555557573b0
0x5555557572d0: 0x0000555555757550  0x0000555555757590
0x5555557572e0: 0x0000555555757450  0x0000555555757430
0x5555557572f0: 0x0000555555757370  0x0000555555757470
0x555555757300: 0x00005555557573f0  0x00005555557574b0
0x555555757310: 0x0000555555757390  0x0000000000000000
0x555555757320: 0x0000000000000000  0x0000000000000021
0x555555757330: 0x00007ffff7ff3000  0x0000000000000000
0x555555757340: 0x0000000000000000  0x0000000000000021
0x555555757350: 0x00007ffff7ff3011  0x0000000000000111
0x555555757360: 0x0000000000000000  0x0000000000000021
0x555555757370: 0x00007ffff7ff3022  0x0000000000000222
0x555555757380: 0x0000000000000000  0x0000000000000021
0x555555757390: 0x00007ffff7ff3033  0x0000000000000333
0x5555557573a0: 0x0000000000000000  0x0000000000000021
0x5555557573b0: 0x00007ffff7ff3044  0x0000000000000444
0x5555557573c0: 0x0000000000000000  0x0000000000000021
0x5555557573d0: 0x00007ffff7ff3055  0x0000000000000555
0x5555557573e0: 0x0000000000000000  0x0000000000000021
0x5555557573f0: 0x00007ffff7ff3066  0x0000000000000666
0x555555757400: 0x0000000000000000  0x0000000000000021
0x555555757410: 0x00007ffff7ff3077  0x0000000000000777
0x555555757420: 0x0000000000000000  0x0000000000000021
〜〜〜省略〜〜〜
0x555555757630: 0x0000000000000000  0x0000000000000000
0x555555757640: 0x0000000000000000  0x0000000000000000
0x555555757650: 0x0000000000000000  0x0000000000000000

まあいいやということで下の2つの四角も読んでいく。
$ebp-0x10が指す値の9バイト先を読んだりcall raxしたりしてる。なんか中途半端だしややこしい。
とりあえずexitさせたくないので0xb950xbc6ブレークポイントを張って何が行われているか見ることにした。
Gyazo

0x33、つまり'3'と比較してjmpしているようだ。フラグは34C3_から始まるので、次は'4'と比較するのかな?

と思ったが違った。'_'だ。引数チェックをした後にsrandが呼ばれていたのでランダムに比較しているみたい。
引数のどこと比較しているかは第1引数に書いてある(この場合はA)。
Gyazo

何度か繰り返すと他の文字も出てきた。
いずれフラグのすべての文字と比較することになるので、ここからフラグが導き出せるのでは?
34C3_AAAAAAAAAAAAAAAAAAだとどこと比較しているかわかりづらいので、34C3_abcdefghijklmnopqrと変えてrunした。

FLAG: 34C3_M1GHTY_M0RPh1nG_g0

「もちろん俺らはsolveするで?」
「どうやってsolveすんねん」
「(cキーに踏み込み)拳で」※実際は指

書いたら簡単だけどすごく時間かかった。遠回りした。