NtSetInformationProcess

この記事をシェア

概要

指定されたプロセスの情報を設定するWin32 APIの関数です。PEB(Process Environment Block)構造体へのポインターやWOW64環境で実行されているかどうかを判別する値など、指定する引数に応じてさまざまな情報を設定することができます。

C++

NTSTATUS NtSetInformationProcess(
  [In] HANDLE            ProcessHandle,
  [In] PROCESSINFOCLASS  ProcessInformationClass,
  [In] PVOID             ProcessInformation,
  [In] ULONG             ProcessInformationLength
);

第二引数のProcessInformationClassで設定する情報のタイプを指定し、第三引数のProcessInformationで設定する値を指定します。
マルウェアの解析妨害においては、ProcessInformationClassとしてProcessBreakOnTermination(0x1D)を指定する手法が挙げられます。この手法を用いると、マルウェアはデバッガーを検知して自身を終了させ、同時にBSoD(Blue Screen of Death)を発生させます。
ProcessBreakOnTerminationタイプの値を設定するためには、デバッグ特権が必要です。解析者がデバッガーを利用する際、以下の理由によりデバッグ特権を有効にする場合があります。
(1) デバッグ対象プロセスの実行権限の関係で、デバッガーでアタッチするためのハンドルを取得できないことがある。
(2) プロセスの詳細情報を取得する処理などが、OSによって制約を受けることがある。
よってマルウェアにデバッグ特権が付与されている場合、デバッガー上で実行されていると判断し、自身を終了させる処理に分岐させます。
なおProcessBreakOnTerminationは、指定プロセスがクリティカルプロセスであるかどうかを示すタイプです。クリティカルプロセスはOSの実行に不可欠なシステムプロセスと位置付けられます。よってこのクリティカルプロセスが終了するとOSの動作が継続できないと判断され、BSoD(Blue Screen of Death)が発生します。

実装の例

C++/x86 Assemblyのコード例を以下に示します。

C++

typedef NTSTATUS (NTAPI* pfnNtSetInformationProcess)(
    HANDLE            ProcessHandle,
    PROCESSINFOCLASS  ProcessInformationClass,
    PVOID             ProcessInformation,
    ULONG             ProcessInformationLength
    );

HMODULE hNtDll = LoadLibraryA("ntdll.dll");
pfnNtSetInformationProcess NtSetInformationProcess = (pfnNtSetInformationProcess)GetProcAddress(hNtDll, "NtSetInformationProcess");

NTSTATUS status;
UINT CriticalProcess = 0x01;

status = NtSetInformationProcess(
    GetCurrentProcess(),
    0x1D,
    &CriticalProcess,
    sizeof(CriticalProcess)
    );

if (NT_SUCCESS(status)) {
    exit(1);
}

Assembly(x86)

push    4                   ; ProcessInformationLength
mov     [ebp-0Ch], 1
lea     edx, [ebp-0Ch]
push    edx                 ; ProcessInformation
push    1Dh                 ; ProcessInformationClass
call    GetCurrentProcess
push    eax                 ; ProcessHandle
call    NtSetInformationProcess
test    eax, eax
jns     short loc_being_debugged
loc_being_debugged:
push    1
call    exit                ; Occurrence of BSoD

回避手法

NtSetInformationProcessによるマルウェア解析環境検知を回避し、プログラムを解析する手法を以下に示します。一時的に検出を回避するときには1または2の手法を、恒久的に検出を回避するときには3の手法を使います。

  • デバッグ中に引数を書き換える
    NtSetInformationProcessが呼び出される前に、ProcessInformationの値を1から0に書き換えます。
  • プラグインを利用する
    ScyllaHide(Ollydbg, x64dbgなどで利用可能なプラグイン)の” NtSetInformationProcess”の項目にチェックを入れます。
  • プログラムを書き換える
    NtSetInformationProcessが呼び出される前のProcessInformationの値が0となるように書き換え、変更を保存します。

検出手法

NtSetInformationProcessを検出するYARAルールを以下に示します。

YARAルール

rule Win32API_NtSetInformationProcess
{
    strings:
        $str ="NtSetInformationProcess"
    condition:
        $str
}
この記事をシェア
サイバーセキュリティ
情報局の最新情報を
チェック!