The following code behaves differently for the SAME file for interactive and admin-users vs. non-interactive ones. It seems to ALWAYS succeed for admins, but for non-admins, restricted default users ONLY when they execute the code as part of an interactive logon session, shell etc. It fails when the same restricted default user is e.g. used to execute a task by the task scheduler after e.g. system boot. Additionally I'm not the only one with this problem.
cpp
/*
* Enumerate catalog information that matches the hash.
*/
uint32_t iCat = 0;
HCATINFO hCatInfoPrev = NULL;
do
{
/* 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;
}
fNoSignedCatalogFound = 0;
Assert(hCatInfoPrev == NULL);
hCatInfoPrev = hCatInfo;
/*
* Call WinVerifyTrust.
*/
[...]
iCat++;
} while (rc == VERR_LDRVI_NOT_SIGNED && iCat < 128);
This is how a log looks like when verification succeeds:
supR3HardNtViCallWinVerifyTrustCatFile: hFile=0000000000000930 pwszName=\Device\HarddiskVolume4\Windows\System32\NetSetupShim.dll
supR3HardNtViCallWinVerifyTrustCatFile: Cached context 0000000001433810
supR3HardNtViCallWinVerifyTrustCatFile: hCatAdmin=0000000001433810
supR3HardNtViCallWinVerifyTrustCatFile: cbHash=20 wszDigest=592E7D18568150098B2F131AD72F2156D1CA3A58
The following is the same file when verification fails:
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)
As one can see, the calculated digest etc. for the file is the same in both cases:
supR3HardNtViCallWinVerifyTrustCatFile: cbHash=20 wszDigest=592E7D18568150098B2F131AD72F2156D1CA3A58
vs.
supR3HardNtViCallWinVerifyTrustCatFile: cbHash=20 wszDigest=592E7D18568150098B2F131AD72F2156D1CA3A58
So it's really the same file and proven that signature information is available in Windows catalogs at all. It only seems that for some reason it's not found/enumerated for restricted users, so the following errors are logged:
supR3HardNtViCallWinVerifyTrustCatFile: Retrying with fresh context (CryptCATAdminEnumCatalogFromHash -> 1062; iCat=0x0)
supR3HardNtViCallWinVerifyTrustCatFile: CryptCATAdminEnumCatalogFromHash failed ERROR_NOT_FOUND (1062)
According to MSDN, 1062
might be the following:
ERROR_SERVICE_NOT_ACTIVE
1062 (0x426)
The service has not been started.
Any idea what the not active service might be in the context of a restricted, non-interactive user and the called enumeration function? Any other idea about the root cause of this problem?