web-dev-qa-db-ja.com

ソースからのコンパイルは「ちょっと」バッファオーバーフロー攻撃から保護しますか?

バッファオーバーフローについて説明しているときに、「メインストリームバイナリ」を使用する代わりに、(特定のコンパイルフラグを使用して)アプリケーション用に独自のバイナリをコンパイルすると、さらに困難になると誰かから言われました攻撃者がバッファオーバーフローを利用するため。

どうやら、それは主流のバイナリと比較して「メモリ割り当てを変更する」ためです。

18
Brian Clozel

質問が見出しで示されているので、「ソースからコンパイルは..バッファオーバーフロー攻撃から保護しますか?」、一般的な答えはいいえ

ただし、ここでは、あなたの友人が何を考えていたかを推測します:現在のバージョンのGNU Cコンパイラ(GCC)は、-fstack-protectorコマンドラインフラグを使用して呼び出すと、オプションで GCC Stack-Smashing Protector を使用できます。コンパイル時に有効にする必要がある他のいくつかの手法があります。以下のUbuntuリンクを参照してください。 。私はあなたの友人がこれらの1つ以上を意味していると思います、そして彼は標準のLinux/BSDはまだこれを使っていないと仮定しました。

しかし、Linux/BSDディストリビューションがすでにこれらの手法を使用している場合は、自分でコンパイルしても役に立ちません。そして、最近の手法の多くは、何をしているのか、 buntuはサーバーエディションで行います (Stack-&Heap Protector、Header Obfuscation、5x ASLR、および4x "Built ..."の見出しを参照してください)。

最後に、すべてのソフトウェアがこれらの手法で動作するわけではありません。これを自分で行いたい場合は、とらえどころのないバグを追跡するのにかなりの時間を費やすリスクがあります。上流のディストリビューションベンダーは、これらの変更を適用するより良い立場にあり、結果のバイナリに、それらが安定していると見なすのに十分なテストと品質保証を提供します。

これらのテクニックは役に立ち、多層防御の有意義なレイヤーを追加します。ただし、これをソースからコンパイルしないでください。代わりに、優れたセキュリティエンジニアリングの考え方を持ち、必要に応じて関連する保護メカニズム(最小限の攻撃面、バッファオーバーフロー保護、おそらくSELinux/AppArmor)をすでに適用しているLinux/BSDディストリビューションを選択してください。

17
Jesper M

それはほとんど真実ではありません。 「メインストリーム」バイナリに使用されているものとは異なるバージョンのコンパイラを使用するか、異なるコンパイルフラグで使用すると、mayの結果、順序が異なりますが、ほとんどのコードが要素は同じ順序で表示されます。バッファオーバーフローの活用に関して何かを変更する限り、物事を再コンパイルすると、攻撃者にとって、物事をより困難にするのとまったく同じように、物事を簡単にすることができます。

ほとんどのバッファオーバーフローの活用は、コードアドレス(たとえば、スタック上の関数の戻りアドレス、またはどこか、特にC++のオブジェクトのvtables内の関数ポインタ)を踏みにじることにあり、攻撃者は実行を強制的に実行したい場所に移動させます。伝統的に、攻撃者はバッファを埋めたばかりのデータに実行をジャンプさせようとしましたが、実行不可能なスタック、そしてより一般的にはいわゆる W ^ X モデルはそれを成功させません:データはコードとして解釈されません。そのため、攻撃者はCライブラリ(またはOSに応じて同様のシステムライブラリ)をターゲットにします。これには、他のファイルを実行するためのNice関数が含まれています。シェル。これは推測を伴い、上記のNice関数はメモリ内にあります。結論:再コンパイルして何らかの影響を与える場合は、アプリケーションではなくCライブラリを再コンパイルする必要があります。

アドレス空間レイアウトのランダム化は、関数のアドレスを推測不可能にするための一般的な方法にすぎません。アドレススペースレイアウトのランダム化が実行ごとに再度ランダム化されるため、再コンパイルよりも完全に再コンパイルされます(実際に再コンパイルすると周りのものが入れ替わると仮定しても) )。特に、攻撃者は、実行可能ファイルのコピーを取得することによってターゲット関数のアドレスを知ることはできません。これは、そのアドレスがまだ決定されていないためです。

しかし、アドレススペースレイアウトのランダム化は厳しい制約の下で動作する必要があるため、特効薬ではありません。アライメント(通常、読み込みアドレスは4 kBの倍数でなければなりません)と断片化の問題(2 GBアドレス)のため、ライブラリをどこにも置くことができません。スペース(32ビットシステムの場合)は小さすぎて、ライブラリをどこにでも分散させることができません。これにより、大きなメモリブロックの割り当てが人為的に防止されます。

(また、「銀の弾丸」は狼男を殺す方法です。これは、あなたの薬の考えが患者を射殺している場合にのみ「理想的な解決策」です。)

バッファオーバーフローはバグです。攻撃者がアプリケーションにデータの一部を攻撃者が選択したバイトでサイレントな方法で上書きさせることができる場合、攻撃者が行うことのできるダメージにはアプリオリ制限はありません。それがJavaのような言語が発明された理由です:少なくとも、Javaでは、バッファオーバーフローで、すぐにスレッドクラッシュが発生しますnotサイレントデータ破損。

21
Thomas Pornin

[Does]「メインストリームバイナリ」を使用する代わりに、特定のコンパイルフラグを使用してアプリケーション用に独自のバイナリをコンパイルすると、攻撃者がバッファオーバーフローを利用することがより困難になりますか?

これは、オペレーティングシステム、アプリケーションの記述言語、およびコンパイラによって異なります。

まず、プログラミング言語はコンパイルされた言語でなければなりません:C、C++、C#、Java、Objective-C、Delphiなど。解釈された言語(JavaScript、PHP、Rubyなど)はソース(コンパイルされていない)から実行されるため、メモリの動作を変更するには、インタープリターの設定またはソースを変更する必要があります。明らかに、コンパイルも保護もありません。

第二に、プログラミング言語は手動のメモリ管理を可能にする必要があります。 JavaおよびC#は自動メモリ管理を使用して、基本的なバッファオーバーフローの脆弱性を防ぎます。CおよびC++では、動的メモリを手動で管理できます。プログラミング言語がメモリを管理している場合、コンパイルは役に立ちません。

3番目に、アプリケーションで使用されるコンパイラまたはライブラリは、拡張された動的メモリ管理の監視または制御をサポートする必要があります。 Microsoft C++、Intel C++、GNU C++、LLVM Clang C++コンパイラはすべて-fstack-protectorをサポートし、IBM XL C++は-qstackprotectをサポートします。AvayaLabsのLibSafeなどの一部のライブラリには、スタック:コンパイラがスタック保護をサポートしておらず、利用可能なスタック保護ライブラリのドロップがない場合、コンパイルは役に立ちません。

第4に、オペレーティングシステムはある程度の保護を提供します。一部のオペレーティングシステムは、実行可能ビット、スタックベースポインター、およびレジスターへの戻りアドレスの保存によって、スタックを既に保護しています。オペレーティングシステムが既にスタックを保護している場合、コンパイルは役に立ちません。

アドレス空間レイアウトのランダム化よりも効率が悪いのですか?

アドレス空間のランダム化は、攻撃者が既知のアドレスを使用してシステム関数を呼び出すのを防ぐ手法です。たとえば、setuid()が常にアドレス0xDEADBEEFにある場合、攻撃者は戻りアドレスを0xDEADBEEFで上書きして、setuidを実行することができます。ランダム化では、バッファオーバーフローは防止されません。静的アドレス値の使用が防止されるだけです。

この点は、OSカーネルの新しいメモリ管理戦略によって疑わしくなりますか?

必ずしも。 OSに依存します。一部のOSは、セキュリティよりもパフォーマンスを重視しています。これらのOSは、実際にはメモリ管理の手口でより多くの脆弱性をもたらす可能性があります。

8
this.josh

彼が話していることはおそらく、元のバイナリが利用可能な保護機能でコンパイルされていない特定のケースでは、それを再コンパイルして有効にすることができるということです。

現在、コンパイラとオペレーティングシステムは多くの高度なセキュリティ保護を提供していますが、アプリケーションにそれらを適用するのは開発者次第であり、それらの一部はコンパイル時に適用され、デフォルトで「オン」である場合とそうでない場合があります。

おそらく最も有名な例は、スタックベースのバッファオーバーフローからの保護です。この保護は純粋にコンパイラベースです。コンパイル時に、スタックにカナリアを追加してチェックするために、プログラムに追加の命令が追加され、特定の種類のオーバーフロー(の結果)が軽減されます。ただし、この保護は、たとえばLinuxで-fstack-protectorフラグを適用した場合、またはWindowsで有名な/ GSフラグを適用した場合にのみ追加されます。最近のオペレーティングシステムとコンパイラでは、これらのフラグはデフォルトでオンになっていますが、常にそうであるとは限りませんでした。

他のそのようなオプションは(gccの場合)-D_FORTIFY_SOURCE = 2で、特定の脆弱なglibc関数にいくつかの健全性チェックを追加し、他のいくつかのバッファーオーバーフローから保護します。-Wl、-z、relroは特定のメモリ領域を読み取り専用としてマークします。

彼が意味したかもしれないもう1つのことは、コンパイル中に他のより安全なライブラリを含めることができることです。

また、ウィンドウのDEPとASLRは、/ NXCOMPATと/ DYNAMICBASEで有効になります。現在、ビジュアルスタジオではデフォルトでこれらが有効になっていると思いますが、やはりそうではありませんでした。これらのフラグがまだ有効になっていないアプリケーションやdllの数に驚かれることでしょう-AdobeやMicrosoftのような会社によって提供されても。適例:Adobe Flashは、バージョン10でのみこれらの保護を取得していましたが、以前は有効化されていませんでした。エクスプロイトライターがエクスプロイト可能なターゲット(または特権を昇格させる方法など)を見つけようとしているときに、そのようなdllを探すのは一般的な方法です。

7
john