web-dev-qa-db-ja.com

バッファオーバーフローの戻りアドレスの前にシェルコードを配置する必要があるのはなぜですか?

バッファオーバーフローの戻りアドレスの前にシェルコードを配置する必要がある理由を知りたいのですが。論理的には、戻りアドレスはシェルコードを指し、実行されるため、戻りアドレスはシェルコードの前に置く必要があります。誰かが私を説明できますか?

2
Scoobydoo

定義上、バッファオーバーフローはバッファをオーバーフローする必要があります。これは、最後に戻りアドレスを上書きするためです。

これにより、シェルコードをドロップするのに便利な場所が得られます。後で追加しようとすると、別のメモリアドレスが上書きされ、プログラムが別の方法でクラッシュする可能性があります。

したがって、戻りアドレスの前にシェルコードを追加すると、戻りアドレスを書き込んで、以前に記述したシェルコードへのジャンプをトリガーできます。要約すると、オーバーフローしているバッファは、多くの場合、別の重要なメモリを上書きせずにシェルコードを書くのに最適な場所です。

2
SilverlightFox

バッファオーバーフローエクスプロイトのリターンアドレスの前にシェルコードを配置する理由は、いくつかの要因に依存します。

  • バッファのサイズ
  • お申し込みの流れ
  • 単純なバッファ+リターンアドレスを超えるトリックでは、相対ジャンプを行う必要があるなど、いくつかの巧妙さが必要になります

バッファオーバーフローの一般的な例は次のようになります。

"\x41"*1000 + "\xe7\x51\x78\xa2" + "\x90"*16 + "[shellcode]"

ここでは、バッファを1000 Aでオーバーフローさせ、EIPを制御して選択した場所を指すことができる場所に着陸させた後、いくつかのNOPを使用してシェルコードの部屋を展開し、最終的に実行可能コードを作成しました。これは比較的簡単なエクスプロイトです。通常、戻りアドレスはJMP ESP命令であり、これはたまたまNOPスレッドの先頭にあります。スレッドはシェルコードに到達するまで機能します。スタックが大きくなるため、スレッドは上書きされます。解凍してNOPスレッドを実行すると、実行されます。

ただし、そのようなエクスプロイトパスがなく、別の方法をとる必要がある場合もあります。

"\x90"*16 + [shellcode] + "\x90"*400 + [return address] + "\x90"*5

ここでは、単純なJMP ESPが不可能なため、シェルコードを最初に配置する必要があります。代わりに、最初にジャンプして実行できるようにする別の命令を見つける必要があります。次に、リターンアドレスの両端にパディングがあります。

詳細は明かさずに、答えは「場合によります」です。これは、特定の状況、エクスプロイトでの作業内容、使用する部屋、および問題のアプリケーションの動作によって異なります。

2
user79537