web-dev-qa-db-ja.com

ゼロ日はどのようにして見つけられますか?

NSAには、「雨の日に」というように、さまざまなソフトウェアに対するゼロデイエクスプロイトの長いリストがあります。つまり、それが役立つ場合はいつでもあるということです。

問題は、どのようにしてこれらのゼロ日を見つけるのかということです。誰かが物理的にコンピューターの前に座って、ランダムなこと(つまり、リモートコードの実行をPDFのスクリプト内にあるbase64でエンコード)を試さなければならないのですか、それとも、ソフトウェアの穴を積極的にペンテストする自動システムがありますか?特権の昇格またはリモートでのコード実行はどこで機能しますか?

53
Naftuli Kay

ゼロデイは、他の種類のホールとまったく同じ方法で見つかります。セキュリティホールを「ゼロデイ」にするものは、他の技術的特徴ではなく、ホールの存在を誰が知っているかにのみ依存します。

穴は通常、ファンキーな振る舞いに気づいた好奇心旺盛な人々によって発見されるか、 imagine バグの可能性があるため、プログラマーがそれに陥ったかどうかを確認しようとします。たとえば、文字列の内容を処理し、大文字と小文字の違いに影響されないように努める(つまり、 "A"を "a"と同等として処理する)コードは、トルコ語のコンピューターで実行すると問題が発生する可能性があります(トルコ語では、 "I"の小文字は "i"ではなく "ı"です)。これは、セキュリティホール(例: some システムの一部が文字列の等価性をチェックする場合)ロケール依存の方法ですが、他の方法はそうではありません)。したがって、私は自分のコンピューターをトルコ語のロケールで構成して、ターゲットとするソフトウェアが(トルコ語を話す以外に)奇妙なことを始めるかどうかを確認できます。

バグ検索の一部は、多くの「異常な組み合わせ」を試すことによって自動化できます。これは ファジング として知られています。クラッシュを引き起こす入力の組み合わせを見つけることは、最初のステップとして役立ちます。クラッシュは通常メモリの破損を意味し、メモリの破損はリモートコード実行のような気の利いたことにときどき悪用される可能性があるため、ターゲットシステムをクラッシュさせるものはすべて調査する必要があります。ただし、そのような調査は依然として人間の脳によって行われる必要があります。

(セキュリティホールを検出する完全に自動化された方法があった場合、ソフトウェア開発者はそれを使用してバグのないコードを生成します。)

71
Thomas Pornin

Thomas Porninの優れた答えに加えて、通常、ゼロデイ脆弱性は、ソースコードの監査、リバースエンジニアリング、ファジング(またはファズテスト)を通じて発見されます。

手法の選択は通常、手元にある情報に依存します。たとえば、ソフトウェアがオープンソースの場合、ソースコードをふるいにかけ、脆弱性を探すことをお勧めします。ソースコードを確認することですべての実行ブランチを調べて理解できるため、ソースコードの監査を通じて発見された脆弱性は通常、悪用されやすくなります。ソースコード監査のプロセスは、strcpyのような危険な関数呼び出しのgrep-ingのように単純な場合もあれば、すべてのブランチコードの実行と分析を探す自動コードカバレッジテストのように複雑な場合もあります。

ソースコードが利用できない場合、脆弱性研究者の次のオプションは、アプリケーションをリバースエンジニアリングして低レベルコードを分析することです。アプリケーションがデバッガーを介して、またはより好ましくはIDAなどの逆コンパイラーを介して分析される場合、コードチャンクとアセンブリニーモニックは、分析が容易な比較的高水準の言語ルーチン構造にマップされます。脆弱性研究者は、実行フローに従って、静的または動的に動作を分析して、さまざまなセキュリティバグを見つけることができます。たとえば、固定サイズのバッファーを割り当て、ユーザー制御の入力を割り当てられたバッファーにコピーすると、通常、バッファーオーバーフローの悪用を通じて悪用される可能性があります。

ソフトウェアの新しい脆弱性を見つける最後の方法は、ファズテストです。特別に細工された文字列(過度に長い文字列や特殊文字を含む文字列など)がクラッシュするソフトウェア。ソフトウェアがクラッシュすると、ファズテストが停止し、アプリケーションがクラッシュした入力を脆弱性研究者が分析できるようになります。クラッシュが確実にトリガーされ(たとえば、アプリケーションに提供された特定のバイトセットがクラッシュを引き起こすたびに)、実行フローが実行可能メモリ内のユーザー制御データに転送される場合、バグはリモートに分類されます。コード実行バグ。それ以外の場合、クラッシュが信頼できるバグであり、コード実行に変換できない場合、サービス拒否のバグとして分類されます。

20
void_in