GCCでコンパイルされたプログラムです-fstack-protector
オプションを使用し、Linux環境でva_randomize_space
カーネル変数を1に設定して、バッファオーバーフロー攻撃から完全に保護しますか?
そうでない場合、バッファオーバーフロー攻撃を生成する一般的な手法は何ですか?
攻撃はstackオーバーフローではありませんが、bufferオーバーフローです(バッファーはスタック上にある可能性があります)。スタックは、RAMアプリケーションがローカル変数を格納し、関数の呼び出しと戻りを編成するために使用する領域です。スタックオーバーフローは、アプリケーションコードが正常に終了したときの領域です。再帰的すぎるため、スタックスペースが不足します。カーネルはスタックスペースの両端でマップされていないページを保持するため、カーネルによってSIGSEGV
に変換されたスタックオーバーフローとスタックアンダーフローのトリガートラップは、問題の無慈悲な終了を意味しますこれはバグですが、セキュリティの脆弱性ではない場合がよくあります。
バッファオーバーフローは、アプリケーションコードがバッファ(RAM内の特定の領域)への書き込みに誘導され、そのバッファに収まるよりも多くのバイト数である場合、したがって、RAMの直後、またはバッファの直前にあったものに「他の場所」のバイトの一部を書き込みます。バッファがスタック上にある場合、バッファに沿っているのは他のローカル変数です。および戻りアドレス。関数に入ると戻りアドレスがスタックスロットに書き込まれます。これは、関数が戻ったときに実行を継続する必要があるアドレスです(つまり、 call
opcodeの直後に続く呼び出し元のコードの命令)戻りアドレスを(バッファオーバーフローで)上書きすることにより、攻撃者はコードを別の場所にジャンプさせようとします。
クラシックバッファオーバーフローの時間では、攻撃者は簡単なパスを使用しました。攻撃者が選択したデータによるバッファのオーバーフロー。データ自体には、攻撃者が実行したいコード(たとえば、シェルを起動するコード)が含まれています。オーバーフローは、バッファー内のそのデータを正確に指すように、戻りアドレスを上書きするために使用されます。関数が戻ると、変更された戻りアドレスが続き、攻撃者のコードにジャンプします。
最初の保護手段は、スタック、およびおそらくRAMの残りのほとんどをnon-executableとしてマークすることです。これは データ実行防止 と呼ばれます。これは、CPUがデータバイト(攻撃者から提供されたもの)を実行可能なコードとして解釈しないようにするためです。ハードウェアはこれを区別できます(古い32ビットx86 CPUでは、完全に簡単にすることはできませんでしたが、それでも可能でした)。
反応として、攻撃者は独自のコードチャンクを挿入する代わりに、すでにRAMにあるコードを使用し始めました。標準ライブラリのいくつかの関数にジャンプする(標準ライブラリには多くの関数があり、そのうちのいくつかは攻撃者にとって非常に便利です)。標準ライブラリには、定義上、コードが含まれているため、「実行可能」とマークされ、DEPはそれに対して何も実行できません。
反応として、防御側は Address Space Layout Randomization を考案しました:これがva_randomize_space
がアクティブになります。これにより、RAMに動的にロードされたライブラリがシャッフルされるため、攻撃者はRAM標準ライブラリの場所を予測できません。ターゲットコードの場所を予測できない場合、攻撃者はそれにジャンプする時間。
反応として、攻撃者はメインの実行可能ファイル自体、または動的リンカーを標的にし始めました。どちらもアドレス空間の固定位置にあります。たまたま、ほとんどのコードチャンクが攻撃者によって悪意のあるスキームを実行するために使用される可能性があります( " Return-Oriented Programming "はそのために作成されました)。その攻撃者と防御者のダンスの次のステップを待っています。
Canaries 変更された戻りアドレスの使用を防止することにより、バッファオーバーフローの従来の悪用を打ち負かそうとします。それがstack-protector
GCCのオプションが実行します(他のいくつかのことを実行しますが、それが主な仕事です)特別なランダム化された値(「カナリア」)は、戻りアドレススロットの直前のスタックに書き込まれます。関数が戻るとき、最初に特別な値がまだあることを確認します。おそらく、オーバーフローが戻りアドレスにゆっくり到達した場合は、カナリアを上書きして変更していたでしょう。コードはそれを認識し、アドレススペースを狂ってジャンプするのではなく、アプリケーションを強制終了します。
カナリアは良いものになりますonly唯一の攻撃者のターゲットが現在の関数の戻りアドレスである場合。また、オーバーフローは nderflow ではなく、連続したバイトのシーケンスで構成され、攻撃者が「幸運にならない」と想定しています。
これらすべてのシステムのコアアイデアは次のとおりです。
バッファオーバーフローに対する本当の保護はデータのオーバーフローを許可しないことです。 ASLR、カナリア...は特定の結果に対処しますが、それはモップを使用して洪水に対抗するようなものです。バッファオーバーフローを禁止するには、2つの方法があります。