4

私は現在、コンピューターシステムの紹介を読んでいます:プログラマーの視点-2&keywords=introduction+to+computer+systems ) を参照し、バッファ オーバーフローを阻止する方法を理解しようとしています。

アドレスのランダム化が使用されるときに NOP スレッドが必要な理由とエクスプロイトの作成方法は理解していますが、本に記載されている NOP スレッドに関連するアドレス計算を理解するのに苦労しています。ここに引用します:-

(スタック上のプログラムの開始アドレスの範囲が、32 ビット システムでは 2^23、64 ビット システムでは 2^32 であると仮定します)

「256 バイトの NOP スレッドを設定した場合、n=2^23 のランダム化は、2^15 の開始アドレスを列挙することでクラックできます。これは、断固たる攻撃者にとって完全に実行可能です。64 ビットの場合、2^ を列挙しようとしています。 24 のアドレスはもっと大変です。」

著者は、32 ビットと 64 ビットの場合、それぞれ 2^15 と 2^24 という数字をどのように思いついたのでしょうか? 説明は本当に役に立ちます。

4

2 に答える 2

2

彼らは、32ビットシステムでの最大合計共有メモリ(キロバイト)を想定しているだけ8388608です。これは、彼らが思いついた場所です2^23

2^15次のように計算されます。

(8388608 / 256) = 32768 == 2^15

言い換えれば:

total_memory_size / NOP_sled_length = total_iterations_to_find_NOP_sled_in_memory

0x0彼らは、NOP スレッドがから0x800000(8388608または)までの範囲内のどこにでもあるという仮定に基づいて計算しました2^23。NOP スレッドの長さは 256 バイトであるため、推測/反復/ブルート フォースごとに 1 ずつインクリメントする必要はありませんが、代わりに、上記の式の結果を得るたびに 256 ずつ増加してカウントします0x800000 / 256 = 32768 == 2^15。したがって、32768 個の可能なアドレスをブルート フォースするだけで済みます。これらのアドレスの 1 つが NOP スレッドの開始点に着陸し、ペイロードまでずっと下にスライドするからです。

NOP スレッドが 500 バイトである場合 (エクスプロイトにより、そのサイズの NOP スレッドに適合できると仮定すると)、式は次のようになります。

0x8000000 / 500 = 268435NOPスレッドの開始アドレスを見つけるための反復。

このアプローチが 64 ビット システムに適していない理由は、次の式によるものです。

2^32 / 256 = 16,777,216(NOP スレッドが開始できる可能性のあるアドレスは 1600 万以上あります! NOP スレッドが 500 バイトで、500 で割ったとしても、NOP スレッドが開始できるアドレスは 850 万以上あることになります!)

0000
0000
NNNN
NNNN
NNNN
PPPP
PPPP
PPPP
0000
0000

上記が私のスタックだと想像すると、合計メモリ サイズは 40 です。12 バイトの NOP スレッド (N) と 12 バイトのペイロード (P) があります。したがって、この悪用可能なシナリオの方程式は次のようになります。

40 / 12 = 3NOP スレッドが (12、24、32 または 16 進数の 0x0c、0x18、および 0x20) で見つかる可能性のある 3 つのアドレスを、できるだけ少ない試行回数で提供します。

したがって、エクスプロイトがスタックの先頭から開始され、12 ずつカウントされる場合、最初の試行で NOP スレッドが検出されます (4 バイトが NOP スレッドに着陸します)。

コメントに基づく更新:

アドレスのランダム化のためのバイパス手法に関する NOP スレッドの背後にある考え方は、NOP スレッドの開始を推測することではありません。NOP スレッドに到達するアドレスの推測が少なくなることを保証する最小量のアドレス を計算することです。 /ブルートフォースを可能な限り。もちろん、NOP スレッドの開始点を見つけたい場合は、次の式を使用できます。

total_mem_size / NOP_size = least_amount_of_guesses_to_land_inside_payload + 1

ただし、try に余分なアドレスを追加することで、ペイロードを実行する前に推測するアドレスの最小量を計算しているわけではないことに注意してください(これは、私とあなたが読んでいる本が計算しているものです。 NOPそり)。

上記の小さな「スタック」を再検討すると、NOP スレッドを開始できる合計 4 つのアドレスが存在する可能性があることは事実ですが、式は NOP スレッドを見つけることが保証されている 3 つのアドレスを計算します (可能な限り少ない推測で、鍵)。より明確にするために、エクスプロイトの開発者は、NOP スレッドのサイズを (可能な場合は) 大きくすることによって、この数をできるだけ小さくしようとするので、NOP スレッドの開始点を見つけることを心配する必要はないと言えます。彼らはNOPそりの中に着陸したいだけです。

インデックスの推測により12、NOP スレッドに 4 バイトが着陸し、ペイロードに到達する前に実行する NOP は 8 つだけになります。インデックスの推測により24、ペイロードに数バイトが着陸し、クラッシュが発生し、インデックスの推測により32、ペイロードを超えて着陸し、クラッシュも発生します。

(合計4つのアドレスを使用する)アプローチを使用して、余分なアドレスが式で考慮されていない理由を示しましょう:

0000
0000
NNNN
NNNN
NNNN
PPPP
PPPP
PPPP
0000
0000

前と同じスタック レイアウトを持つ 4 つの可能なアドレスを与える方程式に 1 を追加しましょう。

40 / 12 = 3 + 1 = 4

これで、NOP スレッドにブルート フォースで着陸するための 4 つのアドレスができました0, 12, 24, 32。12 バイトの NOP スレッドがあるため、シェルコードの先頭でシェルコードの実行を開始できるようにする NOP スレッドに到達するアドレス (元の式で見つかったインデックス 12 のアドレス) は 1 つだけです。インデックス 0 は、NOP スレッドの前に制御していないデータのスタックに着陸します。したがって、ミックスにアドレスを 1 つ追加しても、NOP スレッドを見つけるのに役立ちません。試行/ブルート/推測するアドレスの量が増えるだけです。

はい、あなたは正しいです-私は例がより理にかなっているためにより直感的なアドレスをインクリメントしていますが、実際の実行中にスタック上のアドレスを「カウント」または「インクリメント」すると、上位アドレスから開始されます。

于 2015-01-25T21:49:13.423 に答える
0

これが役立つかどうかわからない:

32 ビット システムの場合、NOP スレッドが 256 バイト (つまり 2^8) で、スタックの範囲が 2^23 バイトの場合、必要なのは 2^15 インスタンス (つまり 2^23 / 2^8 = 2) だけです。 ^15) (重複しない) スレッドの。

64ビットシステムでも同じです

于 2015-01-19T06:12:12.310 に答える