2012年11月12日月曜日

SECCON CTF in NAIST Misc パジャマでおじゃま

問題はパケットチャプチャ形式のファイルで、その中身は以下のようになっています。
ご覧の通り192.168.96.128と192.168.96.129のICMPを利用したpingのパケットが並んでます。
また、データ部も、OSに付属するpingコマンドが付加するシーケンシャルに大きさが増加するバイトが代入されています。
ただ、最初はそうですが、途中からすこし異なってくるようです。
例えばid=0x21dc、seq=26のicmp requestにたいして、同じid、seqとなるicmp replyは3つ返ってくることがわかります。またパケット長も不揃いになってきました。72 ~ 500まで変動しています。さらにパケット長が500のパケットのデータ部は明らかに通常のpingと異なるメッセージになっています。
図の165番のパケットの場合、データ部にLast login Suc Oct 7 15: とか明らかにログイン後に出てくるメッセージなのでicmp replyのデータ部が怪しいと分かります。

各icmp replyのデータ部を眺めているとこんなことに気づきました。

  • パケットの0x44バイト目はシーケンシャルに増加している
  • パケットの0x45バイト目は必ず0x21である
だからid=0x21dcのicmp replyの0x44バイト目を基準にパケットをソートし直して、重複を取り除きました。
すると以下のようになりました。

ログインコマンドが9600,9600なのかは不明ですが、ログイン先のOSがDebian GNU/Linux 5.0でホスト名がsrcみたいです。
ユーザ名はctf、パスワードもctfでログインに成功しました。
若干見づらいですがその後cat key.txtを実行しており、そこでkey.txtの中身が現れ、これが答えとなります。
その後exitしてlogoutに成功しました。
こうした一連のやり取りがpingを通じて行なわれていたことがわかりました。

しかし驚くのはここから、こうしてパケットを縦に並べてみると0x45バイト目の0x21、つまり'!'が縦に並んでいることがわかります。
'!'を境にして左側は通常のpingに付加されるデータ、右側がログイン時の通信というふうにして2つの意味を成していたことがわかりました。

マニアックな通信の仕方ですね。まるでマルウェアみたい笑。




SECCON CTF in NAIST Binary hello-x86-world

またしてもWindowsの実行ファイルからの問題です。実行するとヘルプメッセージを出してくれるとか親切です。
では何を引数に入れたらいいのかを探していきましょう。
下図がmain関数の逆アセンブリです。
call _printfまで実行されたら負けなのでjz short lot_40122Dを追います。loc_40122Dはジャンプ元の直下にあるところで、コマンドライン引数をchar *型として関数sub_4010E0に渡します。では関数sub_4010E0を見てみましょう。
まずeax = _strlen(char *)を求めていることが分かります。
そしてcmp eax, 0xEがあるのでこのコマンドライン引数が14文字であるかどうかを確かめています。14文字の場合、その次のjmpは成立しないので上から順に実行されます。
mov ecx [ebp+ arg_0]
movsx edx, byte ptr [ecx+8]
この2命令でecxにコマンドライン引数であるargv配列の先頭を指すアドレスが入り、edxにargv[8]が入ります。
その次にedx = argv[8] == 0x61 ('a') ? かどうかを比較しているのでargv[8] = 'a'とわかります。
では比較がなりたつ場合、jzは成立せず、また順に実行されます。
上記の手順と同様に
mov eax, [ebp+arg_0]
movsx ecx, byte ptr [eax+7]
mov edx, [ebp+arg_0]
movsx eax, byte ptr [edx+8]
より、ecx, eax = argv[7], argv[8]となりました。
つぎに
sub ecx, eax
cmp ecx, 13h
によりargv[7] = argv[8] + 0x13ということがわかります。
つまりargv[7] = 'a' + 0x13 = 't'となり、argv = "*******ta*****"となります。
以降同様のようなアルゴリズムでargv[0x0] ~ argv[0x10]まで確定しますが、そこで関数が終了しています。(下図)

なのでこれで求まったargv[0:0x10] + "???"の14文字をコマンドライン引数にして代入して実行してあげると同じディレクトリに123というファイルが作成されます。
このファイルの中身からは未だにとくにヒントらしきものが見つからないので
求まったargv[0:0x10]あるいはargv[0:0x10] + "123"がkeyなのではないかと推測しています。

SECCON CTF in NAIST Binary A_Cinderella_protection_for_beginners

問題をダウンロードして解凍するとCinderella.exeというWindows実行ファイルを発見できます。そしてそれを実行すると


 というふうになるので特定の日時にしかイベントが発生しないことが分かります。
では、特定のイベントを発生させるためにプログラムの逆アセンブリを見てみましょう。

main関数は上図のようになります。上図の逆アセンブリからさっきのメッセージボックスはcall MessageBoxAから発生していることが分かります。つまりその前のjnz short loc_401040でイベントが発生するかどうかの分かれ目のようです。
ではloc_401040はどういうコードかというと
こんな感じです。赤色で示されたmov esi, [ebp+arg_0]によってloc_401040にジャンプする前にpushされたeaxがesiに代入されています。さらに前のlea eax [ebp+SystemTime]からSystemTime構造体を指すアドレスがesiとなります。
その後にcmp word ptr [esi], 7DChとかあるので、0x7DC = 2012から考えると
年、月、日、時、分、秒という順に比較されていることが分かります。
つまりこれらの比較条件に合うように[esi+?]の値を操作してあげればイベントが発生します。
なのでこの時刻がキーではないかと思います。
ちなみにイベントはただ時刻をお知らせするメッセージボックスが表れるだけでした。