0

サイトでこれに関する関連記事をいくつか見つけましたが、どれも私の問題を説明していません。コードはここで説明されています: リンク

私の問題は次のとおりです。

著者は、ノートサーチ.c プログラムの strcpy() 関数の戻りアドレスをバッファー内のアドレスで書き換えて、シェルコード (メモリに埋め込まれたマシン コードであると理解しています) が実行されるようにしようとしています。

それが機能するために、彼は次のようなバッファを作成します: nop nop nop ... | シェルコード.. | 差出人住所

strcpy() 関数の呼び出し後に私が理解したことから、バッファはスタックに置かれ、戻り値を notesearch.c のメインに上書きします。strcpy() の実行が終了し、メインに戻りたいときに、バッファから戻り値を呼び出します。

私が理解していないのは、次のとおりです。

  1. 挿入されたリターンアドレスは常に元のアドレスと完全に一致しているように思えます。それはどうしてですか?

  2. 挿入された戻りアドレスは、同じバッファ内のシェルコードを指している、と本の中で述べています。シェルコードをメモリの別の部分ではなく、同じバッファに配置する必要があるのはなぜですか? それは無限ループを引き起こすことができませんでしたか?

  3. リターン アドレスをバッファのシェルコードのアドレスに設定できないのはなぜですか? それとも、その問題の変数シェルコードに?

  4. リターンアドレスがどのように計算され、なぜオフセットが必要なのか、誰でも詳しく説明できますか?

4

1 に答える 1

0

シェルコードをメモリの別の部分ではなく、同じバッファに配置する必要があるのはなぜですか?

実際には、そのメモリ領域で命令を実行できる限り、シェルコードを好きな場所に自由に配置できます。そうは言っても、この例はスタック ベースのバッファ オーバーフローを示しています。このようなエクスプロイトでは、現在のスタック フレーム内のローカル変数のオフセットを簡単に見つけることができます。

それは無限ループを引き起こすことができませんでしたか?

シェルコードにそのような無限ループが含まれていないと仮定すると、いいえ。ただし、実行フローを変更しているため、バグが発生する可能性があります。これは本当にシェルコードに依存します。たとえば、ほとんどのシェルコードはシェルを生成するために使用されます - exec 関数ファミリが使用されると仮定しましょう - シェルが生成されると、元の実行可能イメージはシェルによって上書きされます。

リターン アドレスをバッファのシェルコードのアドレスに設定できないのはなぜですか?

できます。これには、より正確な計算のみが必要です。NOP スレッドを使用すると、シェルコードの実行を可能にする複数のヒットが可能になります。

返信先住所がどのように計算されたかについて詳しく説明できる人はいますか?

作成者は、最初に宣言されたローカル変数のアドレスを取得し、脆弱なバッファへの変位を計算しました。ここでの最初の欠点は、最初に宣言された変数 ( i ) が、一度コンパイルされると最初のローカル変数ではない可能性があることです。そのような制約を確実にしたい場合、回避策は構造体を使用することです (参照:スタック上のローカル変数割り当ての順序)。

作成者はおそらくプログラムを複数回実行し、シェルコードがトリガーされるまでオフセットを調整しました。バッファの正確なアドレスの計算は、実際にはプラットフォームとコンパイラに依存することに注意してください。プログラムをデバッグし、コンパイラがスタック フレームなどをどのように処理するかを調べる必要があります。

なぜオフセットが必要なのですか?

スタック フレーム レイアウトのため、NOP スレッドにヒットするアドレスを見つけるには「有効な」オフセットが必要です。

于 2013-05-28T10:54:12.730 に答える