How Windows Defender Credential Guard Works
Okay, lets talk Credential Guard. What is it, why it matters, and how it works.
— Steve Syfuhs (@SteveSyfuhs) December 1, 2020
Twitter warning: Like all good things this is mostly correct, with a few details fuzzier than others for reasons: a) details are hard on twitter; b) details are fudged for greater clarity; c) maybe I'm just dumb.
Credential Guard is a Windows service that protects credentials from being lifted from a machine. Since that means nothing to the vast majority of people let's expand on that.
Credential Guard protects the secrets used by Windows for single sign-on from being stolen and used on other machines.
These secrets are numerous. First, there's your password. You type it in to log into Windows. You exchange your password for a TGT. Your TGT has a session key to get access to service tickets. Historically these secrets were ripe for the taking if you could run code as system.
The attacks fundamentally work something like this. User logs on, downloads something accidentally. Thing finds an EOP, runs as admin, converts admin to system. This thing can now read all memory on the system. Your secrets are in memory. Voila.
But that's not all. Sometimes it doesn't need to be a complicated attack. We have undocumented APIs that let you get access to these secrets too. They've been around forever and we can't get rid of them for historical reasons. We can only make them harder to access.
A good example is SSO in Java client applications. If a java application wanted to use the current users logon session to access resources without prompting, the end user had to toggle an undocumented registry key that let java steal the user's TGT session key.
Or there's this thing called Credential Manager. If you received a prompt, say for RDP or accessing a file share outside your domain, and clicked save credentials then those credentials go into credman. All you have to do is ask credman to give you those creds and it will.
These were all necessary at one time or another and as our threat models matured we realized there was clearly a security gap here. The problem of course is that our security boundary is system|everything-else. Once you got on as system you could do whatever you wanted.
We attempted to solve this with LSA Protected Process mode, which is an incredibly clever way of preventing anything from being loaded into the LSA process that wasn't signed by a special CA.
This was an important step because loading stuff into LSA was a major attack vector and it'd be a huge win if we could nip that. And it was and is reasonably effective for certain types of attacks. Here's where people "but but mimikatz" me.
LSAPPL isn't perfect. It has weaknesses. If you can make it into the kernel and modify process stuff you can turn it off with the flip of a bit. But you don't build a house with just a hammer. It's one tool of many. Enter Credential Guard.
For decades there was nothing outside the kernel security boundary. Kernel talked to hardware and had access to everything. Ring 0. Nothing lower than ring 0.
Until someone invented the hypervisor, which is just a fancy way of saying "hey lets run multiple kernels on a single machine and doll out access to hardware with us controlling it instead of the kernels." Ish.
It took a generation or two but our hypervisors pretty much let you run all VMs on bare metal now. The hypervisor is this tiny tiny thing that just acts as a resource mediator now and this mediator allows these VMs to stay isolated from one another.
One VM can't peek into another's memory. Can't look at it's processes, can't communicate with it except through external stacks like ethernet, can't do any of that. Full and complete isolation.
That therefore means anything running in a VM kernel doesn't have a full view of the world, and malicious code is pretty much stuck there.
So someone had the brilliant idea: "hey, what if we moved all the critical security-sensitive stuff into a separate VM?"
Enter VSM: Virtual Secure Mode. Or VBS: Virtualization-based Security.
This might seem confusing because your Windows client doesn't run in a VM. It runs on bare metal. You inserted a DVD^H^H^H USB stick and installed it on the physical hard drive. And things running in kernel on the bare metal can access all things on the bare metal. What gives?
As it happens, that's not strictly true anymore. Windows these days runs in a VM on the hypervisor. 😲
Sort of.
It doesn't exist as a VHDX or anything like that. All the resources are physical, but they're now governed by the hypervisor.
So what that means then is if you're running VSM/VBS with Credential Guard or any other service relying on it, you're actually running two virtual environments on your machine.
These are...hybrid VMs if you will. They exist as different modes of the same Windows installation. You have two versions of Windows running side by side. Except one is more locked down than the other.
These VMs are isolated into things we call Virtual Trust Levels. VTL 0 is normal world. It runs all your usual stuff. Your kernel, LSA, explorer, your browser, etc. Regardless of whether you have VSM running or not your stuff runs in VTL 0.
But with VSM enabled we have another VTL -- VTL 1. This is secure world. It runs a different instance of your kernel, but highly optimized for just a special purpose, as well as a separate user mode also highly optimized for a special purpose.
Think of VTL 1 as a side kick. Not quite the hero. Doesn't do everything the hero does, but is super useful in a pinch.
We'll stop using this analogy now because that's as far as it can be taken.
So lets recap. Have secrets living in user mode, can be accessed by evil things running as the user with a little bit of effort. Have virtual secure mode, cannot be accessed by evil things running as the user.
...
...
...
...
With me so far?
What if we moved those secrets out of user mode and into virtual secure mode so evil things can't access them?
And so Credential Guard was born.
Credential Guard is this thing called LsaIso.exe. It's the isolated version of LSA because it lives in Isolated User Mode, AKA user mode of VTL 1 (as opposed to regular user mode in VTL 0).
Processes that run in VTL 1 IUM are normal processes. They're exe's compiled to x64. They're just special in that they don't get to rely on a lot of stuff normally found in Windows.
Because VSM runs as this hybrid thing, it shares certain resources between VTL 0 and 1, such as the process list. The IUM processes are projected into your process list, which is why you can see it. Sorta. It lets you see some things, but not everything. Also can't kill 'em.
When your VTL 1 starts up it eventually starts LSA. LSA is this thing that manages all the security on your machine, and is where all your secrets normally live in memory.
As it starts up LSA checks for Credential Guard. One of the shared resources between VTL 0 and VTL 1 is a communications channel -- RPC. It's always RPC. Even when it never leaves the box it's RPC or it's special friend LPC, but it's still RPC.
And this communications channel is locked down. Only VTL 0 SYSTEM services can communicate over it, which LSA is, so your run of the mill evil thing can't talk to it. It requires a bit more effort if you're evil.
Anyway, this RPC channel is built in such a way that it acts as an oracle. You ask it a question and it gives you a weird answer. This is important because we have to be careful about what it leaks into normal user mode because evil things.
What kind of questions can you ask it? Well, lets walk through a logon first for context.
Way back in the beginning of time I wrote that thread about password logon. You type your password into the textbox. This textbox lives in VTL 0 normal user mode. What Happens When you Type Your Password into Windows? (syfuhs.net)
The password is passed to LSA, and LSA hands it off to Credential Guard. You're doing Kerberos so you also pass a flag saying "heeeeeey can you give me the stuff I need to make Kerberos work".
And so Cred Guard does. You gave it some data, told it to encrypt it using the password, and out came the encrypted goo and a handle to the secret. You never see the secret again.
This is one of those important things to note: the password is unprotected for a brief period of time, but once it's in Cred Guard it's safe, as opposed to stuck around in memory forever.
Anyway, no LSA has this encrypted goo. Can't reeeeeally do anything with it so it fires it off to KDC. The KDC does it's normal Kerberos thing and returns a TGT encrypted to the user's password.
Aha, but LSA doesn't have the password anymore. What do? LSA passes this encrypted blob to Credential Guard, plus the handle to the password and asks Cred Guard nicely to decrypt the blob. And it does, returning to it *most* of the important stuff.
The one thing it doesn't return to LSA is the TGT session key. Or rather, it returns the session key but encrypted to a key only known to Cred Guard, so if someone could steal the blob out of memory it'd be useless.
Now the machine needs a service ticket to itself, or the user is opening a file share or whatever it is people do.
LSA has this TGT (useless on it's own) plus the session key (super important) that's been encrypted to a key it can't use. LSA fires a request off to the KDC and KDC does it's thing, responding with a service ticket, encrypted to the TGT session key. Can you guess what's next?
Only the session key can decrypt to response, and only Credential Guard can decrypt the session key. So LSA hands it both and asks it nicely to decrypt the thing. It does, returns the decrypted service ticket to LSA, which hands it off to the caller, and then off to the app.
And that's all Credential Guard does. You ask it a question and it gives you an answer. But you have to ask the right question.
This is why these legacy and annoying APIs don't work anymore. They ask the question, but don't supply all the right details and get back a weird answer. It's not exactly wrong, just...not useful.
This is also why certain things are outright broken by design. Legacy protocols like MS-CHAP that make it super easy to reverse the password through cryptoanalysis are blocked because it breaks the guarantee Credential Guard provides.
Not to mention unconstrained delegation. We're trying to protect your TGT from being stolen and used on other machines. Unconstrained delegation is Stealing Your TGT as a Service (PS, that's the name of my new consulting firm).
Now all of this hinges on the fact that you have a user mode process in user world communicating with secure world. As an attacker why don't I just turn that off?
Well, yeah. You can do that. At some point you can tamper with the machine enough that it's not really your machine anymore. We can make it a lot harder to do though.
Remember LSA PPL? It prevents stuff from tampering with LSA. That goes a long way to protecting the LSA, but isn't perfect because you can bypass it through the kernel. Thanks to another VSM feature you *can* protect it: HVCI. HVCI watches kernel mode memory for modifications.
We did a whole thing about this last year: Comprehensive protection for your credentials with Credential Guard and HVCI - Microsoft Tech Community
Anyway, that's Credential Guard. It's a relatively small feature, but an incredibly useful tool for protecting your user secrets.