2

aslr のない x86 システムを想定して、次の質問をしたいと思います。

1) 理論によると、スタック オーバーフロー攻撃を実行すると、ebp レジスタが指す値も新しいリターン アドレスで上書きされます。

ここで、呼び出し元の関数に戻ることはないので、前のスタック フレームを復元するために ebp の元の値は必要ありませんが、ebp レジスタは常にどこかを指している必要があります。eipレジスタが新しいシェルコードを指し始めた後、ebpはどのように設定されますか? より具体的には、2 つのアセンブリ命令 (leave-ret) のどれが、ebp を値に復元するさらなるマイクロ命令を誘導しますか?

2) 最後になりましたが、シェルコードがいくつかの値をスタックにプッシュする必要がある場合に、これらの値がシェルコードのどの部分も上書きしないようにするにはどうすればよいでしょうか? 言い換えれば、シェルコードで生成された変数がシェルコードの開始前にのみ配置され、たとえばその間に配置されないことをどのように確認できますか?

よろしくお願いします。

4

2 に答える 2

3

1.関数が呼び出されると、 の値がespにコピーされ、(命令または; ;命令シーケンスを介して)ebpの値を減らすことによって、その特定の関数のスタック フレームが割り当てられます。この時点から、 の値は厳密に上向きに成長するため、現在の関数のスタック フレームに干渉しません。espENTERpush ebpmov ebp,espsub esp, SIZEesp

関数が最後に到達すると、上記の手順を逆方向に実行してスタック フレームを解放しLEAVEますmov esp, ebppop ebp; 命令シーケンス。この時点で、 の値はespリターン アドレスを指しており、これが攻撃者が変更しようとしているアドレスです。この値が変更されると、RET命令の実行時に、変更された戻りアドレスがポップeipされ、変更されたアドレスを指すようになります。

2.シェルコードより上にあるものはすべて「解放」されているため、上記と同じ手順を実行して、シェル コードにスタック フレームを割り当てるだけです。

于 2013-02-17T20:12:51.480 に答える
1

esp質問のパート 2 への回答: 作成している syscall によっては、値を(arg 配列として)入れなければならない場合があります。それがシェルコードの終わりであれば、問題ありません。ただし、シェルコードにさらに多くのことがpush あり、たまたま a を実行し、たまたまシェルコードespの残りのどこかを指している場合は、問題が発生する可能性があります (その時点で、独自の命令を上書きすることになるため)。sub $0x99, %esp簡単な修正は、シェルコードの最初の部分で何かを行うことです。

編集(コメントに応じて)

おそらく私はあなたの質問を誤解しました。あなたが「スタックオーバーフロー」と言ったとき、私はあなたがバッファオーバーフローを意味していると思いました。私が正しく仮定した場合は、読み進めてください。あなたが本当に古典的なスマッシング・ザ・スタックのようなエクスプロイトについて話していると仮定すると(リンク先の写真に基づくとそうです)、nopスレッドでバッファを埋め、shellcode最後にリターンポインタを上書きしています. シェルコードは「位置独立コード」です。これは、レジスタやフラグなどの現在の状態に関係なく実行できる一連の命令であることを意味します。

通常、(これは、投稿したリンクがそれを示している方法でもあります)、バッファーにnopを入力し、その後にシェルコードを入力し、最後にnop sledのどこかを指すリターンアドレスを入力します。ret命令が実行されると、入力されたアドレスがポップインされ%esp、 4 ずつインクリメントさ%eip%espます (x86 の場合)。問題は、シェルコードに複数の命令がある場合、これが減分pushという副作用を持つことです。それらが十分にあり、シェルコードが最後まである場合 (つまり、リターンアドレスに隣接する場合)、シェルコードを命令で上書きすることになる可能性があります。 %esppush

だから、実際にあなたの質問に答えるために。いいえ、シェルコードを「そのスタック」から分離する「メカニズム」はありません。これは、シェルコードのスタック自体がないためです。位置に依存しないコードであることを忘れないでください。マシンの状態に関係なく実行できる必要があります。必要なスタック管理は、シェルコード自体で実行する必要があります。そのため、コードに多くのステートメントがあるsub $0x99, %esp場合は、シェルコードの先頭にa を提案しました。もう 1 つのオプションは、リターン アドレス (指し示すアドレス) とシェルコードpushの間に十分なスペースがあることを確認することです。%esp-4

于 2013-02-19T03:42:58.323 に答える