web-dev-qa-db-ja.com

シェルコードのハードアドレスと相対アドレス

この質問は主に、バッファ(スタックなど)のオーバーフローでの任意のコマンド実行のコンテキストにあります。

私は最近、どこかにハードワイヤード(絶対)アドレスがnot goodであることを読みました。たとえば/ bin/shを使用します。問題は、コードが位置に依存しないことを意味することです。

ただし、固定アドレスが相対アドレスよりも好ましくない理由がわかりません。ハードワイヤードアドレスは、攻撃で使用される目的のライブラリ/呼び出しがコード(つまり、位置に依存しない)のどこからでもアクセスできることを意味しませんか?

3
Sean Frötkék

相対アドレスは常にハードコードされたアドレスよりも優先されます、なぜですか?説明させてください:

  • 終了または再起動後にアプリケーションを再度実行すると、メモリ内の同じアドレスにロードされない場合があります
  • ASLR-アドレス空間レイアウトのランダム化-同じ空間に実行可能ファイルをロードしないOSシステムのセキュリティ機能...これは、アドレスが毎回異なるため、ハードコードされたアドレスが機能せず、毎回それを変更するのは本当に不便であり、機能するだけです。
  • たとえば、jmp [アドレス]の代わりに特定のアドレスにジャンプしたい場合は、jmp ecx + 8などのレジスターに相対的であることが常に適切であり、アドレスが変更されても変更されません。
1
Nipun Jaswal

あなたが混乱させるかもしれないと思う問題には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、スタック/ヒープを使用するその他のデータ、スレッド化など)の影響を受けるため、シェルコードが到達する絶対アドレスを予測することは不可能です。

1
David