2017年1月29日日曜日

CTF4bのバイナリwriteup(復習問題除く)

と言うわけで、Writeupをサクッと書いてしまおうと思います。
(時間無いし、あとでやるとかやってるとだいたいモチベが低下するので)
解いた問題だけやる形でいきます。
と言うわけでスコアボード。
表示はなんか恥ずかしいから、susonoにしてた、バイナリ(非実在バイナリ=テキスト形式で渡されたやつはやってません)を今回は攻めてみた。



スコアボード、スコア全く気にしてなかったけど48位だった。
やったぜ?






まずは、100点から。

問題:HiddenFlag(点数100、回答数208)
問題の概要:stringsでバイナリの中の文字列を抜き出してgrepで絞り込む。
$ strings ./bin100_1 |grep ctf4b
ctf4b{fl4g_1n_d474_53gm3n7}
Flag : ctf4b{fl4g_1n_d474_53gm3n7}

問題:UnusedFunction(点数200、回答数24)
確か、2種類あってもう一種類は復習だった。(復習の方は解いてない)
この問題はIDAで見てgdbで動かすだけで解ける。
問題の概要:使ってない関数を呼び出し(パッチを当てる)て、フラグ生成位置で止める(デバッガを使う)

とりあえず適当なディスアセンブラで開く。
IDA Freeあたりでいいと思う。

で、使ってない関数(genflag)があるのでそれをmainから読んであげて
gdbでブレークしてあげればFlagがでる。

とりあえずgenflagをmainから呼ばれるようにパッチを当てる。
パッチの当て方は、適当にアドレス調べてバイナリエディタで当てる。
ディスアセンブラにパッチを当てる機能があればそれを使う。

パッチを当てたので呼ばれるはず。引数も特に無かったしただcallするだけでOK

genflagの中身、Flagっぽい何かを配列に大量にしまっている。
多分これはエンコード後の文字列なので、デコーダーを探す。

赤枠の所がデコーダー。
青枠の所がgdbで止めるアドレス(ブレークポイント)

んでgdbで止めた所

で、ECXレジスタが指すポインタの文字列がフラグなので、あとはコピペするだけ

Flag: ctf4b{4n4lyz3_unu53d_func710n}

問題3:Cipher(点数300、回答数1=俺)
問題の概要:XORで入力文字列をエンコードする。rand関数の特徴を知っていれば解ける。
rand関数 : srandで与えられた数値を基に、線形合同法で擬似乱数を生成する。
つまり、srandの値が固定なら、rand関数は毎回同じ数値列を返却する。

余談:
なお、セキュリティ用途(暗号等)で使うなら、ちゃんとしたエントロピープールから持ってきた乱数(WindowsならCryptGenRandom、Linuxなら/dev/urandomやrandom(3))使おうな。
この課題みたいに、オレオレXOR暗号化なんてアルゴリズムさえこういうふうに分かっちゃえば解けるんだから絶対駄目よ。
ちゃんとアルゴリズムが公開されて、それを読んでも暗号化されたデータの中身が全く推測できないAESとかECDSAみたいな暗号化アルゴリズム使いましょう。

そんなわけで、main関数を見てみる。


やってること

  1. ユーザから入力を受ける
  2. 改行文字を消す(strchr)
  3. check_flagを呼び出す

というわけで、check_flagを読んでみましょうかね。

なんか見たことあるような感じ。さっきの200点問題と同じ感じがある。



ここも、さっきの200点問題と同じ感じがある。
でもやってることは実は、デコードでなくて、
ユーザから入力されたフラグのエンコード。さっきとは真逆のことをしている。


つまり、さっきみたいに、↓の画像のところでgdbで止めても
見えるのはエンコードされたなんだかよくわからないデータ。
だから次は別の方法でやる。

↑ここでgdbを止めても意味はない。

そこで、このバイナリから、エンコードされているバイナリ部分だけを抜き出す。
(赤枠の部分)


さらに、それをデコードするこんな感じのコードを書く



実行すると、
ctf4b{51mpl3_x0r_c1ph3r} 
が出てくる。

Flag:ctf4b{51mpl3_x0r_c1ph3r}

以上。

0 件のコメント:

コメントを投稿