10

この 2 種類の攻撃の正確な違いを理解したいと思います。私が読んだことから:

バッファ オーバーフロー: スタック上の ret アドレスを上書きして、悪意のあるコードが挿入されているコードの別のセクションを指します。つまり、実際に攻撃を実行するには、プログラムのソース コードを変更する必要があります。

Libc に戻ります。ここでは、ソース コードを変更する代わりに、C ライブラリによって提供されるランタイム関数呼び出しが使用されます (つまり、シェルを開きます)。ここで、関数呼び出しに使用されるパラメーターも上書きバッファーに渡され、スタックの ret 部分の後に終わります。

上記は正確な説明ですか?

関連するもう 1 つの質問 - 元のプログラムのソース コードを実際に変更することなく、バッファ オーバーフロー攻撃を実行することは可能でしょうか? おそらく、新しいプログラムを作成し、メモリの特定のセクション (元のプログラムの破損したスタック内の新しい ret アドレス) を変更できるようにする場合です。繰り返しになりますが、カーネル内のプロセス間で提供されるメモリ保護のために、これは不可能かもしれないと思います。

4

4 に答える 4

12

古典的なバッファ オーバーフロー エクスプロイトでは、オーバーフローするスタック バッファは、実行されるマシン コード (通常はシェル プロセスを呼び出すため、シェルコードと呼ばれます) と新しいリターン アドレスの両方で満たされていました。新しい戻りアドレスは、オーバーフローしたスタック バッファ自体内を指すように細工されます。明らかに、これには、攻撃されたプロセスのスタック バッファのアドレスを知るか推測する必要があります。

当時、プロセスのメモリ レイアウトは通常、非常に決定論的でした。通常、スタック バッファの場所は、攻撃者によってかなり正確に予測できました (特に、攻撃対象のソフトウェアのバージョンが正確にわかっている場合)。当て推量が含まれている場合に成功の可能性を高めるために、アクティブなシェルコードの前に、「NOP スレッド」または「NOP スライド」と呼ばれる、有用な操作を実行しない大量の実行可能なマシン コードが先行することがよくあります。 「操作なし」を実行する機械語命令の典型的な名前です。NOP スレッドの任意のポイントに戻ると、望ましい効果が得られます。

一方、「return-to-libc」エクスプロイトでは、ハイジャックされたプロセスがシェルコードに直接戻ることはありません。代わりに、プロセスが 1 つずつライブラリ関数のチェーンの先頭に戻ります。これらのライブラリ関数は、攻撃者が望む操作を直接実行する可能性がありますが、より一般的には、攻撃者のシェルコードを間接的に実行するために使用されます。

于 2011-09-05T05:07:05.230 に答える
4

バッファ オーバーフローは一種のプログラミング エラーであり、libc への復帰は悪用手法であると言えます。概念を混同しないことをお勧めします。

たとえば、return to libcを使用してバッファ オーバーフローの脆弱性を悪用できます。または、 return to .textreturn to shellcodeなどの他の手法を使用することもできます。逆に、return to libcを使用して、フォーマット文字列などの他のバグを悪用することもできます。

于 2011-09-05T05:16:14.913 に答える
4

ret アドレスを上書きする部分は、両方の攻撃で共有されます。上記の返信が示すように、以前は、作成したアセンブリ コードに単純に戻るだけでした。このアセンブリ コードは、ルート ユーザー シェルを生成します。

どちらの攻撃でも、ソース コードを「上書き」することはありません。アセンブリの観点から見ると、ソース コードは .text セグメントにあり、常に (または少なくとも私が知っている限り) 書き込み保護されています。以前は、メモリ セグメントにアセンブルしたコードを記述し、そのコードにジャンプするという方法を利用していました。コードは通常、「スタック セグメント」内またはその近くに配置されており、オーバーフローすることを選択したものは何でもオーバーフローすることで、(たとえば) そこの ret アドレスからトラフィックをリダイレクトします。他の攻撃の場には、以前に作成してシェルコードを入力した環境変数が含まれていました。またはヒープ、関数ポインター、または PLT も。このように挿入されたコードは、通常、必要なものを実行するために system() 呼び出しを使用しますが、そのためには「実行」できる必要があります。

2 つの攻撃の違いは、メモリの大部分が実行不可能になると、攻撃タイプ a (スタック オーバーフロー) がかなりうまくいかないことです。このタイプの攻撃を回避する試みは、あなたが書いているように、代わりに共有ライブラリ関数に直接アクセスすることでした-別名、最初にコードをスタックセグメントまたは他の場所に書き込んでそこで実行する必要がなくなりました。ただし、libc タイプの攻撃も、現在では大部分がパッチされていると思います。詳細は手元にありません。そして多分私は間違っています。

これらの攻撃が最近どのように阻止されているかを確認したい場合、または少なくともいくつかの重要なアイデアについて読みたい場合は、Google で「2011 年 (または 2010 年) のスタックの破壊」を検索してください。

于 2011-09-05T01:30:08.453 に答える
0

実際、バッファオーバーフロー攻撃では、ret ポインタをオーバーライドしながら悪意のあるコードを挿入します。このために何も変更する必要はないので、結論として、前述の両方の攻撃の違いはわかりません。

例えば:

char* str[5];
cin << str;

これは爆発する可能性のあるコードです。ユーザーが 5 文字を超える文字列を挿入すると、後続のスタック上のすべてが上書きされます。また、ret-ptr がスタック上で「より低い」という事実により、適切な距離が得られればオーバーライドできます。オーバーライド中の意図は、ret-ptr が呼び出されて「ジャンプ」が実行されるとすぐに実行される、悪意のある (アセンブラー) コードを挿入した入力の先頭を指すようにすることです。

于 2011-09-05T00:12:16.367 に答える