私は、任意の変更されていない、信頼されていないバイナリを実行できるサンドボックスの設計について考えています。目標は、アプリケーションを実装することです
例えばのようなものとは異なりGoogle Chromeのサンドボックスは、Windowsに組み込まれたセキュリティメカニズムでは提供できない分離を提供する必要があります。ただし、1台の物理マシンで多数のサンドボックスを実行できるはずなので、本格的なVMは問題外です。
これは次のように機能するはずです。信頼されていないコードによるシステムコールは、最初にサンドボックスコードによってインターセプトされ、システムに渡される前にブロックまたは変更できるようになります。サンドボックスは、必要に応じて高レベルAPIをフックできるようにする必要もあります。信頼できないコードは、サンドボックスコード(インポートされたライブラリを含む)とデータ(スタックとヒープ)を調整できないようにする必要があります。ただし、サンドボックスコードには、サンドボックス化されたコードのアドレス空間へのフルアクセスが必要です。
これらの制約を考えると、サンドボックスに含まれるカーネルモードコードが(セキュリティとテスト容易性の懸念から)可能な限り少ない場合、それは可能な限り単純で(バイナリ変換のようなスタントはありません)、サンドボックス化されたコードは合理的に実行されます。速い。
サンドボックスは自分のサーバーで実行されるため、基盤となるOSでの調整は許容され、Windowsの異なるバージョン間の移植性は難しい要件ではありません。ターゲットアーキテクチャはx86です。64ビットのサポートは重要ではないため、セグメンテーションの使用は許可されています。ただし、VM内で実行できる必要があります。そのため、可能であればハードウェア仮想化はありません(VT-xまたはそれと同等のAMD)。
このようなサンドボックスをどのように実装しますか?このようなサンドボックス設計は文書化されていますか?見落とした重要なポイントはありますか?これらの要件を考えると、あなたはすでに合理的なアイデアを持っているかもしれませんが、私がどのようなデザインを考えていたかは分かりますが、私はどんなアイデアにもオープンです。
編集:目標は、仮想化されたアプリケーションがそこから抜け出すことができないアプリケーション仮想化レイヤー( http://en.wikipedia.org/wiki/Application_virtualization を参照)を提供することです。
優れたシステムコールであるかどうかを判断するための全体的な設計を示唆する回答に同意します。実際、単独では、単一のシステムコールでは十分な情報ではない場合があります。
Windowsの動作に関しては、実際には2つのレベルの操作があります。
ntdll.dll
、つまりカーネルモードルーチンでコーディングするためにsysenter
を介して期待する典型的なシステムコールです。advapi32.dll
、kernel32.dll
、user32.dll
などで実装されている関数です。これらの一部は直接動作しますが、必要なものに応じて、上記の関数自体を呼び出すものもあります。これに加えて、広範な調査として、Win32サブシステムの上に2つの抽象化レイヤーがあります。
mscoree.dll
に読み込まれる変更されたPEバイナリであり、他の.netバイナリ、Win32、またはCOMインターフェイスを介してAPIを使用する場合があります。これで、フッキングテクニックとして、次のことができます。
LD_PRELOAD
として認識されます。プレーンな英語では、同じ名前のDLLを読み込み、目的のAPI dllの前に一致する記号を付けて、呼び出しを盗みます。そのように。 MSVCの機能でさえ、気にしないもののために独自のスタブを実装する必要がなく、DLLでリダイレクトされたリンク関数を生成できます。したがって、基準を満たすサンドボックスを実装する場合は、考慮すべき考慮事項がいくつかあります。
kernel32.dll
をフックしても、これらの関数を呼び出さない場合、API呼び出しが回避できる可能性があります。このようなCOMまたは.netコードは知りませんが、いくつかあると思います。CreateFile
を選択してみましょう。信頼できないコードは、この関数のメモリを単に読み取り、プロローグが期待どおりであることを確認できます。同様に、注入されたDLL、IATフックなどを検出する方法があります。この種の作業は完了しました。Sandboxieは、この種のレベルでサンドボックスを実装しようとする製品の1つですが、カーネルレベルが必要以上に多い可能性があります。私がこのようなことについてあまり知らなかったときは、Sandboxieを少しだけ見返しましたが、コアコンポーネントはカーネルレベルであると思います。ユーザーモードのフックのほとんどすべてが期待どおりに元に戻せるためです。唯一の防御策は、より高いレベルの許可を得ることです。
バイナリ変換がないとのことですが、このため、WindowsのさまざまなデバッグAPIについては説明していません。これらを使用すると、プログラムをステップ実行する場合と同じように基本的にプログラムを実行し、呼び出しやジャンプが行われる前にそれらを分析できます。ただし、これは基本的にバイナリ変換であり、デバッグはどのような場合でもパフォーマンスに影響します。それだけでなく、サンドボックスに抵抗するプログラムを作成している場合、デバッガーを検出するためのいくつかの既知のトリックがあります(1つはデバッガーをデバッグできないため、再起動して新しいプロセスをデバッグしようとすると、これは間違いなくptrace
)に適用され、プログラムをサンドボックスで使用できなくなります。
肯定的な点としては、ほとんどのマルウェア以外の製品は、おそらくこれらの環境での実行に抵抗しようとしないため、使用した手法のセットでうまく機能するでしょう。これは非常に役立つ事実です。
最後になりましたが、箇条書きを過度に使用したことをお詫び申し上げます。そして、呼び出しをフックするためのテクニックの私のリストは完全ではありません-間違いなく他のものがあります。
Windows用のオープンソースのサンドボックス実装であるFeatherweight Virtual Machineを見つけました。
http://static.usenix.org/events/vee06/full_papers/p24-yu.pdf
http://sourceforge.net/projects/fvm-rni/
デューンも興味深いです:
VT-xを使用してLinuxで説明したように、概念実証のサンドボックスを実装します(残念ながら、ほとんどの仮想マシンでは機能しません)。
あなたの計画は、システムコールのある種のスクリーニングによって「悪い」動作を特定できるという欠陥のある仮定に基づいています。できません。 Windowsには、バグ、隠れた機能、および公開されていない依存関係がたくさんあります。提供しなかった他のコードに制御を渡すとすぐに、承認したことだけが実行されるという保証はありません。