この質問は主に、バッファ(スタックなど)のオーバーフローでの任意のコマンド実行のコンテキストにあります。
私は最近、どこかにハードワイヤード(絶対)アドレスがnot goodであることを読みました。たとえば/ bin/shを使用します。問題は、コードが位置に依存しないことを意味することです。
ただし、固定アドレスが相対アドレスよりも好ましくない理由がわかりません。ハードワイヤードアドレスは、攻撃で使用される目的のライブラリ/呼び出しがコード(つまり、位置に依存しない)のどこからでもアクセスできることを意味しませんか?
相対アドレスは常にハードコードされたアドレスよりも優先されます、なぜですか?説明させてください:
あなたが混乱させるかもしれないと思う問題には2つのタイプがあります。 1つは、脆弱なアプリケーションまたは読み込まれたライブラリによって提供されるシェルコードによって呼び出される関数のアドレスであり、もう1つは、シェルコード内の絶対ジャンプと相対ジャンプです。
少しの間、単純なバイナリでlibcに戻るスタイルのエクスプロイトを試みているとしましょう。そのため、このようなエクスプロイトの多くにはsystem
のアドレスが必要です。 system
のアドレスを出力する小さなバイナリを作成してみましょう。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
printf("system @%p\n", system);
return 0;
}
これを数回コンパイルして実行します。
% gcc -o getsystem getsystem.c
% ./getsystem
system @0x7fdc54419d40
% ./getsystem
system @0x7fbc15b61d40
% ./getsystem
system @0x7fbeacfb6d40
実行されるたびに、system
のアドレスが変更されていることに注意してください。これは、ASLRと呼ばれる最新のセキュリティ緩和策によるものです。Cライブラリは別のベースアドレスに読み込まれるため、system
は別のアドレスに読み込まれます。したがって、シェルコードは最初にlibcを見つけてから、ライブラリの先頭からの相対アドレスでsystem
を呼び出す必要があります。 (「ベースアドレス」と呼ばれます。)
より複雑なシェルコードでは、ペイロード自体にjmp
またはcall
を作成する必要がある場合があります。このような場合、シェルコードがロードされる正確なアドレスがわからないため、必須には相対的なジャンプと呼び出しが必要です。 「0x0804abcd
にジャンプ」の代わりに、「5バイト先にジャンプ」する必要があります。これは、「位置独立コード」が意味するものです。固定された開始アドレスだけでなく、任意の位置にロードされたときに動作できます。
シェルコードは通常スタックまたはヒープにロードされ、どちらもさまざまな操作(ASLR、スタック/ヒープを使用するその他のデータ、スレッド化など)の影響を受けるため、シェルコードが到達する絶対アドレスを予測することは不可能です。