ELAM driver and protected process problem

Hello,

I have enabled test signing on my Win10x64 VM and I am trying to load a protected service using an ELAM driver (using the elampsample source, of course). For that purpose I have generated two self-signing certificates: one for the driver and one for the service. That’s how I have done that:

makecert.exe -a SHA256 -r -pe -ss PrivateCertStore -n “CN=TestElam” -eku 1.3.6.1.4.1.311.61.4.1,1.3.6.1.5.5.7.3.3 -sr localmachine c:\test\TestElam.cer

makecert.exe -a SHA256 -r -pe -ss PrivateCertStore -n “CN=TestSrv” -eku 1.1.1.1,1.3.6.1.5.5.7.3.3 -sr localmachine c:\test\TestSrv.cer

I sign both binaries in the post-build step like this:

signtool.exe sign /fd SHA256 /a /v /ph /debug /s “PrivateCertStore” /n “TestElam” /t http://timestamp.verisign.com/scripts/timestamp.dll $(OutDir)elamsample.sys

signtool.exe sign /fd SHA256 /a /v /ph /debug /s “PrivateCertStore” /n “TestSrv” /t http://timestamp.verisign.com/scripts/timestamp.dll $(OutDir)Srv.exe

Afterwards I run the following command: certmgr.exe ?v $(OutDir)Srv.exe and get the hash as it is explained here:

https://msdn.microsoft.com/en-us/library/windows/desktop/dn313124(v=vs.85).aspx

I embed the following structure into the resource file of the driver:

MicrosoftElamCertificateInfo MSElamCertInfoID
{
1, // Number of entries
L"138C94AFE91287D59B972742FB7839992060649A9DFFB8900C16DDA8E1E23354", // hash obtained by running “certmgr.exe ?v $(OutDir)Srv.exe”
0x800c,
L"1.1.1.1", // EKU(s)
}

I reconfigure the service to run as protected using an external app in order not to temper with the signature like this:

Info.dwLaunchProtected = SERVICE_LAUNCH_PROTECTED_ANTIMALWARE_LIGHT;

ChangeServiceConfig2(schService, SERVICE_CONFIG_LAUNCH_PROTECTED, &Info);

Rebuild the driver and reboot. The driver loads and the system boots correctly and everything looks good, however, when I try to start my service I get error == 577 (ERROR_INVALID_IMAGE_HASH).
I think I have followed the protocol, so can anyone please help here?

Thanks a lot,
Dmitry

Your resource strings don’t end with \0.

The makecert commands seem to use two EKU OID but the resource contains only one EKU. Up to three are permitted.

H. G.

H. G., thanks a lot for your answer.

I have corrected the resource structure and now it looks as following:

MicrosoftElamCertificateInfo MSElamCertInfoID
{
1, // count of entries, number of maximum entries allowed is 3
L"7F7ABF09510DF8C1DCD10A486DA0D4C4F72779A99E419C472D4DA26417EA7E4C\0",
0x800c,
L"1.1.1.1;1.3.6.1.5.5.7.3.3\0",
}

where the second field is actually a file hash obtained by running:

signtool verify /pa /v Srv.exe

Signature Index: 0 (Primary Signature)
Hash of file (sha256): >7F7ABF09510DF8C1DCD10A486DA0D4C4F72779A99E419C472D4DA26417EA7E4C

The MSDN document requests that Certificate Hash is present and not the file hash.
If I understand correctly, the certificate hash may be found in the certificate manager
and this would be the certificate thumbprint which is not changing even when the binary
signed with this certificate is. I am facing some problems:

  1. When I put the file hash in the resource section it does not work,
    since probably, it should not be there in the first place.

  2. When I am trying to use the certificate hash there are multiple problems.

certmgr.exe -v Srv.exe
yields four entries that contain “Content SignatureAlgorithm”, two SHA1 hashes and two SHA256 hashes.
SHA1 hashes are different while the SHA256 hashes are identical.
Which ones should I use in the resource file? I tried to put SHA256 and it did not work.

  1. After the system boots, I am trying to run the following code:

Info.dwLaunchProtected = SERVICE_LAUNCH_PROTECTED_ANTIMALWARE_LIGHT;
ChangeServiceConfig2(schService, SERVICE_CONFIG_LAUNCH_PROTECTED, &Info);

Which constantly returns “ERROR_ACCESS_DENIED” while the service handle is successfully opened
with SERVICE_ALL_ACCESS and I am running as an Administrator.

  1. I am also wondering whether this solution of ELAM driver + protected service may work using only self-generated, test
    certificates? May this be one of the caveats?

“SignTool Error: A certificate chain processed, but terminated in a root
certificate which is not trusted by the trust provider.”

Any help would be appreciated.

Thanks,
Dmitry

Read the ELAM Sample README.md file on github :

« Early Launch drivers are required to be signed with a code-signing certificate that also contains the Early Launch EKU “1.3.6.1.4.1.311.61.4.1”. »

https://github.com/Microsoft/Windows-driver-samples/blob/master/security/elam/README.md

H. G.

Maybe you or someone from MSFT could shed some light on this. For
test-signing the case is clear, but I searched high and low for
information on how to obtain a certificate with this EKU and in the end

  • and after some conversation with a technical support engineer from
    Symantec/VeriSign - it looked as if MSFT was the only party to possess
    this kind of certificate (with the required EKU).

It therefore looked like the secret sauce was to get the driver file (or
.cat file only?) signed by Microsoft, presumably via SysDev. But I was
appointed some other tasks before I got to verify that theory.

Thanks in advance for any pointers you (or others) can provide.

// Oliver

On 2017-06-23 21:11, xxxxx@gmail.com wrote:

Read the ELAM Sample README.md file on github :

« Early Launch drivers are required to be signed with a code-signing
certificate that also contains the Early Launch EKU
“1.3.6.1.4.1.311.61.4.1”. »

https://github.com/Microsoft/Windows-driver-samples/blob/master/security/elam/README.md

H. G.

H.G.,

I am using the eku you mentioned when I am signing the driver.
At this point I am pretty confident that what is supposed to be in the structure is as following:

MicrosoftElamCertificateInfo MSElamCertInfoID
{
1, // count of entries, number of maximum entries allowed is 3
L"1F8723F9551E864410F7B02B4A41583CA1DAA176\0",
0x8004,
L"1.3.6.1.5.5.7.3.3\0"
}

Where the second field represents a thumbprint of the certificate that will be used for future signing of binaries. How do I know that? I wrote a test app, that calls InstallELAMCertificateInfo() on the driver binary. Technically, I am not supposed to call this function since the OS must have extracted the certificate already, but the call succeeds only if the MSElamCertInfoID is built in a way I mentioned.

However, when I am trying to run and my service is signed with the cert in the structure, it is always failing here:

00 CI!CipReportAndReprieveUMCIFailure
01 CI!CiValidateImageHeader
02 nt!SeValidateImageHeader
03 nt!MiValidateSectionCreate
04 nt!MiCreateNewSection
05 nt!MiCreateImageOrDataSection
06 nt!MiCreateSection
07 nt!MmCreateSpecialImageSection
08 nt!NtCreateUserProcess
09 nt!KiSystemServiceCopyEnd
0a ntdll!NtCreateUserProcess

Maybe someone from Microsoft would be kind enough to respond here…

Thanks,
Dmitry

Yes the final package is signed my MSFT (for production environment).

“Early Launch drivers are signed by Microsoft for qualifying Anti-Malware
vendors with a WHQL certificate that contains this EKU.”

So you just sign your package with the appropriate EKU(s) and submit it to
MSFT for WHQL signing. Finaly, a package signed by MSFT is returned.

My question is however: can this whole scheme be made fully functional in a test environment, using only test certificates? i.e. driver embeds information about other test certificates that will be used for signing, the system boots and binaries signed with those embedded certificates actually run as protected processes?

Thanks,
Dmitry

Take a look at WDBoot.sys. This is Windows Defender?s ELAM driver. You need to do an HLK submission for ELAM signing to get the ?Microsoft Windows Early Launch Anti-malware Publisher? signed to your driver.

From: hgfhhgf jhgfgbbgfmailto:xxxxx
Sent: Friday, June 23, 2017 5:22 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: Re: [ntdev] ELAM driver and protected process problem

Yes the final package is signed my MSFT (for production environment).

“Early Launch drivers are signed by Microsoft for qualifying Anti-Malware vendors with a WHQL certificate that contains this EKU.”

So you just sign your package with the appropriate EKU(s) and submit it to MSFT for WHQL signing. Finaly, a package signed by MSFT is returned.
— NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers! Details at To unsubscribe, visit the List Server section of OSR Online at</mailto:xxxxx></mailto:xxxxx>

Yes, the test signing works provided you set the right EKU’s.

Good luck,

mm

On Jun 23, 2017 7:32 PM, wrote:

> My question is however: can this whole scheme be made fully functional in
> a test environment, using only test certificates? i.e. driver embeds
> information about other test certificates that will be used for signing,
> the system boots and binaries signed with those embedded certificates
> actually run as protected processes?
>
> Thanks,
> Dmitry
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

If you read the MSDN page that is mentionned in the first post, you have:

“Note that the certificate chain must include the Code Signing EKU
(1.3.6.1.5.5.7.3.3), but this EKU must not be included in the resource
section of the ELAM driver.”

“Note If EKU information is included in certificate information for the
ELAM driver, then the same EKU must be used when signing your binaries.”

So I would use the following resource:

MicrosoftElamCertificateInfo MSElamCertInfoID {
1,
L"1F8723F9551E864410F7B02B4A4158 3CA1DAA176\0",
0x8004,
L" 1.3.6.1.4.1.311.61.4.1\0",
}

And provide the same EKU(s) for both the driver and the service binary.

Sorry, according to the command that generates the certificate for the service binary, the resource should be :
MicrosoftElamCertificateInfo MSElamCertInfoID {
    1,
    L"1F8723F9551E864410F7B02B4A4158 3CA1DAA176\0",
    0x8004,
    L" 1.1.1.1\0",
}
Only EKU 1.1.1.1 should be added.

Hi H.G,

On 2017-06-23 23:22, hgfhhgf jhgfgbbgf wrote:

Yes the final package is signed my MSFT (for production environment).

“Early Launch drivers are signed by Microsoft for qualifying
Anti-Malware vendors with a WHQL certificate that contains this EKU.”

So you just sign your package with the appropriate EKU(s) and submit it
to MSFT for WHQL signing. Finaly, a package signed by MSFT is returned.
Thank you, I don’t recall that quoted part from the early versions of
the README upon which we acted some time back.

The CA (in our case Symantec) didn’t know how to issue us such a cert
with that EKU to us. Makes sense, since only MS wants to wield that
power. And as you state in the second paragraph MS will do the
(counter-)signing which adds that ELAM EKU.

Third paragraph then mentions “appropriate EKU(s)”, which, I take it
doesn’t include the ELAM EKU, because that’s supplied by the
counter-signature via WHQL, right?

Thanks for your answer. I wish I would have asked here when I
encountered the issue. However, I was certain that only a small subset
of folks reading these mailing lists would even have to deal with ELAM,
so ended up not asking.

Best regards,

Oliver