Opened 4 years ago
Last modified 4 years ago
#20341 new defect
HARDENING fails to verify DLLs on Windows for non-interactive, restricted user
Reported by: | Thorsten Schöning | Owned by: | |
---|---|---|---|
Component: | host support | Version: | VirtualBox 6.1.22 |
Keywords: | Cc: | ||
Guest type: | all | Host type: | Windows |
Description
Background
I need to automatically run VMs headless WITHOUT any interactive user login after Windows booted. The started VMs should additionally run somewhat secure using a default, restricted non-admin user of Windows. This seems like exactly the setup recommended on non-Windows and am I using with Ubuntu 16.04 and phpVirtualBox currently. In theory this should easily be possible by creating a standard user in Windows and a task in the task scheduler to execute a VM headless using that user and e.g. the following command line:
VBoxManage startvm "[...]" --type headless
HARDENING prevents necessary functionality
While that works using an interactive login on the shell, it didn't work by default using task scheduler. The reason is HARDENING, which simply refuses to load necessary and otherwise legitimate Windows-DLLs, resulting in errors like the following. Things heavily depend on the configured VM and the purpose of loading some DLLs, the following error is from a VM using bridged networking.
supR3HardenedErrorV: supR3HardenedScreenImage/LdrLoadDll: rc=VERR_LDRVI_NOT_SIGNED fImage=1 fProtect=0x0 fAccess=0x0 \Device\HarddiskVolume4\Windows\System32\NetSetupShim.dll: Not signed. supR3HardenedErrorV: supR3HardenedMonitor_LdrLoadDll: rejecting 'C:\Windows\System32\NetSetupShim.dll' (C:\Windows\System32\NetSetupShim.dll): rcNt=0xc0000190 NetworkAttachmentType_Bridged: Failed to get NetCfg, hrc=ERROR_TRUST_FAILURE 0x800706FE (0x800706fe) AssertLogRel F:\tinderbox\win-6.1\src\VBox\Main\src-client\ConsoleImpl2.cpp(5376) int __cdecl Console::i_configNetwork(const char *,unsigned int,unsigned int,struct INetworkAdapter *,struct CFGMNODE *,struct CFGMNODE *,struct CFGMNODE *,bool,bool): !FAILED(hrc) hrc=ERROR_TRUST_FAILURE 0x800706FE Constructor failed with rc=VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR pfnCFGMConstructor=00007ffc15bd1e60 VMSetError: F:\tinderbox\win-6.1\src\VBox\VMM\VMMR3\VM.cpp(318) int __cdecl VMR3Create(unsigned int,const struct VMM2USERMETHODS *,void (__cdecl *)(struct UVM *,void *,int,const char *,unsigned int,const char *,const char *,char *),void *,int (__cdecl *)(struct UVM *,struct VM *,void *),void *,struct VM **,struct UVM **); rc=VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR VMSetError: The configuration constructor in main failed due to a COM error. Check the release log of the VM for further details. ERROR [COM]: aRC=E_FAIL (0x80004005) aIID={872da645-4a9b-1727-bee2-5585105b9eed} aComponent={ConsoleWrap} aText={The configuration constructor in main failed due to a COM error. Check the release log of the VM for further details. (VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR)}, preserve=false aResultDetail=-6400 Console: Machine state changed to 'PoweredOff' Power up failed (vrc=VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR, rc=E_FAIL (0X80004005))
HARDENING fails signature verification
While changing bridged networking to NAT makes the VM start, I simply have use cases which require a bridged network and one can't be sure anyway. The problem in all of those cases still is HARDENING not being able to verify some DLLs, which can be seen more detailed in the following logs:
supR3HardenedMonitor_LdrLoadDll: returns rcNt=0x0 hMod=00007ffc74d20000 'C:\windows\system32\rsaenh.dll' supR3HardNtViCallWinVerifyTrustCatFile: hFile=0000000000000808 pwszName=\Device\HarddiskVolume4\Windows\System32\NetSetupShim.dll supR3HardNtViCallWinVerifyTrustCatFile: Cached context 00000000019efab0 supR3HardNtViCallWinVerifyTrustCatFile: hCatAdmin=00000000019efab0 supR3HardNtViCallWinVerifyTrustCatFile: cbHash=20 wszDigest=592E7D18568150098B2F131AD72F2156D1CA3A58 supR3HardNtViCallWinVerifyTrustCatFile: Retrying with fresh context (CryptCATAdminEnumCatalogFromHash -> 1062; iCat=0x0) supR3HardNtViCallWinVerifyTrustCatFile: New context 00000000019ef030 supR3HardNtViCallWinVerifyTrustCatFile: hCatAdmin=00000000019ef030 supR3HardNtViCallWinVerifyTrustCatFile: cbHash=20 wszDigest=592E7D18568150098B2F131AD72F2156D1CA3A58 supR3HardNtViCallWinVerifyTrustCatFile: CryptCATAdminEnumCatalogFromHash failed ERROR_NOT_FOUND (1062) supR3HardNtViCallWinVerifyTrustCatFile: Cached context 00000000019eef70 supR3HardNtViCallWinVerifyTrustCatFile: hCatAdmin=00000000019eef70 supR3HardNtViCallWinVerifyTrustCatFile: cbHash=32 wszDigest=668C2310EFB19B6732352E1B4C6B047E3037FC14D9878DA0CC690CFA6D37CE20 supR3HardNtViCallWinVerifyTrustCatFile: Retrying with fresh context (CryptCATAdminEnumCatalogFromHash -> 1062; iCat=0x0) supR3HardNtViCallWinVerifyTrustCatFile: New context 00000000019efab0 supR3HardNtViCallWinVerifyTrustCatFile: hCatAdmin=00000000019efab0 supR3HardNtViCallWinVerifyTrustCatFile: cbHash=32 wszDigest=668C2310EFB19B6732352E1B4C6B047E3037FC14D9878DA0CC690CFA6D37CE20 supR3HardNtViCallWinVerifyTrustCatFile: CryptCATAdminEnumCatalogFromHash failed ERROR_NOT_FOUND (1062) supR3HardNtViCallWinVerifyTrustCatFile -> -22900 (org 22900) supHardenedWinVerifyImageByHandle: -> -22900 (\Device\HarddiskVolume4\Windows\System32\NetSetupShim.dll) WinVerifyTrust Error (rc=0): supR3HardenedScreenImage/LdrLoadDll: rc=Unknown Status -22900 (0xffffa68c) fImage=1 fProtect=0x0 fAccess=0x0 \Device\HarddiskVolume4\Windows\System32\NetSetupShim.dll: Not signed. supR3HardenedWinVerifyCacheInsert: \Device\HarddiskVolume4\Windows\System32\NetSetupShim.dll Error (rc=0): supR3HardenedMonitor_LdrLoadDll: rejecting 'C:\Windows\System32\NetSetupShim.dll' (C:\Windows\System32\NetSetupShim.dll): rcNt=0xc0000190 supR3HardenedMonitor_LdrLoadDll: returns rcNt=0xc0000190 'C:\Windows\System32\NetSetupShim.dll' supR3HardenedDllNotificationCallback: Unload 00007ffc2aa90000 LB 0x000ef000 C:\Program Files\Oracle\VirtualBox\VBoxProxyStub.dll [flags=0x0] supR3HardenedDllNotificationCallback: Unload 00007ffc77240000 LB 0x00052000 C:\windows\System32\SHLWAPI.dll [flags=0x0] supR3HardenedDllNotificationCallback: Unload 00007ffc15f60000 LB 0x003c0000 C:\Program Files\Oracle\VirtualBox\VBoxC.dll [flags=0x0] Terminating the normal way: rcExit=0 supR3HardNtChildWaitFor[2]: Quitting: ExitCode=0x0 (rcNtWait=0x0, rcNt1=0x0, rcNt2=0x103, rcNt3=0x103, 1448 ms, the end); supR3HardNtChildWaitFor[1]: Quitting: ExitCode=0x0 (rcNtWait=0x0, rcNt1=0x0, rcNt2=0x103, rcNt3=0x103, 1921 ms, the end);
The following is the relevant code:
/* Get the next match. */ HCATINFO hCatInfo = g_pfnCryptCATAdminEnumCatalogFromHash(hCatAdmin, abHash, cbHash, 0, &hCatInfoPrev); if (!hCatInfo) { if (!fFreshContext) { SUP_DPRINTF(("supR3HardNtViCallWinVerifyTrustCatFile: Retrying with fresh context (CryptCATAdminEnumCatalogFromHash -> %u; iCat=%#x)\n", RtlGetLastWin32Error(), iCat)); if (hCatInfoPrev != NULL) g_pfnCryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfoPrev, 0 /*dwFlags*/); g_pfnCryptCATAdminReleaseContext(hCatAdmin, 0 /*dwFlags*/); goto l_fresh_context; } ULONG ulErr = RtlGetLastWin32Error(); fNoSignedCatalogFound = ulErr == ERROR_NOT_FOUND && fNoSignedCatalogFound != 0; if (iCat == 0) SUP_DPRINTF(("supR3HardNtViCallWinVerifyTrustCatFile: CryptCATAdminEnumCatalogFromHash failed ERROR_NOT_FOUND (%u)\n", ulErr)); else if (iCat == 0) SUP_DPRINTF(("supR3HardNtViCallWinVerifyTrustCatFile: CryptCATAdminEnumCatalogFromHash failed %u\n", ulErr)); break; }
Comparing verification results
The following is how a successful verification of that same file looks like. Specially look at "cbHash" and "wszDigest", which seems to be the exact same values like for the first attempt in the former logs. So if this verification succeeds, the catalogs contain the necessary data and the state of the DLL is obviously OK.
supR3HardNtViCallWinVerifyTrustCatFile: hFile=0000000000000930 pwszName=\Device\HarddiskVolume4\Windows\System32\NetSetupShim.dll supR3HardNtViCallWinVerifyTrustCatFile: Cached context 0000000001433810 supR3HardNtViCallWinVerifyTrustCatFile: hCatAdmin=0000000001433810 supR3HardNtViCallWinVerifyTrustCatFile: cbHash=20 wszDigest=592E7D18568150098B2F131AD72F2156D1CA3A58
The following lines are of additional interest because they seem to contain some error code of Windows:
supR3HardNtViCallWinVerifyTrustCatFile: Retrying with fresh context (CryptCATAdminEnumCatalogFromHash -> 1062; iCat=0x0) supR3HardNtViCallWinVerifyTrustCatFile: CryptCATAdminEnumCatalogFromHash failed ERROR_NOT_FOUND (1062)
Which might the following:
ERROR_SERVICE_NOT_ACTIVE 1062 (0x426) The service has not been started.
https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--1000-1299-
dberr.txt
A corresponding error code is logged to the file "C:\Windows\System32\catroot2\dberr.txt" after adjusting its permissions to allow my executing restricted default user to write to it. For some reason this is not the default, but doesn't make any difference for signature checking itself. These lines repeat multiple times, most like for each attempt to check the signature for each DLL of interest.
CatalogDB: 12:29:34 03.05.2021: waitsvc.cpp at line #345 encountered error 0x00000005 CatalogDB: 12:29:34 03.05.2021: waitsvc.cpp at line #352 encountered error 0x00000005 CatalogDB: 12:29:34 03.05.2021: catdbcli.cpp at line #345 encountered error 0x00000005 CatalogDB: 12:29:34 03.05.2021: catdbcli.cpp at line #590 encountered error 0x00000426 CatalogDB: 12:29:34 03.05.2021: catadnew.cpp at line #2479 encountered error 0x00000426 CatalogDB: 12:29:34 03.05.2021: catadnew.cpp at line #939 encountered error 0x00000426
Educated guess: COM permissions problem again?
So here's what I think is going on: This signature verification relies on some COM-component again and default security settings of those only allow SYSTEM, ADMINISTRATORS and INTERACTIVE to activate those. I have documented that in the related ticket #20340 already. When using task scheduler with my restricted user it's no member of any of these groups, therefore necessary components are not activated and signature can't be checked. This changes instantly when using the same command line etc. with the same user with an interactive shell.
While that could be argued as a limitation of Windows default settings, the problem in my opinion in this case is that HARDENING is requiring that signature verification, not Windows, while without it things would simply work. So to make HARDENING succeed in this case, I would need to make my restricted user being a member of ADMINISTRATORS, which obviously doesn't make too much sense from a security perspective: Providing far more permissions than absolutely necessary to make an additional security(!) check succeed first. :-)
Like discussed in #20340, this might be worked around by creating an additional group and providing necessary permissions on the COM component of interest to that group. The problem is that I couldn't find the exact component yet... :-/
Another workaround would be to make HARDENING optionally being disabled, it harms in this case, or at least make it more tolerant and ignore some of those errors under some circumstances. As said, the mentioned DLLs are all Windows default DLLs, unchanged, which otherwise easily pass signature verification.
Attachments (4)
Change History (6)
by , 4 years ago
Attachment: | VBoxHardening good.log added |
---|
comment:1 by , 4 years ago
I'm not the only one with this issue as well, it has been reported in the forum some years ago already:
https://forums.virtualbox.org/viewtopic.php?f=6&t=84697&sid=4cec086c23d0e16640c9ae4e923df762
comment:2 by , 4 years ago
Like discussed in #20340, this might be worked around by creating an additional group and providing necessary permissions on the COM component of interest to that group. The problem is that I couldn't find the exact component yet... :-/
I've forgot to mention that I did find one COM-server of interest already, but that's most likely not the individual component needed to fix this:
HKEY_CLASSES_ROOT\Catsrv.CatalogServer CLSID {182C40F0-32E4-11D0-818B-00A0C9231C29} %systemroot%\system32\catsrv.dll
That server is shown by Windows as a running COM-server instance in the GUI-control "%windir%\system32\comexp.msc" and is most likely provided by the system service "CryptSvc". There's even some associated security group with a similar name, but hidden from normal user etc. groups. That COM-server and its child components can be seen and configured when opening the control under the node "System Application". There's a whole bunch of individual components, but I didn't find any obvious name are obvious wrong security settings, like discussed in #20340.
VBoxHardening good