Does anybody know of some sample code that can be used to verify the signature of an executable from a driver? I am looking for a way to determine if the caller that opened my driver is who I expect it to be. I saw a thread on NTDEV that hinted at a way but it references functions that I cannot find any information on (other than dissasembling them from windbg):
The first question is what are you trying to do really? Note in the
thread you reference the OP never did answer the real goal of what he
wanted to do. There is a lot of discussion on this forum in the past of
finding who is calling the driver, and if look back you will see most of
the schemes once the real goal is defined are worthless.
> Does anybody know of some sample code that can be used to verify the signature of an executable from a driver? I am looking for a way to determine if the caller that opened my driver is who I expect it to be. I saw a thread on NTDEV that hinted at a way but it references functions that I cannot find any information on (other than dissasembling them from windbg): > > http://www.osronline.com/showThread.cfm?link=196613 > > Any help would be appreciated.
I think he did define what he wanted to do. If you have a driver that interacts with a windows service by sending FSCNTL to it you may want to make sure that the caller sending the FSCNTL is your service and not some malware trying to mess with you. The way I would like to do this is to get the signature from the calling executable and verify that it was signed by me and has not been corrupted. (Note that I do not really need to know if Microsoft trusts the signature - just that it is my signature)
So any change to the service even a trivial one means creating a new
driver? Duh, did that once when I could not convince a client how
stupid that was, they quickly demanded I remove it, and then got pissed
that I charged them for the work and for removing it. Consider having a
handshake model that allows you to figure out if the client is the right
one. Remember it is pretty easy to create a helper driver for another
application that will get the impersonation right so that your driver
checks your service but the request comes from an unauthorized source.
> I think he did define what he wanted to do. If you have a driver that interacts with a windows service by sending FSCNTL to it you may want to make sure that the caller sending the FSCNTL is your service and not some malware trying to mess with you. The way I would like to do this is to get the signature from the calling executable and verify that it was signed by me and has not been corrupted. (Note that I do not really need to know if Microsoft trusts the signature - just that it is my signature)
Why does it require creating a new driver? If the updated service is signed and the driver can check the signature of the service in a generic way (for instance getting the certificate blob from the PE header as mentioned in the post I referenced) I do not see why a new driver would be required.
> Why does it require creating a new driver? If the updated service is signed and the driver can check the signature of the service in a generic way (for instance getting the certificate blob from the PE header as mentioned in the post I referenced) I do not see why a new driver would be required.
No, as I said only if it is signed by me. If the service is updated it would be signed with the same certificate as the previous version so all I need to know if it was signed with that cert and that it has not been changed since it was signed.
This is a classic case of PKI validation of private/public keys; there’s a
ton of literature on how to do this reliably. I worried about this about
a decade ago when I was involved in some computer security work, and I
used an introductory textbook on PKI to figure out how to do it right. It
was quite tricky, and our PhD cryptologist sent my first half-dozen
solutions down in flames. It boils down to a problem of maintaining the
privacy of the private key the driver needs to verify the integrity of the
communication. Most security models assume the other half of the process
takes place in a machine both distant and secure relative to the machine
generating the encryption; when both are the same machine, and in the
absence of a trusted core to manage certificates, it got a lot trickier.
Unfortunately, I can’t really talk about the solution. Partly because it
was ten years ago, and partly because the solution was a key piece of IP
for the company I was consulting with. Although the NDA has long since
expired, I feel I should honor it. But bottom line is: get a good
introductory PKI textbook. Unfortunately, mine was the property of the
cryptologist and I returned it to him when my contract ended.
joe
No, as I said only if it is signed by me. If the service is updated it
would be signed with the same certificate as the previous version so all I
need to know if it was signed with that cert and that it has not been
changed since it was signed.
Even just that would already be great to have. The way I see it, it’s a
missing piece from the puzzle.
By signing kernel mode code you have at least a reasonable guarantee that
the software being loaded has not been tampered with. Applications that have
been tampered with will still load, and of course WinVerifyTrustEx from
usermode can easily be hooked. The verification needs to take place from the
trusted environment.
If one could extend that trust to the calling application among other
things, one could create a software protection mechanism that “works” by
making the application heavily dependent on the driver. Then for an attacker
to make a tampered application work, it will require so much work that it is
basically an entire rewrite.
I have been thinking about creating user mode DLLs, adding DllInitialize and
DllUnload kernel routines to them and faking them to be kernel mode DLLs so
their trust can be verified, but it’s not going to be enough to cover the
holes.
//Daniel
“Don Burn” wrote in message news:xxxxx@ntfsd… > So any signed application is ok to call your driver? > > > Don Burn > Windows Filesystem and Driver Consulting > Website: http://www.windrvr.com > Blog: http://msmvps.com/blogs/WinDrvr > > > > > “xxxxx@yahoo.com” wrote in message > news:xxxxx@ntfsd: > >> Why does it require creating a new driver? If the updated service is >> signed and the driver can check the signature of the service in a generic >> way (for instance getting the certificate blob from the PE header as >> mentioned in the post I referenced) I do not see why a new driver would >> be required. > >
The joke of course is that revocation doesn’t work, except for specific end
certificates. You can’t really revoke trust in the Microsoft root for
instance.
However so long as your driver knows who published it, and precisely what
publishers of user-mode software you want to trust (Microsoft+yourself),
and you have some means to prevent other publishers from placing their
code in your process, you are okay so long as you can always release
drivers and UM software at the same time (you will have to deal with your
own cert expiration more creatively otherwise).
You can write kernel code to verify embedded authenticode signatures from a
driver - its documented enough and there is enough support in the kernel
Ps/CNG interfaces to do this (yes this means PE parsing, X.509 parsing
etc., there is no high level WVT() to rely on that I’m aware of at least).
The problem is that most in-box software is not embedded signed, it is
signed by catalog files that are squirreled away in a catalog database
somewhere. The NTloader can validate files against the catalog database
(you can catalog sign a boot driver - just not a good idea from a
performance standpoint), however I’ve not seen enough official/unofficial
documentation that a reasonable implementation could be done even if you
where not inclined to be concerned about how official it is.
t.
On Wed, Jun 27, 2012 at 4:17 AM, Rod Widdowson wrote:
> +1 to everything Joe says. > > Remember also that if you do not have a strategy for revocation you do not > have a solution. > > — > NTFSD is sponsored by OSR > > For our schedule of debugging and file system seminars visit: > http://www.osr.com/seminars > > To unsubscribe, visit the List Server section of OSR Online at > http://www.osronline.com/page.**cfm?name=ListServerhttp: ></http:>
The joke of course is that revocation doesn’t work, except for specific
end certificates. You can’t really revoke trust in the Microsoft root
for instance.
Unfortunately, the joke is a little more profound than that. At best
all you will ever succeed in doing is to verify the integrity on disk of
the main executable image from which the process ostensibly was started.
Verification occurs on the putative process image mapped as a data
section in memory. Verification doesn’t prevent someone from modifying
the process image after it has been loaded. Nor does prevent a
malicious entity from injecting code into your “trusted” process and
doing whatever they damn please.
If you think this is going to provide “security”, note that it is going to
be reasonably easy to spoof.
What makes your program so special? Note that ACLs on your device are
probably going to give the same answer as a complex hack of checking certs
from the kernel. And they exist, are documented, and supported.
Note: if anyone can run your app, anyone can call your driver. So
security doesn’t matter. If, on the other hand, only restricted people
can run your app, then ACLs on the app guarantee that only they can run
it.
I suspect you are trying to build a complex solution to a problem that was
solved decades ago.
joe
Does anybody know of some sample code that can be used to verify the
signature of an executable from a driver? I am looking for a way to
determine if the caller that opened my driver is who I expect it to be. I
saw a thread on NTDEV that hinted at a way but it references functions
that I cannot find any information on (other than dissasembling them from
windbg):
The fact that it is a target for malware is good enough for me (without going into details, it *is* a target).
Also, regarding your comment “It boils down to a problem of maintaining the
privacy of the private key the driver needs to verify the integrity of the
communication” - why does it need the private key? My understanding is that the public key is all it needs.
So your assertion is that ACLs are as good as it gets and there is no point is at least making it a little harder than getting the correct access?
“George M. Garner Jr.” wrote in message news:xxxxx@ntfsd… > Unfortunately, the joke is a little more profound than that. At best all > you will ever succeed in doing is to verify the integrity on disk of the > main executable image from which the process ostensibly was started. > Verification occurs on the putative process image mapped as a data section > in memory. Verification doesn’t prevent someone from modifying the > process image after it has been loaded. Nor does prevent a malicious > entity from injecting code into your “trusted” process and doing whatever > they damn please. >
That is true, a process can modify the address space of another process with functions like WriteProcessMemory. There is however a principle difference here, the process needs to be altered at runtime, there is no way anyone can crack the application by patching or rewriting the binary.
This gives the protector a very clear advantage because it can protect itself from both kernelmode and usermode, it can be made fairly trivial to require the attacker to execute kernelmode code as well, which in turn requires a signature which can then be revoked. Possibly this can be made waterproof with help of a file system filter so that in case the authenticity of the process can be guaranteed you can have an uncrackable protection scheme, which means equal to what Windows provides to prevent unsigned kernel mode code from executing.
In any case by guaranteeing that a binary on disk has not been tempered with you can raise the bar exponentially high and you have a very principle advantage. I think it’s very interesting what Tracy said, that it can be done from kernel mode. Why there is no high level kernel function provided to do the work is not clear to me.
The entire protection model means you have to rely upon the entire CA chain. MD5 checksums have been known to be attackable for a while, but in this case they found and exploited a collision so they could install anything.
Once compromised, a system such as this is not trustworthy. That’s why we now have trusted boot logic in Windows 8 boxes - so that the validation is done by the bootstrap loader, etc. But if someone compromises the private key (or *gasp* finds a checksum collision for it - although that’s much harder with SHA than MD5) then all bets are off.
Thank you all for your responses. It is an interesting discussion.
I am still interested in finding out if this can be done. Regardless of whether it is the right solution for what I wanted it for I am curious to see if all the parts are there. The CNG functions will run in kernel mode and there is a BcryptVerifySignature function but I have not found any examples that show how to use it to verify an executables signature (only examples for signed messages).
Clearly Microsoft verifys signatures in kernel mode so there must be a way.
There is a way, but it largely depends on you doing the heavy lifting,
and the crypto aspects are only part of the full solution.
The problem space here is similar to the one that Win8 is sort of tackling.
Its not an issue of protecting kernel resources from particular users, its
an issue of protecting kernel resources that provide services to user-mode
software that effectively have ring0 privileges when using those services.
That is not something you should simply protect behind an ACL because then
your driver becomes the attack point, as the mear existence of malware on
the NT platform proves, its not hard to get users to run your code. You
might argue that drivers should not be providing services for user-mode
code that provides such privilege, but I honestly think that is simply
naive. It doesn’t even have to be an AV application we are talking about.
Take for instance the scenario of a user-mode file system. The user-mode
portion may contain complex/risky code that simply doesn’t need to run in
kernel. However to avoid dead-locks, the user-mode code will need to
communicate with a driver peer to open files, perform reads and writes etc.
Your driver peer without some sort of application verification and defense
mechanism can simply become the next boost into kernel mode for some
enterprising malware author. I wouldn’t be surprised to learn that this is
happening with existing commercial products that implement similar patterns
today (not my area though - I read about it on slashdot like the rest of
you).
t.
On Wed, Jun 27, 2012 at 3:48 PM, wrote:
> Thank you all for your responses. It is an interesting discussion. > > I am still interested in finding out if this can be done. Regardless of > whether it is the right solution for what I wanted it for I am curious to > see if all the parts are there. The CNG functions will run in kernel mode > and there is a BcryptVerifySignature function but I have not found any > examples that show how to use it to verify an executables signature (only > examples for signed messages). > > Clearly Microsoft verifys signatures in kernel mode so there must be a way. > > — > NTFSD is sponsored by OSR > > For our schedule of debugging and file system seminars visit: > http://www.osr.com/seminars > > To unsubscribe, visit the List Server section of OSR Online at > http://www.osronline.com/page.cfm?name=ListServer >