久しぶりにWriteupを書いてみる

卒論も無事終わって久しぶりに問題解いたのでWriteup書いていく
問題はNuit du Hack CTF Quals 2016のMatriochka - Step 2です

Matriochka - Step 2

stage2.binというファイルが手に入るのでfileコマンドでみてみるとELFだったのでとりあえず実行してみる

$ ./stage2.bin

Usage: ./stage2.bin <pass>

引数を渡さないといけないらしい

てきとうな引数を渡してみる

$ ./stage2.bin abcd

Try again...

たぶん引数がflagになる感じ

次は最近勉強しているradare2で解析してみる
ざっくり全体見てみるとやっぱり引数がflagになるらしい

細かく見ていく

f:id:hntsu:20180123183736p:plain:h300

ここらへんを見ると最初に引数の文字数の判定をしている
文字数にいくつかの処理をした後の数が0x1f8と等しければいいらしい
フラグの文字数はそんなに多くないだろうと思うので30文字以内で求めてみる

30.times do |n|
  rax = n
  rdx = rax + 1
  rax = rdx
  rax = rax << 2
  rax += rdx
  rax = rax << 2
  rax += rdx
  rax += rax
  puts n if rax == 0x1f8
end  

>> 11

flagは11文字なのが分かった

少し進むといくつかの条件式があるのがわかる
見てみるとflagの1文字に対していくつかの処理をした後に比較している

f:id:hntsu:20180127171654p:plain
[local_30h]に0x8を足したアドレスがflagの先頭になる
つまりここではflag[0] == 0x50
こんな感じで続きもやっていく

f:id:hntsu:20180127171657p:plain

2flag[3] = 0xc8

f:id:hntsu:20180127171700p:plain

flag[6] == flag[0] + 0x20

f:id:hntsu:20180127171703p:plain

rax = flag.size << 3
rax = rax + flag.size
rax -= 4
flag[5] == rax

f:id:hntsu:20180127171706p:plain

flag[1] == flag[7]

f:id:hntsu:20180127171709p:plain

flag[1] == flag[10]

f:id:hntsu:20180127171712p:plain

flag[1] - 0x11 == flag[0]

f:id:hntsu:20180127171611p:plain

flag[3] == flag[9]

f:id:hntsu:20180127171614p:plain

flag[4] == 0x69

f:id:hntsu:20180127171631p:plain

flag[2] - flag[1]== 0xd

f:id:hntsu:20180127171637p:plain

flag[8] - flag[7]== 0xd


これらを求めると以下のようになる

flag[0] == 0x50
flag[1] == 0x61
flag[2] == 0x6e
flag[3] == 0x64
flag[4] == 0x69
flag[5] == 0x5f
flag[6] == 0x70
flag[7] == 0x61
flag[8] == 0x6e
flag[9] == 0x64
flag[10] == 0x61

文字に直してあげればflagの完成
Flag is {Pandi_panda}

おわりに

卒論等で忙しかったので久しぶりに問題解いた、、、
卒論発表会がまだ残ってるけどSECCONとかに向けて少しずつ準備を進めていきたいですね