Signed file fails to start because of bad signature

StarGazer 1 Reputation point
2021-04-08T03:39:37.383+00:00

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.
85584-blocked.png
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."
85585-audit.png
signtool verify /v /pa states that everything is OK. Signature in file properties is also OK.
85525-signature.png
It's a simple file, user-mode, console, does nothing, imports 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?
Signed files uploaded here https://1drv.ms/u/s!Auk-n3iYU349b9w1wPqWbnBwl_k?e=teN8Sc There are 3 files: signed without /INTEGRITYCHECK and without /ph, signed with /INTEGRITYCHECK and without /ph, signed with /INTEGRITYCHECK and with /ph.
Thank you for your time and help.

Windows 10
Windows 10
A Microsoft operating system that runs on personal computers and tablets.
10,563 questions
Windows 10 Compatibility
Windows 10 Compatibility
Windows 10: A Microsoft operating system that runs on personal computers and tablets.Compatibility: The extent to which hardware or software adheres to an accepted standard.
453 questions
Windows 10 Security
Windows 10 Security
Windows 10: A Microsoft operating system that runs on personal computers and tablets.Security: The precautions taken to guard against crime, attack, sabotage, espionage, or another threat.
2,747 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Gary Nebbett 5,721 Reputation points
    2021-04-08T19:37:55.513+00:00

    Hello @StarGazer ,

    By chance, only yesterday I was playing with developing a tool that analyses and verifies Authenticode signatures and hashes (including page hashes, but completely ignoreing certificate chain policies), so I was interested to see your message.

    Many thanks for providing such safe examples! A program whose sole code consists of "xor eax,eax" and "ret" meant that I had no objections to running and testing you sample code :-)

    I traced the attempted program activation with the Microsoft-Windows-CodeIntegrity provider and enabled stack traces for the events. The trace shows VerificationError = 7, where 7 means "Invalid root certificate" and did a bit more research (but have not yet tried kernel debugging - it takes a long time for me to set that up at home). I think that you are probably correct that a Windows driver type signature policy must be observed.

    I still have a Windows 8.0 test system and the two images with IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY fail there too and in the same way.

    During my search of the web, someone mentioned that bcrypt.dll is a (rare) example of a Windows image that has IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY set. Since this is signed with a Microsoft certificate the following observation is probably not useful (or unexpected), but this Authenticode signature does pass kernel-mode driver signing policy checks.

    Gary

    1 person found this answer helpful.
    0 comments No comments

  2. StarGazer 1 Reputation point
    2021-04-08T19:58:27.14+00:00

    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.