Another code sign question

Hello everybody.
I have the latest Windows 10 with March 2021 updates. Microsoft Windows [Version 10.0.19042.867]
Edition doesn’t matter, it happens on Home, Pro N. Bitness doesn’t matter either, x86 or x64.
It’s a stock Windows installed from official ISO, no other programs installed.
I have a simple exe-file, it basically does nothing and just an empty stub. It’s signed with GlobalSign EV SHA-256 code signature.
When I try to start the file the aforementioned Windows shows “Your organization used Windows Defender Application Control to block this app” screen.
In Event Viewer->Windows Logs->Security I can see a message “Code integrity determined that the image hash of a file is not valid. The file could be corrupt due to unauthorized modification or the invalid hash could indicate a potential disk device error.”
signtool verify /v /pa states that everything is OK. Signature in file properties is also OK.
It’s a simple file, user-mode, console, does nothing. Old versions like Windows 7, 8, the first 10 - they all start the file OK. But this new Windows 10 refuses to run it.
Disabling Windows Defender or Secure Boot doesn’t help. Signing with /ph option doesn’t help either. The only thing that helps is disabling /INTEGRITYCHECK linker option. But some files in my product require this option. Besides I couldn’t find anywhere that having this flag set enforces some extra/more strict checks than just a mandatory standard signature check.
Debugging the kernel didn’t show much, CiEvaluatePolicyInfo is the one failing and failing quite early. I suspect that this INTEGRITYCHECK enforces not a standard signature check, but a heavy one like for drivers that require DevPortal MS signature. But I couldn’t find this behavior documented anywhere. Maybe it’s some kind of WDAC policy, but everything is default and I couldn’t find any default policy that could explain this.
Has anyone faced a similar issue?
I can upload the signed file, just not sure that doesn’t break any rules.
Thank you for your time and help.
P.S. I do realize it’s not exactly a driver question, but code sign questions discussed here are one of the best on the Internet. So I silently hope this one will slide :slight_smile:

Just grasping for straws, is it possible that your build procedure had you modifying the resources or adding a manifest after signing the file?

I don’t think so. I don’t do anything dangerous. And in this case signature would be invalid and hence signtool /verify and file properties would have shown that signature is broken. Besides it works on older Windows.

Which DLLs is your EXE statically linked with? Could one of them be failing validation instead of the EXE itself?

1 Like

IMHO with this one you can give the new Microsoft Q&A system a try.
Post with tags windows-10-security, windows-10-application-compatibility, maybe windows-10-general. Share your file via Google - oops, OneDrive.

https://docs.microsoft.com/en-us/answers/topics/windows-10-security.html

–pa

1 Like

@MBond2 said:
Which DLLs is your EXE statically linked with? Could one of them be failing validation instead of the EXE itself?

It’s an empty stub that does nothing. It’s completely stripped, so it doesn’t even have an import table and imports nothing.

@Pavel_A said:
IMHO with this one you can give the new Microsoft Q&A system a try.
Post with tags windows-10-security, windows-10-application-compatibility, maybe windows-10-general. Share your file via Google - oops, OneDrive.

I’ll give it a try, thank you. Added: done.

INTEGRITYCHECK linker switch is quite special and only rarely required, e.g. for AMSI provider DLLs, processes talking to WSC, Antimalware protected process light, etc. Code signing verification in that case is similar to legacy driver verification and as such requires cross signing with Globalsigns cross cert toward the Microsoft Code Verification Root CA. Manual verification via signtool requires /kp the kernel mode policy switch, which unfortunately only works with secure boot disabled. The bad news is that the Globalsign cross cert expires 2021-04-15, which is next week, and will not be reissued by Microsoft. This basically means you can not use Globalsign any longer with Integritycheck binaries. As I am in the AV industry and a member of the Microsoft Virus Initiative I do know quite a bit more of how to continue after that date, but all that stuff is still under NDA…hope that clarified a bit.

1 Like

I think this INTEGRITYCHECK flag silently moved from mandatory simple signature check to hardened signature check. Like it’s expected to be used for sensitive code only that needs strict signature checks like AMSI or LSA. Hence it requires MS signature like drivers, just for user-mode. And documentation completely misses this change.

I kept digging it and today I was able to run it using a dirty hack: I signed it at dev portal as LSA. Obviously it has nothing to do with LSA, but I didn’t (and still don’t) see the right way to do it. After that the file has 2 signatures: mine and Microsoft Windows Software Compatibility Publisher. This way it runs. I know, it doesn’t shed much light on why it still fails to run in its original form and I still don’t know the right way to do it, but at least there is some dirty hack to make it work.

I’ll be really grateful if someone tells me what’s wrong with my file or what’s the right way to do it.

1 Like

@AndreG said:
The bad news is that the Globalsign cross cert expires 2021-04-15, which is next week, and will not be reissued by Microsoft. This basically means you can not use Globalsign any longer with Integritycheck binaries.

I can see that R1 root expires on April, 15 2021, but looks like R3 root expires on June, 04 2025. Maybe this one can be used? Of course if you have appropriate certificate and will be able to build chain of trust up to R3. But for some reason articles in GlobalSign KB recommend R1-R3 cross and R1-MS cross for some yet unknown reason. Maybe R3 will be (is) blocked for driver signing?