Check Point Security Academyによる忍耐パズルのテスト

HabréでCheck Point Security Academyプログラムについて何度か言及しました。その本質は、 Check Point企業が夏にCapture the Flag形式のコンペを発表したことです。参加者の過去の経験は重要ではなく、サイバーを解く能力だけですパズル。 この競争の結果に基づいて、会社はサイバーセキュリティの3か月の専門コースに20人の参加者を募集し、コースの最初からすべての参加者は、コース終了後2年で会社で働く義務の下でKBの専門家の全給を受け取ります。





CTF競技会では、旗はこのような絵になることさえあります。



参加者の選考は8月に終了しましたが、コンテストのウェブサイトは来年の夏まで運営されます。スポーツの興味のために登録して手を試してみたい人を招待します。 コンテストは、複雑さの異なる12個のパズルで構成され、10〜150ポイントの評価があります。

ここでは、「サプライズ」カテゴリの「Test My Patience」パズルを解析します。 彼女は中程度の難易度(50ポイント)であり、全文は次のとおりです。

こんにちは

この実行可能ファイルは、ローカルの時計メーカーのコンピューターで見つかりました。

どういうわけか時計職人がそれを破ることに成功した唯一の人だったと噂されています。

あなたは時計職人と同じくらい良いと思いますか?

注:このファイルは悪意のあるものではありません
参照-Windows用の32ビットバイナリ。 一部のウイルス対策ソフトウェアはそれを誓いますが、それでも実行すると、次のようになります。







バイナリの内部は暗号化されています。 デバッガーでの実行を拒否します。 実行中にデバッガを接続しようとすると、すぐに終了します。 おそらく、チェックポイントの専門家は、ある種のマルバリから借りた暗号パッカーにパズルを包んでいました。



時計職人が作り上げた数字をどのように推測しますか?



2つの方法があります。 最初は条件付きで「パワーがあり、気にしない」と呼ぶことができます。プログラムをライブでデバッグできない場合は、死んだものをデバッグします!



32ビットの「タスクマネージャー」(\ Windows \ SysWOW64 \ taskmgr.exe)を起動し、不可解なプロセスを右クリックして、[ダンプファイルの作成]を選択します。 (32ビットプロセス用の64ビットタスクマネージャーはwow64cpuエミュレーターのダンプを作成しますが、これは作業が困難です。)



ダンプを調べて、少なくともその中の行が既に復号化されていることがわかります。







ただし、隠し番号またはフラグの付いた行はまだ表示されていません。



メインキャリバーの武器であるWinDbg(X86)-> Open Crash Dump ...







私たちが見たいと思う行は、メモリのどこにありますか-「お疲れ様でした!」

lm



コマンドを使用すると、バイナリが01140000



から01140000



にロードされている01140000



015b2000



ます。 その後、 sa 01140000 015b2000 "Good job my friend!"



0115a0d0



検索文字列を検索します。







ここで、この行が印刷される場所を見つけましょう。おそらく、コマンドには、目的の行のアドレスに対応するバイトd0 a0 15 01



が含まれている場合があります。 ( sb 01140000 015b2000 d0 a0 15 01







頑張って! -そのようなコマンドが見つかりました:







このコマンドの周りのコードは何ですか? ( ub 011412f7; u 011412f7











関数01141180



の結果に応じて、探しているメッセージが印刷されるか、または「間違っています...」



機能コード01141180



は3つの画面を占有します。 これがstrcmp()



実装であり、その中にSleep(700)



呼び出しが追加されていることを理解するのは非常に簡単です。 Sleep()



が存在する理由はまだ明らかではありません。 ただし、それでも関数の結果には影響しません。そのため、比較される行の種類を把握します。







ebp-14h



ebp-24h



等しい2つのポインターebp-24h



ebp-14h



ます。 2番目の関数は、引数を関数011410b0



に渡す前011410b0





これは隠し番号を要求する関数ではありませんか? 呼び出しスタック( k



)を確認しましょう。







はい、彼女です!



パズルの一般的なスキームが明確になりました。ユーザーの予測はebp-24h



保存され、その数はebp-14h



ebp-14h



。その後、比較され、「Good job my friend!」または「Wrong one ...」が印刷されます。



残るのは、スタックフレームから隠し番号を取得することだけです。 コールスタックから彼のebp



を既に知っています。







さあ、さあ...







成功! おいしいものを外すことができます。



しかし、3つの不思議な事柄は説明なしで残されました。
  1. Sleep(700)



    strcmp()



    Sleep(700)



    内にSleep(700)



    呼び出しがあるのはなぜですか?
  2. なぜ、隠し番号を入力したときに、「Good job my friend!」を印刷する前にプログラムが10秒間フリーズしたのですか?
  3. 時計職人はこのパズルと何をしなければなりませんか?


したがって、推測された数を推測するための2番目の(よりインテリジェントな)方法があります。 0から9の数字をランダムに試してみると、9でプログラムが少しハングしていることに気付くのは簡単です。 90〜99の数字を試してみると、98の数字でプログラムが2倍の長さで「フリーズ」していることがわかります。 (内臓を発見したので、私たちはすでに問題を理解しています。文字の各ペアの比較に成功すると、0.7秒の遅延が発生します。)デバッガーを起動せずにパズルを解くには、次の数字を選択するだけで十分でした。正確なストップウォッチ、または単純なスクリプトを使用します。 したがって、コンパイラーは、エラーメッセージが測定および分析されるまでの時間が長い場合、 暗号アルゴリズムを攻撃する長年の方法を示唆しました。



しかし、私の意見では、未知の暗号パッカーに包まれたプログラムをピックアップする方法を学ぶことは、より興味深く、より価値があります:-)



バイナリがどのように暗号化されるか、または入力した数字の文字列がスタックにどのように表示されるかを把握する必要はないことに注意してください(ダンプで文字列定数の中にないことがわかりました)-準備と準備の両方ができました約12個のWinDbgコマンドで十分でした。



All Articles