web-dev-qa-db-ja.com

なぜスタックに直接ジャンプするのではなく、JMP ESP

まず、この投稿が正確にここに収まらない場合、またはREに適している場合があります。必要に応じて移動できます。

それで、私はこれを読んでいました writeup vulnserverの悪用について(それを知らない人のために、vulnserverは欠陥を念頭に置いて設計されたプログラムであり、これは悪用手法を実践するためです)

ある時点で、それは言う:

このステップでは、レジスタとスタックを確認する必要があります。コードを実行するためにバッファにジャンプする方法を見つける必要があります。 ESPは、バッファのC部分の先頭を指します。JMPを見つける必要がありますESPまたはCALL ESP指示。アドレスに不正な文字が含まれていてはならないことを忘れないでください!

これは理にかなっていますが、 EIPを制御しているので、スタックに直接ジャンプすることは不可能で簡単ではないでしょうか? (もちろん、ASLRとDEPは無効になっていると想定しています)。主な理由:

  1. ESPが自分のシェルコードを指しているのはなぜですか。なぜESPが正確にそこを指しているのですか?代わりに自分のシェルコードの最後を指しているべきではありませんか?

  2. これはどのように再起動または別のコンピューターで機能するはずですか?

ありがとう。

スタックのバッファをオーバーフローさせているため、エクスプロイトペイロードはスタックに残ります。これにより、リターンアドレスも制御できるようになります。

スタック上の戻りアドレスを上書きする4バイトの直後にペイロードを配置するため、ESPは(攻撃対象の関数でretを実行した後)ペイロードの先頭を直接指します。 retは4(または8)バイトをEIPにポップし、ESPが直接続くペイロードを指すようにします。

しかし、その値がわからないESPがその時点で持つ、スタックASLRと異なるこの時点までの呼び出しスタックの深さはアドレスを変更する可能性がありますしたがって、正しい戻りアドレスをハードコードすることはできません。

ただし、プロセスのメモリ内の固定(ASLRされていない)アドレスのどこかにjmp espまたはcall espとしてデコードされるバイトがある場合、エクスプロイトの戻りアドレスとしてthatアドレスをハードコーディングできます。実行はそこに行き、次にペイロードに行きます。

これが実際によくあるケースです。一部のDLLでは、コードに対してASLRが有効になっておらず、メインの実行可能ファイルのコードもASLRされていない場合があります。

allのコードASLRは、攻撃者がターゲットプロセスにアドレスをリークさせない限り、jmp esp攻撃を無効にします。

64ビットコードの場合、文字列ベースのバッファオーバーフローにjmp rspを使用できない可能性があることに注意してください コードアドレスには先頭に0バイトが含まれるため


したがって、jmp espは、(非常に大きなNOPスレッドを使用して)リターンアドレスを繰り返し推測するよりもはるかに信頼性の高いエクスプロイトを提供します。

推測を繰り返すと、間違っているたびにターゲットプロセスがクラッシュしますが、jmp espを使用すると、最初の試行で成功する可能性が高くなります。これにより、クラッシュログが残されなくなります。また、クラッシュするサーバープロセスを探し、IPアドレスなどからの接続をブロックする侵入検知システムを無効にすることもできます。


探している2バイトの命令は、プログラムが正常に実行されたときに別の命令の一部として、または静的データ(特に、読み取り専用データが実行可能ページにあることが多い)として表示される可能性があることに注意してください。したがって、プログラムの逆アセンブリでは、jmp espではなく、2バイトのシーケンスを検索するだけで済みます。コンパイラーがjmp espを使用することはないため、その方法でコンパイラーを見つけることはできません。


より一般的には、任意のレジスタのバッファポインタで終了する関数(たとえば、memcpyまたは特にstrcpyから) )は、jmp eax命令を探すことで、ret2reg攻撃を許可できます。

これは64ビットモードで機能します。このモードでは、アドレスに高位のゼロバイトがあります。 strcpyの後続ゼロがその上位アドレスバイトを書き込む場合、エクスプロイト文字列の終わりは、スタック上の戻りアドレスを上書きするゼロ以外のアドレスバイトである可能性があります。

この場合、実行可能ペイロードはbefore関数がレジスターポインティングを残しているバッファー内のスポットに戻りアドレスになります。 (通常、レジスター内のバッファーへの有用なポインターがある場合は、バッファーの先頭)。

10
Peter Cordes

バッファーがオーバーランすると、ESPにシェルコードが含まれます。イミュニティで確認できます。EIPはESPをポイントする必要があります。私の理解は、悪用の前に、システムDLLはESPを使用する必要があります。 DLLが呼び出されたとき。

しかし、バッファーがオーバーフローした後、EIPはどこを指すべきかわからなくなります。 EIPに渡す4バイトは、[jmp ESP]アドレスのいずれでもかまいません。

だからそれはこのようになります-

  1. EIPまで正確にバッファーをオーバーフローさせる
  2. [jmp ESP]アドレスをEIPに渡す
  3. ESPに保存された値が実行されます(NOP +シェルコード))

私はエクスプロイトを作成し、[jmp ESP]でアドレスのバリエーションを使用し、毎回この脆弱性を悪用する可能性があります。

これがexploit.pyです。RPCRTdllを使用していることに注意してください。ただし、Shell32.dllやその他のシステムdllも使用できます。

https://github.com/shankar-ray/Exploit-Development/blob/master/exploit-py

私はいくつかの追加のNOPでShell bind shellcodeを使用しています。

ところで、OSになんらかの保護機能があるか、コンパイラが元のsrcコードのコンパイル中に保護機能を追加した場合。これは、シェルコードの場所を見つけるための宝探しになります。シェルコードに到達するには、いくつかのジャンプを使用する必要があります。

お役に立てば幸いです。

4