コードが VM 内で実行されていることを VM 内から識別する方法はありますか?
特に VM にプロバイダーの拡張機能がインストールされている場合 (VirtualBox や VMWare など)、特定の VM システムを特定する簡単な方法は多かれ少なかれあると思います。しかし、CPU で直接実行していないことを識別する一般的な方法はありますか?
コードが VM 内で実行されていることを VM 内から識別する方法はありますか?
特に VM にプロバイダーの拡張機能がインストールされている場合 (VirtualBox や VMWare など)、特定の VM システムを特定する簡単な方法は多かれ少なかれあると思います。しかし、CPU で直接実行していないことを識別する一般的な方法はありますか?
これに関する多くの研究は、いわゆる「ブルーピル」攻撃、つまり、積極的に検出を回避しようとしている悪意のあるハイパーバイザーの検出に専念しています。
VMを検出するための古典的なトリックは、ITLBにデータを入力し、仮想化する必要のある命令を実行し(ハイパーバイザーに制御を与えるときに、このようなプロセッサーの状態を必ずクリアします)、さらにコードを実行して、ITLBにデータが入力されているかどうかを検出します。 。それに関する最初の論文はここにあり、研究者のブログからのかなりカラフルな説明と、ブログ記事への代替のWayback Machineリンク(画像が壊れています)。
これに関する議論の結論は、悪意のあるハイパーバイザーを検出する方法は常に存在し、隠そうとしていないハイパーバイザーを検出する方がはるかに簡単であるということです。
Red Hat には、実行されている仮想化製品 (存在する場合) を検出するプログラムがありますvirt-what
。
サードパーティが管理するツールを使用することは、独自の検出ロジックを展開しようとするよりも長期的には優れた戦略です: より多くの目 (より多くの仮想化製品に対してテストする) など.
より経験的なアプローチは、既知のVMデバイスドライバーを確認することです。WMIクエリを記述して、たとえば、VMwareディスプレイアダプター、ディスクドライブ、ネットワークアダプターなどを見つけることができます。これは、環境内の既知のVMホストタイプについてのみ心配する必要があることがわかっている場合に適しています。これをPerlで行う例を次に示します。これは、選択した言語に移植できます。
それはあなたが何を求めているかに依存します:
VMが意図的に隠れていない場合は、既知のフックを使用できます。VmWareドライバ、またはメモリ内の特定の文字列の存在、またはその他の特定の兆候を探しているようです。
VMが本当に特別なことをしてほしい場合は、プロセッサのIDを変更したり、VMを検出するためにアクセスできる特別なレジスタを追加したりするなど、明らかなフックがあります。または、メモリ内の既知の場所にある特別なデバイス(自分の世界の物理的なメモリ空間に生でアクセスできると仮定します)。IBMPower6やSunUltraSparcT1 / T2のような最新のマシン設計は、常にハイパーバイザーを実行するように設計されており、生のハードウェア上で直接実行することはありません。OSが使用する「ハードウェア」へのインターフェースは、実際にはハイパーバイザーソフトウェアレイヤーのインターフェースであり、それを回避する方法はありません。この場合、検出は常に「はい」であるため、簡単です。これは、オーバーヘッドを許容できるすべてのコンピュータシステムの将来の方向性である可能性があります。
VMが意図的に非表示にしようとしていて、その存在を追いかけている場合、それは、VMのタイミングの乱れとさまざまなパフォーマンスプロファイルがほとんどの場合、VMを解放するといういたちごっこゲームです。明らかに、これはVMの実装方法と、アーキテクチャーに配置されているハードウェアサポートの量によって異なります(zSeriesメインフレームは、通常のx86よりも特定のOSでVMまたはVMのスタックの存在を隠すのにはるかに優れていると思いますマシンは、たとえば)です。このトピックに関する議論については、http://jakob.engbloms.se/archives/97を参照してください。VMとして非表示にしようとすることは可能ですが、十分に努力すれば、検出が常に勝つ可能性が非常に高くなります。
ほとんどの場合、そうしようとすべきではありません。いくつかの特定の場合を除いて、誰かがVMでコードを実行しているかどうかは気にしないでください。
必要に応じて、Linuxで最も一般的な方法は、を確認することです/sys/devices/virtual/dmi/id/product_name
。これにより、ほとんどの実際のシステムではラップトップ/メインボードの名前が、ほとんどの仮想システムではハイパーバイザーの名前が一覧表示されます。dmidecode | grep Product
もう1つの一般的な方法ですが、rootアクセスが必要だと思います。
私はかつて、VM内にいるかどうかを示すアセンブリコードスニペットに出くわしました。グーグルで検索しましたが、元の記事が見つかりませんでした。
しかし、私はこれを見つけました:プログラムが仮想マシン内で実行されているかどうかを検出します。
それが役に立てば幸い。
VMが適切に機能する場合は、仮想化されていることをクライアントに認識できないようにする必要があります。ただし、他の手がかりを見ることができます。
VM環境に固有の既知のドライバーまたはソフトウェアを探すことが最善の方法だと思います。
たとえば、Windowsを実行しているVMWareクライアントでは、vmxnet.sysがネットワークドライバーになり、VMwareアクセラレーションAMDPCNetアダプターとして表示されます。
良い例の1つは、マザーボードの製造元に対してWMIクエリを実行しているようで、「Microsoft」が返された場合はVMを使用していることです。これはVMWare専用だと思います。VMホストソフトウェアごとに異なる方法で判断できる可能性があります。
この記事はこちらhttp://blogs.technet.com/jhoward/archive/2005/07/26/407958.aspxに、VM内にいるかどうかを検出するためのいくつかの良い提案とリンクがあります(VMWareとVirtualPC少しでも)。
ネットワーク接続のMACアドレスを調べることで、仮想マシンを使用しているかどうかを識別できる場合があります。たとえば、Xenは通常、特定の範囲のアドレス00:16:3e:xx:xx:xxを使用することをお勧めします。
システムの管理者が適切なMACアドレスを指定する必要があるため、これは保証されません。
TrapKITは、VMwareを識別するためのツールであるScoopyNGを提供します。これは、回避手法を回避しようとしますが、必ずしもVMware以外の仮想化ソフトウェアを対象としているわけではありません。ソースとバイナリの両方が利用可能です。