web-dev-qa-db-ja.com

リターン指向プログラミング:system()のアドレスにNULLバイトが含まれています

免責事項:私はこの質問を教育目的でのみ行っています。

strcpy()を使用する脆弱なバイナリを利用して、リターン指向のプログラミングを使用していくつかの関数呼び出しを連鎖させようとしています。これらの関数呼び出しの1つは、system()への呼び出しでなければなりません(シェルコマンドを実行するため)。残念ながら、system()のアドレスにはNULLバイトが含まれているため、このバイトが確認されるとstrcpy()がペイロードのコピーを停止します。

したがって私の質問は、この問題を解決するための最良のアプローチは何ですか?

Libcでsystem()に類似した関数を確認しましたが、何も見つかりませんでした。私の別のアイデアは、fork()exec()、およびwait()を後で呼び出すことです。ただし、これによりペイロードの複雑さが増します。

2
foobar

シェルコードの実行時に元のプロセスを残しておく必要がある理由はありますか?直接execveを呼び出すだけで(スタックを十分に制御できる場合)、または そのヘルパー関数の1つ を呼び出すと、現在のプロセスがターゲットプロセスになります。

うまくいくかもしれないよりトリッキーなアプローチは、dlsymを使用してsystemへのポインターを取得することです。これは、ターゲットコマンドで呼び出すことができます。ただし、mightは最初にdlopenを呼び出す必要があります。 dlsymのセマンティクスはわかりません。対応するWindows関数GetProcAddressは、ロードされたモジュール(ライブラリーまたは実行可能ファイル)のベースアドレスを最初のポインターとして使用します。dlsymでも同じことができます。 ROPを使用しているため、おそらくASLRに悩まされることはなく、アドレスは予測可能です。

最後に、ROPを使用しているため、目的のアドレスを算術的に生成できる1つ以上のガジェットを見つけることができます。特定の値を生成するために使用できるオペランド(エクスプロイト時の既知の値を持つシェルコード、レジスターまたはアドレスの定数など)と操作(加算、減算、またはxorなど)の多くの組み合わせがあります。 1つを含まない部分からのNULLバイトが含まれ、ALU演算が短いため、適切なガジェットを見つけるのは難しくありません。

1
CBHacking