NtQuerySystemInformation

この記事をシェア

概要

指定されたシステム情報を取得するWin32 APIの関数です。システム上で動作しているプロセッサー数の情報や、乱数生成時に使用されるシード値の情報など、指定する引数に応じてコンピューターシステムに関する様々な情報を取得することができます。

C++

NTSTATUS NtQuerySystemInformation(
  [In]            SYSTEM_INFORMATION_CLASS  SystemInformationClass,
  [In, out]       PVOID                     SystemInformation,
  [In]            ULONG                     SystemInformationLength,
  [In, optional]  PULONG                    ReturnLength
);

第一引数のSystemInformationClassで取得する情報の種類を指定します。マルウェアの解析妨害においては、SystemInformationClassとしてSystemKernelDebuggerInformation(0x23)を指定して、カーネルデバッガーの存在を検知する手法が挙げられます。
SystemKernelDebuggerInformation(0x23)を指定して関数が実行されると、第二引数のSystemInformationが示す構造体に結果が返されます。この構造体はKdDebuggerEnabledとKdDebuggerNotPresentの2つのメンバから構成されます。このうち、KdDebuggerNotPresentがFalse(0x0)を示す場合、マルウェアはカーネルデバッガーを検知して自身を終了させます。

実装の例

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

C++

typedef enum SYSTEM_INFORMATION_CLASS {
    SystemKernelDebuggerInformation = 0x23
} SYSTEM_INFORMATION_CLASS;

typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION {
    BOOLEAN DebuggerEnable;
    BOOLEAN DebuggerNotPresent;
} SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION;

typedef NTSTATUS (NTAPI* pfnNtQuerySystemInformation)(
    SYSTEM_INFORMATION_CLASS SystemInformationClass,
    PVOID                      SystemInformation,
    ULONG                      SystemInformationLength,
    PULONG                     ReturnLength
    );

HMODULE hNtDll = LoadLibraryA("ntdll.dll");
pfnNtQuerySystemInformation NtQuerySystemInformation = (pfnNtQuerySystemInformation)GetProcAddress(hNtDll, "NtQuerySystemInformation");

SYSTEM_KERNEL_DEBUGGER_INFORMATION info;
 
NtQuerySystemInformation(
    SystemKernelDebuggerInformation,
    &info,
    sizeof(info),
    NULL
    );

if (!(info.DebuggerNotPresent)) {
    exit(1);
}

Assembly(x86)

push    0                   ; ReturnLength
push    2                   ; SystemInformationLength
lea     edx, [ebp-0Ah]
push    edx                 ; SystemInformation
push    23h                 ; SystemInformationClass
call    NtQuerySystemInformation
cmp     [ebp-9], 0
jz      short loc_being_debugged
loc_being_debugged:
push    1
call    exit

回避手法

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

  • デバッグ中にフラグを書き換える
    NtQuerySystemInformationが呼び出された後に、KdDebuggerNotPresentの値を0x0から0x1に書き換えます。
  • デバッグ中に分岐命令を変更する
    NtQuerySystemInformationを呼び出した後の分岐命令をJMP命令またはNOP命令に書き換えます。
  • プログラムを書き換える
    NtQuerySystemInformationを呼び出した後の分岐命令をJMP命令やNOP命令となるように書き換え、変更を保存します。

検出手法

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

YARAルール

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