web-dev-qa-db-ja.com

CPUID命令の偽の出力

仮想マシン(linux)のマルウェアを分析しようとしていますが、 cpuid 出力を使用して、それが仮想マシン/サンドボックスにあるかどうかを確認し、仮想化された内部にある場合、malignコードの実行を拒否します環境。

マルウェアがcpuidフラグをチェックするときに、仮想化されていないマシンのcpuidを確認できるように、cpuid命令の出力を変更/偽造することは可能ですか?

KVM config(セクション this チュートリアルの「VM検出対策」のように)を変更することでそれを回避できることを知っていますが、それがホストコンピューターの構成を変更せずに、ゲストマシン内から実行できますか?

私はこの可能な解決策について考えました:

1- $ set cpuid instruction output to X

2- $ run malware

3-マルウェアがcpuidを呼び出すと、仮想化されていない環境のフラグが表示され、悪性コードが実行されます

項目1を実行するコマンドはありますか?または、ホストからKVM構成を変更せずにこれを達成できる他の方法はありますか?

2
rmauter

CPUIDの戻り値は、既知の仮想化CPUID値と照合する前に、どこかに保存する必要があります。

「ハードウェア」サンドボックスのCPUID値を変更することは困難ですが、システムが返すCPUIDを編集することで、いつでもマルウェアをだますことができます。

逆アセンブラで、cpuid命令が使用されている場所を見つけてください。次のようなものが表示されます。

 xor    eax, eax
 mov    eax,0x40000000
 cpuid
 cmp ecx,0x4D566572
 jne <somewhere_else>

Cpuid syscallの説明は次のとおりです。

EAXレジスタに最初に入力された入力値に従って、プロセッサの識別情報と機能情報をEAX、EBX、ECX、およびEDXレジスタに返します。

上記のコードスニペットでは、cpuid命令はAEX引数= "x400000"で初期化され、魔女はシステムの「ハイパーバイザーブランド」を返すように要求します。

次に、cpuid syscallの後で、ECXレジスターの値が、VMware関連のCPUID値である「x4D566572」と照合されます。

この検証をバイパスするには、cpuid命令の直後にブレークポイントを設定し、必要に応じてレジスタを編集して、「非仮想」環境をシミュレートします。

CpuidコードをいくつかのNOPで置き換えることにより、悪意のあるバイナリにパッチを適用することもできます。これにより、cpuidチェックが完全に削除されます。

または、cpuid値の比較に続く条件付きジャンプを編集して、それを役に立たなくすることができます。

1
Guillaume

CPUID値は、モデル固有レジスター(MSR)プラットフォームに保管されます。

これらのレジスタの読み取りと書き込みは、それぞれrdmsrwrmsr命令によって処理されます。これらは特権命令であるため、オペレーティングシステムでのみ実行できます。 Linux msrカーネルモジュールを使用すると、疑似ファイル/dev/cpu/xID/msrが作成されます(プロセッサーまたはプロセッサーコアごとに固有のxIDが含まれます)。このファイルの読み取りまたは書き込み、あるいはその両方を行う権限を持つユーザーは、ファイルI/O APIを使用してこれらのレジスタにアクセスできます。

別の例:VC++ __readmsr registerで指定されたモデル固有のレジスタを読み取り、その値を返すrdmsr命令を生成しますが、関数はカーネルモードでのみ使用可能です。 、ルーチンは組み込みとしてのみ使用できます。

0
Overmind