
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つの不思議な事柄は説明なしで残されました。
-
Sleep(700)
strcmp()
Sleep(700)
内にSleep(700)
呼び出しがあるのはなぜですか? - なぜ、隠し番号を入力したときに、「Good job my friend!」を印刷する前にプログラムが10秒間フリーズしたのですか?
- 時計職人はこのパズルと何をしなければなりませんか?
したがって、推測された数を推測するための2番目の(よりインテリジェントな)方法があります。 0から9の数字をランダムに試してみると、9でプログラムが少しハングしていることに気付くのは簡単です。 90〜99の数字を試してみると、98の数字でプログラムが2倍の長さで「フリーズ」していることがわかります。 (内臓を発見したので、私たちはすでに問題を理解しています。文字の各ペアの比較に成功すると、0.7秒の遅延が発生します。)デバッガーを起動せずにパズルを解くには、次の数字を選択するだけで十分でした。正確なストップウォッチ、または単純なスクリプトを使用します。 したがって、コンパイラーは、エラーメッセージが測定および分析されるまでの時間が長い場合、 暗号アルゴリズムを攻撃する長年の方法を示唆しました。
しかし、私の意見では、未知の暗号パッカーに包まれたプログラムをピックアップする方法を学ぶことは、より興味深く、より価値があります:-)
バイナリがどのように暗号化されるか、または入力した数字の文字列がスタックにどのように表示されるかを把握する必要はないことに注意してください(ダンプで文字列定数の中にないことがわかりました)-準備と準備の両方ができました約12個のWinDbgコマンドで十分でした。