カーネル シェルコードの読み込み

Access violation from shellcode dereferencing null pointer news

最近のハッキング ツール ダンプの結果として、FLARE チームは、カーネル シェルコードを爆発させるマルウェア サンプルの急増を確認しました。ほとんどのサンプルは静的に分析できますが、FLARE チームはこれらのサンプルをデバッグして特定の機能を確認することがあります。デバッグは、パッキングや難読化を回避し、カーネル シェルコード サンプルがアクセスしている構造、システム ルーチン、およびプロセスをすばやく特定するための効率的な方法です。

この投稿は、カーネル ソフトウェアの分析を中心としたシリーズの始まりであり、カスタム Windows カーネル ドライバーを使用して Windows カーネル シェルコードを読み込んで実行するツールを紹介します。いくつかのカーネル シェルコードの簡単なケース スタディ、 FLARE のカーネル シェルコード ローダーを使用してシェルコードをロードする方法、独自のコピーを作成する方法、およびその動作について説明します。

いつものように、VM などの安全な環境でのみマルウェアを分析してください。作業を完了するために依存しているシステムでは、カーネル シェルコード ローダーなどのツールを使用しないでください。

角ペグと丸穴の話

シェルコード サンプルがどのように検出されるかによっては、アナリストは、それがユーザー空間とカーネル空間のどちらを対象としているのかわからない場合があります。一般的な選別手順は、サンプルをシェルコード ローダーにロードし、ユーザー空間でデバッグすることです。カーネル シェルコードでは、図 1 のアクセス違反のような予期しない結果が生じる可能性があります。

Access violation from shellcode dereferencing null pointer
ヌル ポインターを逆参照するシェルコードからのアクセス違反

カーネル環境は、ユーザー モードとは別世界です。さまざまなレジスタが異なる意味を持ち、まったく異なる構造を指します。たとえば、64 ビット Windows ユーザー モードの gs セグメント レジスタは、サイズがわずか 0x38 バイトのスレッド情報ブロック (TIB) を指しますが、カーネル モードでは、はるかに大きいプロセッサ制御領域 (KPCR) を指します。図 1 のアドレス 0x2e07d9 で、シェルコードは KPCR の IdtBase メンバーにアクセスしようとしていますが、ユーザー モードで実行されているため、gs セグメントからのオフセット 0x38 の値は null です。これにより、次の命令が NULL ページの無効なメモリにアクセスしようとします。コードが実行しようとしていることが、ユーザー モード環境では意味をなさず、結果としてクラッシュしました。

対照的に、カーネル モードは最適です。図 2 は、WinDbg の dt コマンドを使用して ntoskrnl.pdb 内で定義された _KPCR タイプを表示し、IdtBase という名前のオフセット 0x38 にあるフィールドを強調表示しています。

KPCR 構造
KPCR 構造

このサンプルの残りのコードを考えると、KPCR の IdtBase フィールドにアクセスすることは完全に理にかなっています。これがカーネル シェルコードであると判断したことで、残りの質問をすばやく解決できましたが、調査結果を確認するために、カーネル シェルコード ローダーを作成しました。このツールを使用して、何もしない小さなシェルコードをロードすると、次のようになります。

FLARE のカーネル シェルコード ローダーの使用

カーネル デバッガーを使用してターゲット システムを起動し、シェルコード ローダー (kscldr.exe) をコピーしたディレクトリで管理コマンド プロンプトを開きました。シェルコード ローダーは、シェルコードが配置されているディスク上のファイルの名前を唯一の引数として受け取ることを想定しています。図 3 は、16 進エディターを使用して NOP (0x90) 命令と RET (0xC3) 命令のオペコードをバイナリ ファイルに書き込み、kscldr.exe を呼び出してそのコードをカーネル シェルコード ローダー ドライバーに渡している例を示しています。 Vim for Windowsに付属する xxd の Windows ポートを使用してファイルを作成しました。

kscldr.exe を使用してカーネル シェルコードをロードする
kscldr.exe を使用してカーネル シェルコードをロードする

シェルコード ローダーにより、セキュリティ警告が表示されます。 [はい] をクリックすると、kscldr.exe はドライバーをインストールし、それを使用してシェルコードを実行します。カーネル ドライバーが既にブレークポイントを発行しており、カーネル デバッガーがコマンドを待機しているため、システムはこの時点でフリーズします。図 4 は、WinDbg がブレークポイントに到達し、対応する kscldr.sys のソース コードを表示する様子を示しています。

kscldr.sys の侵入
kscldr.sys の侵入

ブレークポイントから、ソース レベルのデバッグで WinDbg を使用して、シェルコード バッファーにステップ アンド トレースします。図 5 は、これを実行した後の WinDbg によるバッファーの逆アセンブリを示しています。

シェルコードのトレースと逆アセンブル
シェルコードのトレースと逆アセンブル

逆アセンブリは、以前の 0x90 および 0xc3 オペコードを示しており、シェルコード バッファが実際に実行されていることを示しています。ここから、WinDbg の強力な機能を使用して、コードの動作をデバッグおよび分析できます。

自分で組み立てる

FLARE のカーネル シェルコード ローダーを自分で試すには、ソース コードをダウンロードする必要があります。

ビルドを開始するには、 Windows Driver Kit (WDK)をダウンロードしてインストールします。私はコマンド ライン駆動のWindows Driver Kit Version 7.1.0を使用していますが、WDK の最新バージョンは Visual Studio と統合されています。新しいキットを快適に使用できる場合は、それを歓迎しますが、ビルド コマンドと依存関係に関しては、自分で問題を解決する必要があることに注意してください。 WDK 7.1.0 はこのツールの目的に適しているため、この投稿で説明するバージョンは WDK 7.1.0 です。

WDK をダウンロードしてインストールしたら、開発システムのスタート メニューで Windows Driver Kits ディレクトリを参照し、適切な環境を選択します。図 6 は、Windows 7 システム上の WDK プログラム グループを示しています。 「チェック済みビルド」という用語は、デバッグ チェックが含まれることを示します。私は 64 ビット カーネル シェルコードをロードする予定で、Windows が間違いを早期に検出できるようにするのが好きなので、x64 Checked Build Environment を使用しています。

Windows Driver Kits プログラム グループ
Windows Driver Kits プログラム グループ

WDK コマンド プロンプトで、FLARE カーネル シェルコード ローダーをダウンロードしたディレクトリに移動し、ez.cmd と入力します。このスクリプトにより、テスト署名証明書のパスワードを入力して使用するよう求めるプロンプトが表示されます。ビルドが完了したら、bin ディレクトリにアクセスし、kscldr.exe をデバッグ ターゲットにコピーします。このツールのカスタム コピーの使用を開始する前に、いくつかの手順を実行してターゲット システムを準備する必要があります。

デバッグ ターゲットの準備

カーネル シェルコードをデバッグするために、特権レベル 0 でシェルコードを読み込んで実行する Windows ソフトウェア専用ドライバーを作成しました。通常、Windows は特別なクロス証明書で署名されたドライバーのみを読み込みますが、Windows ではテスト署名を有効にして、署名されたドライバーを読み込むことができます。検査証明書付き。このテスト証明書は無料で作成できます。これにより、ドライバーを実稼働システムにロードすることができなくなります。これは理想的です。

テスト署名モードを有効にすることに加えて、カーネル シェルコードが実行された後に何が起こっているかを実際に追跡できるように、カーネル デバッグを有効にする必要があります。 Windows Vista 以降では、管理コマンド プロンプトで次の 2 つのコマンドを発行してから再起動することで、テスト署名とカーネル デバッグの両方を有効にすることができます。

bcdedit.exe /set testsigning on

bcdedit.exe /デバッグをオンに設定

VM でデバッグするためにVirtualKDをインストールしますが、シリアル ポートを名前付きパイプまたは WinDbg が理解するその他のメカニズムに接続するための仮想化ベンダーの指示に従うこともできます。セットアップとテストが完了したら、準備完了です。

シェルコード ローダーを試してみて、停止コード 0x3B (SYSTEM_SERVICE_EXCEPTION) を示すブルー スクリーンが表示された場合は、事前にカーネル デバッガーに正常に接続していない可能性があります。シェルコードを実行する直前に、ドライバーがソフトウェア割り込みを発行して、デバッガーに制御を与えることに注意してください。デバッガーが正常に接続されていない場合、Windows はブルー スクリーンになります。このような場合は、再起動して再試行します。今度は、最初に [デバッグ] -> [WinDbg でB reak ] をクリックして、デバッガーが制御されていることを確認します。制御できることがわかったら、g コマンドを発行して実行を続行できます (ドライバのロード通知を無効にして、それ以上介入せずにブート プロセスを終了させる必要がある場合があります: sxd ld)。

使い方

ユーザー空間アプリケーション (kscldr.exe) は、ドライバを PE-COFF リソースからディスクにコピーし、Windows カーネル サービスとして登録します。ドライバーは、デバイス書き込みおよび I/O 制御ルーチンを実装して、ユーザー アプリケーションからの対話を可能にします。そのドライバー エントリ ポイントは、最初にディスパッチ ルーチンを登録して、CreateFile、WriteFile、DeviceIoControl、および CloseHandle を処理します。次に、Devicekscldr という名前のデバイスと、ユーザー空間からデバイス名にアクセスできるようにするシンボリック リンクを作成します。ユーザー アプリケーションがデバイス ファイルを開き、WriteFile を呼び出すと、ドライバーは、PoolType に NonPagedPool ( 実行可能) を指定して ExAllocatePoolWithTag を呼び出し、新しく割り当てられたメモリにバッファーを書き込みます。書き込み操作の後、ユーザー アプリケーションは DeviceIoControl を呼び出してシェルコードを呼び出すことができます。応答として、ドライバーはデバイス オブジェクトに適切なフラグを設定し、ブレークポイントを発行して制御をカーネル デバッガーに渡し、最後に関数であるかのようにシェルコードを呼び出します。

あなたがここにいる間

ドライバーの開発により、独自の計測機会への扉が開かれます。たとえば、図 7 は、システム全体のプロセス、スレッド、および DLL アクティビティを追跡できる、WDK ヘルプ ファイルに記述されているいくつかのカーネル コールバック ルーチンを示しています。

WDK カーネル モード ドライバー アーキテクチャ リファレンス
WDK カーネル モード ドライバー アーキテクチャ リファレンス

カーネル開発は、多くの研究を伴う深いテーマですが、WDK には、正しい Windows カーネル プログラミング テクニックを示す多数のサンプル ドライバーも付属しています。これは、Windows の内部情報、セキュリティ研究のトピック、およびインストルメンテーションの可能性の宝庫です。時間があれば、仕事に戻る前に周りを見て回ってください。

要約

カーネル シェルコードを動的に分析できるように、テスト環境で特権シェルコードをロードするための FLARE のツールを共有しました。これにより、カーネル シェルコードが環境に現れた場合に迅速にトリアージするための簡単な方法が提供されることを願っています。ソースコードを今すぐダウンロードしてください。

FLARE からこれらのツールとテクニックについてもっと学びたいですか?それなら、今年の夏にラスベガスで開催される Black Hat クラスのいずれかを受講する必要があります。私たちのオファリングには、 マルウェア分析クラッシュ コースリバース エンジニアのための macOS マルウェア、およびマルウェア分析マスター クラスが含まれます。

参照: https://www.mandiant.com/resources/blog/loading-kernel-shellcode

Comments

Copied title and URL