web-dev-qa-db-ja.com

Windows用のサンドボックスの設計

私は、任意の変更されていない、信頼されていないバイナリを実行できるサンドボックスの設計について考えています。目標は、アプリケーションを実装することです

例えばのようなものとは異なりGoogle Chromeのサンドボックスは、Windowsに組み込まれたセキュリティメカニズムでは提供できない分離を提供する必要があります。ただし、1台の物理マシンで多数のサンドボックスを実行できるはずなので、本格的なVMは問題外です。

これは次のように機能するはずです。信頼されていないコードによるシステムコールは、最初にサンドボックスコードによってインターセプトされ、システムに渡される前にブロックまたは変更できるようになります。サンドボックスは、必要に応じて高レベルAPIをフックできるようにする必要もあります。信頼できないコードは、サンドボックスコード(インポートされたライブラリを含む)とデータ(スタックとヒープ)を調整できないようにする必要があります。ただし、サンドボックスコードには、サンドボックス化されたコードのアドレス空間へのフルアクセスが必要です。

これらの制約を考えると、サンドボックスに含まれるカーネルモードコードが(セキュリティとテスト容易性の懸念から)可能な限り少ない場合、それは可能な限り単純で(バイナリ変換のようなスタントはありません)、サンドボックス化されたコードは合理的に実行されます。速い。

サンドボックスは自分のサーバーで実行されるため、基盤となるOSでの調整は許容され、Windowsの異なるバージョン間の移植性は難しい要件ではありません。ターゲットアーキテクチャはx86です。64ビットのサポートは重要ではないため、セグメンテーションの使用は許可されています。ただし、VM内で実行できる必要があります。そのため、可能であればハードウェア仮想化はありません(VT-xまたはそれと同等のAMD)。

このようなサンドボックスをどのように実装しますか?このようなサンドボックス設計は文書化されていますか?見落とした重要なポイントはありますか?これらの要件を考えると、あなたはすでに合理的なアイデアを持っているかもしれませんが、私がどのようなデザインを考えていたかは分かりますが、私はどんなアイデアにもオープンです。

編集:目標は、仮想化されたアプリケーションがそこから抜け出すことができないアプリケーション仮想化レイヤー( http://en.wikipedia.org/wiki/Application_virtualization を参照)を提供することです。

7
Maarten

優れたシステムコールであるかどうかを判断するための全体的な設計を示唆する回答に同意します。実際、単独では、単一のシステムコールでは十分な情報ではない場合があります。

Windowsの動作に関しては、実際には2つのレベルの操作があります。

  • NTレベルの呼び出し。これらは、ntdll.dll、つまりカーネルモードルーチンでコーディングするためにsysenterを介して期待する典型的なシステムコールです。
  • Win32サブシステムレベル。これらは、advapi32.dllkernel32.dlluser32.dllなどで実装されている関数です。これらの一部は直接動作しますが、必要なものに応じて、上記の関数自体を呼び出すものもあります。

これに加えて、広範な調査として、Win32サブシステムの上に2つの抽象化レイヤーがあります。

  • COM、COM、COM +、DCOM、ActiveX、SuperDuper(大丈夫、冗談)などとも呼ばれる友達。
  • .Netと友達。 .net実行可能ファイルは、とりわけmscoree.dllに読み込まれる変更されたPEバイナリであり、他の.netバイナリ、Win32、またはCOMインターフェイスを介してAPIを使用する場合があります。

これで、フッキングテクニックとして、次のことができます。

  • カーネル。最近、ISRフッキングは、PatchGuardをリバースエンジニアリングして無効にするか、デバッガーでOSを永続的に実行している場合を除いて、安定自殺と同じです。ただし、Windowsに実装されているフィルタリングのオプションがあり、 Filter Drivers によって提供されます。これは通常、ウイルス対策製品がネットワークアクティビティをスキャンしてファイアウォールを実装する方法です。
  • ユーザー。ここにはいくつかのオプションがあります:
    • 起動時にバイナリにパッチを適用します。 @Polyはコードの洞窟とリダイレクトについて話しました-ターゲットバイナリが与えられた場合、1つのオプションはその関数のコードを上書きするか、コードにリダイレクトする興味深いAPIの関数を上書きすることです。通常、アドレススペース内の古い場所へのジャンプにパッチを適用するための十分なスペースがないため、呼び出し/フルサイズのジャンプを配置するには、関数の近くに「コードケイブ」が必要です。
    • これに代わる方法として、IATフッキングがあります。これは、バイナリのインポートテーブルを変更して、元のターゲットではなく関数をプルする方法です。
    • もう1つの方法は、DLLリダイレクトを使用することです。 Linuxでは、これはLD_PRELOADとして認識されます。プレーンな英語では、同じ名前のDLLを読み込み、目的のAPI dllの前に一致する記号を付けて、呼び出しを盗みます。そのように。 MSVCの機能でさえ、気にしないもののために独自のスタブを実装する必要がなく、DLLでリダイレクトされたリンク関数を生成できます。
    • 結果のインターフェイスクラスのvtableの関連エントリを上書きすることで、COM呼び出しにパッチを適用できます。
    • 他のテクニックがあります。 DLL注射など.

したがって、基準を満たすサンドボックスを実装する場合は、考慮すべき考慮事項がいくつかあります。

  • まず、どこに何をフックするか。すべてのkernel32.dllをフックしても、これらの関数を呼び出さない場合、API呼び出しが回避できる可能性があります。このようなCOMまたは.netコードは知りませんが、いくつかあると思います。
  • PatchGuardの結果として、カーネルのパッチ適用には注意が必要です。フィルターマネージャーは、ウイルス対策(したがっておそらくサンドボックス)に必要なことのほとんどを提供しますが、フィルターマネージャーの外に出ると、不安定な土地にすぐに入ることになります。できることには制限があるかもしれません。
  • 次に、ユーザーランドに配置するフックはすべて、バイナリ変換を使用していないと仮定すると、サンドボックスでほぼ確実に検出できます。たとえば、パッチCreateFileを選択してみましょう。信頼できないコードは、この関数のメモリを単に読み取り、プロローグが期待どおりであることを確認できます。同様に、注入されたDLL、IATフックなどを検出する方法があります。
  • 同じことがカーネルモードコードのサンドボックス化にも当てはまります。信頼できないコードにドライバーをインストールさせると、再び同じレベルの競争条件になります。

この種の作業は完了しました。Sandboxieは、この種のレベルでサンドボックスを実装しようとする製品の1つですが、カーネルレベルが必要以上に多い可能性があります。私がこのようなことについてあまり知らなかったときは、Sandboxieを少しだけ見返しましたが、コアコンポーネントはカーネルレベルであると思います。ユーザーモードのフックのほとんどすべてが期待どおりに元に戻せるためです。唯一の防御策は、より高いレベルの許可を得ることです。

バイナリ変換がないとのことですが、このため、WindowsのさまざまなデバッグAPIについては説明していません。これらを使用すると、プログラムをステップ実行する場合と同じように基本的にプログラムを実行し、呼び出しやジャンプが行われる前にそれらを分析できます。ただし、これは基本的にバイナリ変換であり、デバッグはどのような場合でもパフォーマンスに影響します。それだけでなく、サンドボックスに抵抗するプログラムを作成している場合、デバッガーを検出するためのいくつかの既知のトリックがあります(1つはデバッガーをデバッグできないため、再起動して新しいプロセスをデバッグしようとすると、これは間違いなくptrace)に適用され、プログラムをサンドボックスで使用できなくなります。

肯定的な点としては、ほとんどのマルウェア以外の製品は、おそらくこれらの環境での実行に抵抗しようとしないため、使用した手法のセットでうまく機能するでしょう。これは非常に役立つ事実です。

最後になりましたが、箇条書きを過度に使用したことをお詫び申し上げます。そして、呼び出しをフックするためのテクニックの私のリストは完全ではありません-間違いなく他のものがあります。

6
user2213

Windows用のオープンソースのサンドボックス実装であるFeatherweight Virtual Machineを見つけました。

http://static.usenix.org/events/vee06/full_papers/p24-yu.pdf

http://sourceforge.net/projects/fvm-rni/

デューンも興味深いです:

http://dune.scs.stanford.edu/

VT-xを使用してLinuxで説明したように、概念実証のサンドボックスを実装します(残念ながら、ほとんどの仮想マシンでは機能しません)。

4
Maarten

あなたの計画は、システムコールのある種のスクリーニングによって「悪い」動作を特定できるという欠陥のある仮定に基づいています。できません。 Windowsには、バグ、隠れた機能、および公開されていない依存関係がたくさんあります。提供しなかった他のコードに制御を渡すとすぐに、承認したことだけが実行されるという保証はありません。

2
ddyer