Windows Driver の整数オーバーフローの脆弱性 CVE-N/A: PoC エクスプロイトが登場

Integer Overflow Vulnerability in Windows Driver Enables Privilege Escalation, PoC Published

2024/11/28 SecurityOnline — Windows オペレーティング・システムの ksthunk.sys ドライバーは、32 Bit から 64 Bit へのプロセス通信を容易にする機能を持つが、このコンポーネントに存在する深刻な脆弱性が、SSD Secure Disclosure の研究者により発見された。ローカル攻撃者に権限昇格を許す、この整数オーバーフローの脆弱性は、権威ある TyphoonPWN 2024 イベントで実証され、2位を獲得するほど注目されている。

この脆弱性は、カーネル内において入出力データの管理するための、バッファーを割り当てる CKSAutomationThunk::ThunkEnableEventIrp 関数に存在する。具体的に言うと、バッファー ・サイズの調整計算中に、整数オーバーフローの検証が行われないことに起因する。この見落としにより、不適切なメモリ・サイズが割り当てられ、ヒープ オーバーフローがトリガーされ、隣接するメモリへの上書きに至ってしまう。

// Only Called when the calling process is 32bit.
__int64 __fastcall CKSAutomationThunk::ThunkEnableEventIrp(__int64 a1, PIRP a2, __int64 a3, int *a4)
{
  ...
  inbuflen = CurrentStackLocation->Parameters.DeviceIoControl.InputBufferLength;
  outbuflen = CurrentStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
  // [1]. Align the length of output buffer
  outlen_adjust = (outbuflen + 0x17) & 0xFFFFFFF8;
  if ( a2->AssociatedIrp.MasterIrp )
    return 1i64;

  if ( (unsigned int)inbuflen < 0x18 )
    ExRaiseStatus(-1073741306);

  ProbeForRead(CurrentStackLocation->Parameters.DeviceIoControl.Type3InputBuffer, inbuflen, 1u);
  if ( (*((_DWORD *)CurrentStackLocation->Parameters.DeviceIoControl.Type3InputBuffer + 5) & 0xEFFFFFFF) == 1
    || (*((_DWORD *)CurrentStackLocation->Parameters.DeviceIoControl.Type3InputBuffer + 5) & 0xEFFFFFFF) == 2
    || (*((_DWORD *)CurrentStackLocation->Parameters.DeviceIoControl.Type3InputBuffer + 5) & 0xEFFFFFFF) == 4 )
  {
    // [2]. Validate the Length
    if ( (unsigned int)outbuflen < 0x10 )
      ExRaiseStatus(-1073741306);
    if ( outlen_adjust < (int)outbuflen + 16 || outlen_adjust + (unsigned int)inbuflen < outlen_adjust )
      ExRaiseStatus(-1073741306);

    // [3]. Allocate the buffer to store the data
    // 0x61 == POOL_FLAG_USE_QUOTA | POOL_FLAG_RAISE_ON_FAILURE POOL_FLAG_NON_PAGED
    a2->AssociatedIrp.MasterIrp = (struct _IRP *)ExAllocatePool2(
                                                   0x61i64,
                                                   outlen_adjust + (unsigned int)inbuflen,
                                                   1886409547i64);
    a2->Flags |= 0x30u;
    ProbeForRead(a2->UserBuffer, outbuflen, 1u); // [*] 
    data = (__int64)a2->AssociatedIrp.MasterIrp;
    ...
    // [4]. Copy the Data
    if ( (unsigned int)outbuflen > 0x10 )
      memmove((void *)(data + 0x20), (char *)a2->UserBuffer + 16, outbuflen - 16);
    memmove(
      (char *)a2->AssociatedIrp.MasterIrp + outlen_adjust,
      CurrentStackLocation->Parameters.FileSystemControl.Type3InputBuffer,
      inbuflen);
    ...
}

SSD Secure Disclosure 技術チームは、「上記のリスト内の [1] では、outbuflen + 0x17 の計算中に整数オーバーフローの検証が行われない。そのため、outlen_adjust を小さな値に設定することが可能となり、割り当てサイズが不足し、[4] でのデータのコピー中に、ヒープ・オーバーフローが発生する」と説明している。

以下のエクスプロイト示すのは、カーネルのセーフガードをバイパスし、SYSTEM レベルの権限を取得する一連の手順である。

  1. メモリ操作:カーネルの非ページ・プール内の名前付きパイプ・オブジェクト間で、ギャップの作成に成功した攻撃者は、オーバーフローの悪用を容易にする。
  2. 任意のメモリ アクセス: 隣接する名前付きパイプを破損することで、攻撃者は任意の読み取りおよび書き込み機能を取得する。
  3. トークンの上書き:カレントのプロセス・トークンを変更することで SYSTEM 権限を不正に取得し、マシンの完全な制御を達成する。

この脆弱性について通知を受けた Microsoft は、重複した問題であり、すでに解決済みだと主張している。その一方で、依然として Windows 11 23H2 環境において、問題とされる脆弱性の悪用が可能であることを、この研究者は発見しました。しかし、現時点においては、CVE 番号や詳細なパッチ情報は提供されていない。

この脆弱性が例示するのは、カーネル・レベルの欠陥に関連するリスクである。この脆弱性の悪用により、ドライバーを介した権限昇格が達成されることが、カーネル・コードでの厳格な検証の重要性を強調している。SSD Secure Disclosure が指摘したように、制御可能な割り当てサイズと、関連するデータにより、この脆弱性悪用は容易であり、高度な脅威アクターの潜在的なツールとなる。

SSD Disclosure の公式アドバイザリでは、技術的な詳細と PoC コードが提供されている。