信頼できないコードを実行するアプリケーションを開発しています。私はLinux向けに設計しており、必要に応じてWindows上の仮想マシンで実行できると考えています。 Linuxのセキュリティ機能は、信頼できないコードが、制限付きのLinuxコンテナ内、制限付きのAppArmorプロファイルの下で、seccompのようなutraceポリシーによって仲介されるsyscallで、seccompの下で実行されるインタープリター言語にあることです。
しかし、この仮想化されたウィンドウをWindowsで実行することについて思いついたのは、次のとおりです。悪意のあるプログラムがインタープリター言語を破壊し、仮想マシン内で任意のマシンコードを実行するとします。 Linuxアクセスポリシーをバイパスして、ホストWindows OSに直接システムコールを行うことはできますか?もしそうなら、私はウィンドウ自体に対応するサンドボックスポリシーを必要とするでしょう。 seccomp、utrace、linuxコンテナー、AppArmorに対応するWindows機能はありますか?
Linuxのセキュリティ機能は、信頼できないコードが、制限付きのLinuxコンテナ内、制限付きのAppArmorプロファイルの下で、seccompのようなutraceポリシーによって仲介されるsyscallで、seccompの下で実行されるインタープリタ言語にあることです。
...クリキー。いい意味で。
Linuxアクセスポリシーをバイパスして、ホストWindows OSに直接システムコールを行うことはできますか?
さて、これに対する答えは、視覚化の方法と他のいくつかの要因に依存します-それをカバーするには、「仮想化の仕組み」の説明が本当に必要です。
Intel-VTを想定して、仮想化 here を少し詳しく(およびリンク)取り上げました。非常に簡単な要約として、ホストは通常のオペレーティングシステムのことを行います-ページテーブル、ゲート記述子を呼び出します。次に、仮想マシンを実行するために、ホストはVMのメモリマップを含むVMを説明する別のテーブルを設定し、VMXON
命令を実行します。その後、VMが作成されます。
仮想マシンから見ると、表示されるメモリは、使用可能なシステムメモリ全体です。これは、通常のアプリケーションの仮想メモリと同じ考え方です。通常の仮想化シナリオでは、ホストが実行しているのと同じメモリをゲストに提示するのではなく、独自のスペースを割り当てます。つまり、既存のセットアップに直接到達することはできません。
ただし、ホストメモリをゲストにマップできる場合、ホストシステムコールを直接実行するには、ホストに登録されている割り込みを発生させる必要があります。 これはかなり良いことです NTドキュメントの内部-これを実際に実装するにはWindowsとはかなり異なるため、おそらくカーネルを変更する必要があり、メモリをそのまま公開した場合、あなたはWindowsを壊すか、Linuxを壊すでしょう。もちろん、これはホストメモリをゲスト仮想マシンにマップすることを前提としています...私は明確ではない可能性があるため、問題が何であるかを正確に言うと、Linuxはint 80
を登録しています(またはsysenter
を使用しています) ); Windowsはint 2e
またはsysenterを登録しています( 別の良い記事 -前の記事と同じ作者))。他のソフトウェアが空いていれば、異なるソフトウェア割り込みハンドラーを確実に登録できますが、sysenter
の共有は変更なしでは不可能です。これは、メモリの場所に関する問題です。呼び出し規約について話すと、事態はさらに粘り強くなります...
しかし、まだ森の外には出ていません。関係するプラットフォームを変更するための真剣なエンジニアリングなしに直接ホストのシステムコールを直接呼び出すことは簡単にはできませんが、ホストと通信するためにsomeの方法が必要になることは明らかです。ある-VMCall
命令(ゲスト内)は、情報交換でホストにVMExit
を発生させ、ホストがリクエストをプロビジョニングできるようにします-ここに脆弱性がある場合、間接的にシステムコールを呼び出すことができます。これらは、あなたとホストがCPUとメモリ以外のものを共有する必要があるときに必ず発生します。 Intel VT-d は、ハードウェアで必要に応じてDMAを提供する取り組みであり、一部のクラスのデバイスではVMCallの必要性を回避します。
ソフトウェアの仮想化を行う場合、状況は少し異なります。同じことを提供するには、CPUエミュレーターを作成する必要があります。ただし、これはホスト実行プロセスであるため、コードを挿入して実行できる場合は、エミュレーターが持つすべての権限のコンテキストでシステムコールを呼び出すことができます。これは、JVMのバグ(非常に大まかに言って、免責事項:比喩的に言えば)に匹敵します-Javaにシェルコードを挿入できる不正なVMバイトコードがJVMによって提供されるセキュリティに関係なく、厄介なことを行います。
ここに明白なものを追加する必要があります-私はエンジニアリングと仮想マシンの問題について話しています。悪意のあるコードによって提供されたsamba共有を設定してdodgy.exe
をダブルクリックすると、ゲームオーバーになります。それはあなたにとって明らかな発言のように聞こえますが、他の人々がVMがすべての問題を解決すると考えている場合に備えて...
さまざまな参照:
tl; dr
ハードウェアベースの仮想化では、ゲストからホストに属するシステムコールを直接呼び出すことは(OSの一部の再構築についてはまもなく)非常に困難です。異なるOSを使用する場合はさらにそうです。悪用は間接的に可能ですが、ハイパーバイザーコードまたはその使用に脆弱性が必要です。