2016年02月07日

CTF Writeup 場阿忍愚CTF(バーニングCTF)

 本日、オンラインで昨年11月16日から開催されていた場阿忍愚CTFが終了しました。楽しかったです。 結果は20位で、四段:ド変態の称号(ヒドイw)をいただきました。すでにWriteupを書かれた方がいるので、取り急ぎそちらで記載されていないものだけ記載します。

 Writeupリンク

123 二進術 Unity遊戯如何様

 Unityで作成されたMacのアプリケーション。3Dゲームだったので、とりあえず普通にプレイしてみる。ホップ・ステップ・ジャンプといった調子でジャンプするとジャンプ力が上がるため、楽しくて本気で2時間ほどプレイしてみましたが、どうしても3枚目のコインを発見できません・・・(苦笑)
 ヒントにあった Assembly-CSharp.dll をILSpyでデコンパイルしてソースコード(GUI Managerクラス)を確認すると、コインが3枚の時にフラグを表示することが判明します。というか、フラグ文字列「its_3D_Game_Tutorial」が普通に見えているので、それをサブミットするも不正解。スコアサーバの調子が悪いのかと思い、しつこく何回もサブミットしてしまいました。

 ゲームのチートをする問題なので、ソースコードを読むだけじゃダメなのかなと諦めて、Windows環境にVisualStudio 2008 ExpressとUnity Editorをインストールして、ILSpyでデコンパイルした Assembly-CSharp.dll をプロジェクト形式で保管したものを読み込み、必ずフラグが表示されるようソースコードを修正してDLLをビルド。
 DLLを入れ替えて、Macでゲームを実行したところ、フラグが全て大文字で表示されました。

 フラグ: ITS_3D_GAME_TUTORIAL

142 攻撃術 Ninja no Aikotoba

  問題サーバに接続すると、問いかけの文字列(例:Kawa)が表示され、合言葉の入力を求められる。ソースコード(aikotoba.c)を読み、合言葉の解読方法を考える問題でした。

1問目
 サーバが表示する問いかけは、合言葉を特定のアルゴリズムで変換したもの。プログラムを読み、問いかけから合言葉を導きだします。
  問いかけ:Kawa
  問いかけ生成のアルゴリズム: 合言葉の文字列(4文字)を整数型に型変換し、0x001a0012でxorします。
  合言葉:Yama

2問目
 プログラムに合言葉が埋め込まれている。8進数、10進数、16進数で文字コードが記載されています。
  合言葉:too
3問目
 合言葉をencrypt関数で処理した結果が、12個の10進数として画面に表示されます。なお、画面に表示される数値は毎回同じ。 encrypt関数を読むと、合言葉[n]と合言葉[n+6]を処理した結果を、result[n]とresult[n+6]に格納していることが分かります。問題プログラムを読むと、合言葉はアルファベット(大文字、小文字)で構成されていることが分かるため、ブルートフォースするプログラムを書けば解けます。
  合言葉:KansaiTanaka
4問目
 MD4のハッシュ値が表示されるので、ハッシュ値のクラックサービスでクラックします。
  合言葉:Zach
5問目
 この問題だけはソースコードを読んでも答えが分かりません。IDAで問題ファイル「aikotoba」、および呼び出しされる「libc.so.6」の関数を確認しても、脆弱性の存在を発見できませんでした。(aikotobaの逆アセンブリリストをじっくり読んでも脆弱性を発見できなかったので、libc.so.6のどこかで脆弱性のあるのだと思いますが・・・) libc.so.6をチラ見したところ、setbuf関数のなかで、バッファサイズを約8KBに設定しているようだったので、なんとなく8KB程度の大量データを繰り返し送信していたら、たまにフラグが表示されることに気が付きました。 攻撃が成功した理由はよく分かっていません・・・(-_-;)

[攻撃ログ](ファイルinputは、1問目から4問目までの答え、および5問目への入力として8KB程度のASCIIテキストを記載してあります。)

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input

C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
Let me check if you are my ally.

Kawa? : Good.

So then next? : Good.

-9 0 0 18 -10 8 159 194 220 212 204 202? : Good.

aa1bf8cae599b19366a8bd4b87ddd327? : Good.

And the rest? : You aren't my ally!!!
[*] YOU DIED

C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
Let me check if you are my ally.

Kawa? : Good.

So then next? : Good.

-9 0 0 18 -10 8 159 194 220 212 204 202? : Good.

aa1bf8cae599b19366a8bd4b87ddd327? : Good.

And the rest? : You aren't my ally!!!
[*] YOU DIED

C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
Let me check if you are my ally.

Kawa? : Good.

So then next? : Good.

-9 0 0 18 -10 8 159 194 220 212 204 202? : Good.

aa1bf8cae599b19366a8bd4b87ddd327? : Good.

And the rest? : You aren't my ally!!!
[*] YOU DIED

C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
Let me check if you are my ally.

Kawa? : Good.

So then next? : Good.

-9 0 0 18 -10 8 159 194 220 212 204 202? : Good.

aa1bf8cae599b19366a8bd4b87ddd327? : Good.

And the rest? : You aren't my ally!!!
[*] YOU DIED

C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
Let me check if you are my ally.

Kawa? : Good.

So then next? : Good.

-9 0 0 18 -10 8 159 194 220 212 204 202? : Good.

aa1bf8cae599b19366a8bd4b87ddd327? : Good.

And the rest? : You aren't my ally!!!
[*] YOU DIED

C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
Let me check if you are my ally.

Kawa? : Good.

So then next? : Good.

-9 0 0 18 -10 8 159 194 220 212 204 202? : Good.

aa1bf8cae599b19366a8bd4b87ddd327? : Good.

And the rest? : You aren't my ally!!!
[*] YOU DIED

C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
Let me check if you are my ally.

Kawa? : Good.

So then next? : Good.

-9 0 0 18 -10 8 159 194 220 212 204 202? : Good.

aa1bf8cae599b19366a8bd4b87ddd327? : Good.

And the rest? : You aren't my ally!!!
[*] YOU DIED

C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
C:\WORK\CTF\Attack300>nc 210.146.64.35 31338 < input
Hi.
Let me check if you are my ally.

Kawa? : Good.

So then next? : Good.

-9 0 0 18 -10 8 159 194 220 212 204 202? : Good.

aa1bf8cae599b19366a8bd4b87ddd327? : Good.

And the rest? : Well Done!

Flag: flag={GetsuFumaDen}


C:\WORK\CTF\Attack300>
            

 フラグ:GetsuFumaDen

155 解析術 Encrypted Message

 問題ファイル「155-secret」の内容をバイナリエディタで確認したところ、暗号化されたデータのように見えます。もう一つ問題ファイルとして配布されているメモリダンプのなかに復号のヒントがあると考え、Volatilityで解析を実施しました。

 (1)imageinfo
    Win8SP0x86またはWin8SP1x86のメモリイメージであることが判明
 (2)pslist (profile=Win8SP1x86)
    TrueCryptが起動していることが判明。「155-secret」はTrueCryptのコンテナファイルであると推測

 (3)truecryptmaster / truecryptpassphrase (profile=Win8SP1x86)
    何も抽出されない

 (4)truecryptmaster / truecryptpassphrase (profile=Win8SP0x86)
    プロファイルが間違っている可能性を考え、SP0で再度実行したところ、truecryptのMaster Keyを取得

 Master KeyからTrueCryptコンテナを復号するため、Master Keyを埋め込んだTrueCryptをコンパイルします。
 (1)Linux環境でTrueCrypt 7.0aのソースコードを準備
 (2)VolumeHeader.cppにパッチを適用(詳細は参考リンクを参照)
    パッチには、前述の手順で取得したMaster Keyを埋め込む
 (3)TrueCryptをコンパイル

 これだけではTrueCryptコンテナを復号できないため、「155-secret」のヘッダ情報を次の手順で書き換えます。
 (1)Windows環境の通常版TrueCryptでコンテナファイル(テンプレートと呼ぶ)を作成
    その際、暗号方式、サイズ(Disk Length)は「155-secret」を同じ設定とする
    パスフレーズは任意のものを設定する。ここでは、「abc123」を設定した
 (2)テンプレートのヘッダ(ファイルの先頭512バイト)を、「155-secret」に上書きする
    $ dd if=template of=155-secret bs=512 count=1 conv=notrunc

 ヘッダを書き換えた「155-secret」を上記3.で準備したパッチ適用済みTrueCryptでマウントします。
パスフレーズは、テンプレートで設定した「abc123」を指定します。この手順により、「155-secret」をマウントすることができます。

 コンテナのなかに、「flag.txt」が格納されており、フラグが記載されていました。

 フラグ: Already Ended In 5/2014

 参考リンク

PlaidCTF Writeup: Fun with Firewire
http://mweissbacher.com/blog/tag/truecrypt/

以上です。
posted by やまと at 20:51| Comment(0) | CTF

2015年04月19日

無線LANセキュリティの基礎

 最近、無線LANセキュリティとして「ステルスSSID」や「MACアドレス制限」ってどうなの?と聞かれることが続いたので、プチプレゼン資料にまとめてみました。

 結論としては、意図的な攻撃に対するセキュリティ対策としては、ほとんど意味はありません。

 しかし、MACアドレス制限は、組織内で正規利用者にAP接続パスワードを開示せざるを得ない状況において、補助的に利用するのはアリだと思っています。

 詳細は資料をご覧ください。

以上
タグ:無線LAN
posted by やまと at 21:42| Comment(0) | 実験日誌

2015年03月14日

簡易解析入門 プログラム実行の痕跡の調査 (1)Prefetch

 マルウェア感染などのインシデントにおいて、特定のプログラムの実行有無および実行日時を確認したいことがあります。

[確認したい状況の例]
  • マルウェアに感染した日時を特定したい(マルウェアが実行された日を知りたい)
  • 不審メールに添付されていたマルウェアの実行有無を確認したい(利用者の記憶が曖昧なため調査したい)

 Windowsでは、プログラム実行の痕跡がさまざまな形で残りますが、今回はお手軽に調べることができる「Prefetch」(プリフェッチ)の調査方法を紹介します。

Prefetchの概要

 Prefetchは、利用頻度が高いアプリケーションの起動を高速化する仕組みで、WindowsXPから導入されました。

[主な特徴]
  • プログラムが起動された10秒後に、C:\Windows\Prefetchフォルダに、ファイル名が「プログラム名-フルパスのハッシュ値.pf」のファイルが作成される。
  • ハッシュ値は、プログラムのフルパスから計算される。「プログラム名」部分が同一でハッシュ値が異なるPFファイルは、異なるフォルダから実行されたと判断できる
  • PFファイルには、プログラムのフルパス、実行日時、実行回数、プログラムが起動時に読み込んだファイル名(DLLファイルなど)、ボリューム関連情報が記録される。
  • コマンドラインやオートラン機能(autorun.inf)などにより実行したプログラムもPFファイルが作成される。
  • PFファイルは最大で128個程度作成される(参考文献では最大128個との記載がありますが、私の環境では129個まで作成されることを確認しています)
  • Windows7以降で、SSDを搭載しているとPrefetchが無効化される場合がある(私のDynabook R632 2012年モデルでは無効化されていません)

(注記)条件は不明ですが、PFファイルが作成されない場合もあります。 そのため,PFファイルが存在していないことで、「過去に実行されたことはない」と判断することはできません。 (Prefetchに限らず、フォレンジック調査では「存在していなかったこと」を証明することは難しいです)

参考文献

Forensics Wiki - Prefetch(英語)
http://www.forensicswiki.org/wiki/Prefetch

Forensics Wiki - Windows Prefetch File Format(英語)
http://www.forensicswiki.org/wiki/Windows_Prefetch_File_Format

調査方法

エクスプローラーによるお手軽調査方法

 エクスプローラーで、Prefetchフォルダを確認してみましょう。なお,このフォルダにアクセスするには管理者権限が必要です。 PFファイルの存在から、プログラム実行の痕跡を確認できます。 また、PFファイルの作成日時・更新日時から、実行日時を推測することができます。

(注記)PFファイルのタイムスタンプは、プログラム実行の10秒後に更新されることにご注意ください

Prefetch Folder

「WinPrefetchView」による調査方法

 NirSoft「WinPrefetchView」は、PFファイルの解析結果を表示してくれるフリーソフトです。

 起動には管理者権限が必要です。起動すると、C:\Windows\Prefetchフォルダに格納されているPFファイルの解析結果が表示されます。

 任意のフォルダに格納したPFファイルを解析したい場合は、メニューから「Options」-「Advanced Options」をクリックすると、フォルダ指定ダイアログが表示されます。

[説明]
  • 表示されるタイムスタンプは、すべてローカルタイム(日本時間)
    (設定を変更すればUTCでの表示も可能)
  • 「Last Run Time」は、PFファイルに記録されている最終実行日時
  • 「Run Counter」は、プログラム実行回数
  • 「Created Time」、「Modified Time」は、PFファイルのタイムスタンプ
    (PFファイルのコピーなどの操作により、タイムスタンプが更新されるので注意)

WinPrefetchView

バイナリエディタによる調査方法

 参考文献のPFファイルのフォーマットを読むと、PFファイルには、ボリュームシリアルも記録されることが分かります。

 ボリュームシリアルとは、ファイルシステムをフォーマットした時刻情報をもとに生成されるランダムな値のことです。 現在接続されているディスクなどのボリュームシリアルは、コマンドプロンプトからdirコマンドを実行することで簡単に調べることができます。

E:\>dir
ドライブ E のボリューム ラベルは LABUSB です
ボリュームシリアル番号は 523E-8109 です

(表示内容は省略)

E:\>
    

 調査対象機器のボリュームシリアルが同じ値となる可能性は低いため、例えば起動されたプログラムが格納されていたUSBメモリの特定などに役立ちます。

 残念なことに、WinPrefetchViewでは、ボリュームシリアルを表示することができません。

 しかし、バイナリエディタを使って手動でPFファイルを解析すれば、ボリュームシリアルを特定することが可能ですので、挑戦してみましょう。

注意事項

この調査方法は、WindowsXPで作成されたPFファイルに対してのみ有効です。
Windows7のPFファイルには、USBファイルから起動した痕跡は残りません。

 今回は、USBメモリにFTK Imager Liteを格納し、WindowsXP SP3に接続して実行したPFファイルを解析してみます。

 それでは、適当なバイナリエディタでPFファイルを開いてみましょう。

 ファイルの先頭(Offset 0x00)のデータが、「0x11」(10進数で17)となっています。 これは、PFファイルのバージョン情報で、WindowsXPのPFファイルであることを示しています。 もしも、0x11以外の値だった場合、他のOSで作成されたPFファイルのため、USBメモリに関する情報は含まれない可能性が高いため、ご注意ください。

Prefetch Image01

 次に、ファイルの先頭から0x6cバイトの位置(Offset 0x6cと表現します)に記録されている4バイトの値を確認します。 Bzエディタの場合、上部にある検索ボックスに「> 6c」と入力してエンターキーを押すと、指定したアドレスにカーソルがジャンプします。

 この例では、Offset 0x6cから「B8 33 00 00」となっています。 リトルエンディアン(アドレスが大きいほうから、小さいほうに記録する形式)で記録されているため、右から左にバイトずつ読み取り「0x000033b8」と解釈します。

Prefetch Image02

 読み取った「0x33b8」に「0x10」を加算したアドレス「0x33c8」が、ボリュームシリアルへのオフセットです。 それでは、Offset 0x33c8の値を確認してみましょう。「09 81 3e 52」となっています。 これもリトルエンディアンで記録されていますので、右から左に読み取り「52 3e 81 09」と解釈します。

 コマンドプロンプトで確認したボリュームシリアルと一致しました。

Prefetch Image03

 また、プログラムのフルパスも記録されていますので、プログラム名で検索してみましょう。 Bzで検索する場合は、メニュー「表示」-「文字コード」を「Unicode(UTF-16)」にしないと検索がヒットしないので注意してください。 (Bzは現在表示している文字コードで検索する仕様です)

 フルパスはハードディスクから実行した場合と異なる形式で記録されており、USBストレージから起動したことが分かります。 ハードディスクから起動した場合にどのように記録されているかは、ぜひ皆さんの環境でご確認ください。

Prefetch Image04

 なお、今回はボリュームシリアルをdirコマンドで確認しましたが、FTK Imager Liteなどで、 USBメモリ(またはUSBメモリのイメージファイル)を参照することでも確認することができます。 ボリュームシリアルは、ディスクのあるオフセットに書き込まれているのですが、今回は詳細な説明は割愛します。

Windows7環境におけるUSBメモリからの実行痕跡

冒頭で述べたとおり、Windows7環境では、PFファイルにUSBメモリの痕跡が残りませんので、注意が必要です。

具体的には、次のように記録されます。

  • ボリュームシリアルは、OS起動ドライブのものが記録される
  • プログラム本体やDLLファイルなど、USBメモリに格納したファイルのパスは一切記録されない
  • ボリューム作成日時は、OS起動ドライブの$MFTのタイムスタンプが記録される
    (本記事では説明していない内容のため、ご参考まで)
以上
posted by やまと at 00:01| Comment(0) | 実験日誌