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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CallbackHell — CVE-2021-40449 - Win32k 特権昇格の脆弱性 (LPE) のエクスプロイト | Kitploit
ツール/GitHubGitHub/ly4k/callbackhell
特権昇格脆弱性分析エクスプロイトシェルコードポストエクスプロイトペイロード開発バイナリエクスプロイト
GitHubly4k/callbackhell

CallbackHell

CVE-2021-40449 - Win32k 特権昇格の脆弱性 (LPE) のエクスプロイト

リポジトリを見る
4819524年前Kitploit レビュー済み

人気

すべて見る →

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

すべてのツールを探索

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

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

CallbackHell

CVE-2021-40449 (Win32k - LPE) のエクスプロイト

  • CallbackHell
    • 説明
    • 技術解説
    • PoC
    • 参照

説明

CVE-2021-40449 は Win32k における use-after-free であり、ローカル権限昇格を可能にします。

この脆弱性は、Kaspersky によって実環境で発見されました。

発見されたエクスプロイトは、以下の Windows 製品をサポートするように作成されていました:

  • Microsoft Windows Vista
  • Microsoft Windows 7
  • Microsoft Windows 8
  • Microsoft Windows 8.1
  • Microsoft Windows Server 2008
  • Microsoft Windows Server 2008 R2
  • Microsoft Windows Server 2012
  • Microsoft Windows Server 2012 R2
  • Microsoft Windows 10 (build 14393)
  • Microsoft Windows Server 2016 (build 14393)
  • Microsoft Windows 10 (build 17763)
  • Microsoft Windows Server 2019 (build 17763)

ただし、このエクスプロイトは現在、以下のバージョンでのみテストされています:

  • Microsoft Windows 10 (build 14393)
  • Microsoft Windows 10 (build 17763)

技術解説

先に進む前に、Kaspersky の 技術解説 を読むことを強くお勧めします。

Kasperky による技術解説に記載されているように、この脆弱性は GreResetDCInternal に存在します。攻撃者が hdcOpenDCW の呼び出し中に呼び出されるユーザーモードコールバック DrvEnablePDEV をフックした場合、ResetDC を呼び出して元のデバイスコンテキストを破棄することができ、ユーザーモードコールバックが戻ったときにカーネル内で use-after-free が発生します。

以下の擬似コードは、流出した Windows XP のソースコードの一部と、Win32kfull.sys から (パッチ適用前の) 最新の GreResetDCInternal をリバースエンジニアリングして作成されました。不要な部分は [...] で削除されています。VULN: コメントを探してください。

root@kitploit:~
BOOL GreResetDCInternal(
    HDC hdc,
    DEVMODEW *pdmw,
    BOOL *pbBanding,
    DRIVER_INFO_2W *pDriverInfo2,
    PVOID ppUMdhpdev)
{
    // [...]
    HDC hdcNew;

    {
        // Create DCOBJ from HDC
        DCOBJ dco(hdc);

        if (!dco.bValid())
        {
            SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
        }
        else
        {
            // Create DEVOBJ from `dco`
            PDEVOBJ po(dco.hdev());

            // [...]

            // Create the new DC
            // VULN: Can result in a usermode callback that destroys old DC, which
            // invalidates `dco` and `po`
            hdcNew = hdcOpenDCW(L"",
                                pdmw,
                                DCTYPE_DIRECT,
                                po.hSpooler,
                                prton,
                                pDriverInfo2,
                                ppUMdhpdev);

            if (hdcNew)
            {
                po->hSpooler = NULL;

                DCOBJ dcoNew(hdcNew);

                if (!dcoNew.bValid())
                {
                    SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
                }
                else
                {
                    // Transfer any remote fonts

                    dcoNew->pPFFList = dco->pPFFList;
                    dco->pPFFList = NULL;

                    // Transfer any color transform

                    dcoNew->pCXFList = dco->pCXFList;
                    dco->pCXFList = NULL;

                    PDEVOBJ poNew((HDEV)dcoNew.pdc->ppdev());

                    // Let the driver know
                    // VULN: Method is taken from old (possibly destroyed) `po`
                    PFN_DrvResetPDEV rfn = po->ppfn[INDEX_DrvResetPDEV];

                    if (rfn != NULL)
                    {
                        (*rfn)(po->dhpdev, poNew->dhpdev);
                    }

                    // [...]
                }
            }
        }
    }

    // Destroy old DC
    // [...]
}

擬似コードからわかるように、古いデバイスコンテキストは hdcOpenDCW 呼び出しからのユーザーモードコールバック内で解放され、その後、DrvResetPDEV メソッドが古いデバイスコンテキストから取得され、(po->dhpdev, poNew->dhpdev) を指定して呼び出されます。

デバイスコンテキストを作成してフックするには、次のようにします:

  • EnumPrinters を使用して利用可能なプリンターを見つける
  • OpenPrinter、GetPrinterDriver、LoadLibraryExA を使用してプリンタードライバーをメモリに読み込む
  • GetProcAddress と DrvEnableDriver を使用してプリンタードライバーのユーザーモードコールバックテーブルを取得する
  • VirtualProtect を使用してプリンタードライバーのユーザーモードコールバックテーブルの保護を解除する
  • プリンタードライバーの目的のユーザーモードコールバックテーブルエントリを上書きする
  • CreateDC(NULL, printerName, NULL, NULL) を使用してプリンターのデバイスコンテキストを作成する

これで、ユーザーモードコールバックがフックされたプリンターのデバイスコンテキストが得られたはずです。

私たちが関心を持つフックは1つだけ、すなわち DrvEnablePDEV です。このフックは、先に説明したように、UAF をトリガーすることと引数を制御することの2つの点で興味深いものです。UAF 脆弱性をトリガーするには、フック内で ResetDC を呼び出し、古いデバイスコンテキストを破棄します。フックから戻ると、まだ最初の GreResetDCInternal 内にいることになり、その直後に、破棄された古いデバイスコンテキストから DrvEnablePDEV が返した2つの引数(古い DHPDEV と新しい DHPDEV)を使って DrvResetPDEV の関数ポインターを取得して呼び出します。

プロセスが中整合性レベルで実行されている場合、EnumDeviceDrivers と NtQuerySystemInformation の助けを借りれば、KASLR は問題になりません。

Kaspersky によると、元のエクスプロイトは GDI パレットオブジェクトと単一のカーネル関数呼び出しを使用して任意のメモリ読み取り/書き込みを実現していました。このエクスプロイトは、ビッグプールに BitMapHeader を割り当てる手法 と RtlSetAllBits を使用して、現在のプロセストークンのすべての特権を有効にします。BitMapHeader は、現在のプロセストークンの _SEP_TOKEN_PRIVILEGES を指します。RtlSetAllBits(BitMapHeader) を呼び出すことで、単一のカーネル関数呼び出しで現在のプロセストークンのすべての特権を有効にできます。ここから、新しい特権を悪用して SYSTEM になることができます。このエクスプロイトは、SeDebugPrivilege を使用して winlogon.exe プロセスにシェルコードを注入します。

PoC

./poc.png

参照

  • https://securelist.com/mysterysnail-attacks-with-windows-zero-day/104509/
  • https://github.com/siberas/CVE-2016-3309_Reloaded/
  • https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel-internals/how-kernel-exploits-abuse-tokens-for-privilege-escalation
  • https://github.com/KaLendsi/CVE-2021-40449-Exploit
  • https://mp.weixin.qq.com/s/AcFS0Yn9SDuYxFnzbBqhkQ
ツールをダウンロード