Protecting Windows Networks – Defeating Pass-the-Hash

Pass-the-hash is popular attack technique to move laterally inside the network that relies on two components – the NTLM authentication protocol and ability to gain password hashes. This attack allows you to log in on the systems via stolen hash instead of providing clear text password, so there is no need to crack those hashes. To make use of this attack, attacker already has to have admin rights on the box, which is a plausible scenario in a modern “assume breach” mindset.

It is not new, but still a lot of people not aware of it and of possible mitigations.

What the problem?

In Windows domain there is a different types of authentication – there is an interactive one when you type your credentials locally or via RDP session and there is a network one when you access various services over the network like shares, sharepoint sites, exchange email and the like. So, when you perform network login Windows actually calculate the ntlm hash from your password and send it over the network for validation with domain controller. This hash is cached and stored in memory of lsass.exe process. This allows the system to transparently log you in to different services without constantly asking you for the password – the SSO feature. Attack is based on this fact – if you can steal this hash and send it yourself you can impersonate user on the network.

Playing for the red team

We got a shell on the box, credentials is usually what we want next to move inside the network.

Good overview of various techniques of how to get creds and hashes available here and here.

So let’s dump hashes:

Since only local user hashes is stored locally it is not much to go on initially.

But we can assume they probably use the same local admin password across all systems, so if we can get the password for this account, then we probably can access all other systems, right?

But there is no need to bruteforce passwords when we can just pass the hash:

This way we can move system to system and compromise whole network.

What if they don’t have a shared password or you’re can’t connect with local accounts?

You could also dump hashes directly from memory which include domain users, so if anyone connected to this PC before with domain credentials, you will have their hash as well.

Looks like admin user was helping our user with some PC issues and logged on with his domain admin credentials to this PC. Now we can pass-the-hash his domain admin account and own the whole network:

What if you don’t get that lucky and won’t find domain admin on the first machine?

You probably get at least one domain user and he can access some other machines too, so you could move around and gather more hashes until you find privileged accounts logged on somewhere. Also think about all those tools that work under domain admin accounts and log everywhere like security scanners.

What else could we do?

Well, there is good chance that some passwords was reused somewhere else.

So, we could try to bruteforce whole domain to find more credentials and go from there.

But wait, we don’t have passwords ourselves, does that means we have to bruteforce our hashes first? Of course not, we can use pass the hash with bruteforce tools too 😉

Detection

To detect this activity you need to look closely at local and domain wide 4624 and 4625 events. Look for authentication done via NTLM, easy way is to look for authentication package NTLM or logon process ntlmssp. There shouldn’t be many of those events unless you have a lot of legacy systems that can only use NTLM.

I also noticed that some tools generate random computer names when passing the hash, so aggregating on Workstation name can be quickly used for detection:

Another indicator is a NTLMv1 of protocol, some tools use v2, so it is not a clear cut indicator, but still useful as it is unlikely NTLMv1 is used in your environment.

To summarize:

Alert on any privileged account login via NTLM, especially built in Administrator.

Alert on any NTLMv1 if you don’t have legacy systems that use it.

Whitelist your legitimate NTLM systems and alert when any not whitelisted systems is authenticating via NTLM.

Hunt proactively using Workstation indicator and network information.

There is also advice on the internet to detect pass-the-hash based on NSA whitepaper, that rely on domain field being blank when passing the hash for domain accounts – don’t use it, since this is no longer true. All tools that I’ve tested correctly populate domain field and you won’t detect anything.

Mitigation

Protect your local admin accounts

Reusing local admin credentials is a bad practice and one of the most commonly abused facts by attackers. We already looked at how to prevent this in my previous article.

Honestly, today attackers probably won’t succeed in passing local credentials due to the remote UAC token filtering(appears to be working even when UAC is disabled) and the fact that in Windows 7 built-in Administrator account is disabled by default. After installing KB2871997 you can’t use other local accounts other than SID 500.

Here is attempt to connect to PC which is configured to deny network access for local accounts:

Protect privileged domain accounts

Restricted Admin mode – there is a new functionality that disallows passing credentials to the host machine when you connect via RDP. So, there is no stored credentials on the host machine and dumping memory won’t give you hashes or passwords of domain users logged with this mode. However, this only works with 8.1 and 2012 Windows. Be aware that enabling this mode allow you to use pass-the-hash attacks against RDP as explained here.

Protected Users group – there also a new special group that enforce Kerberos-only authentication for it’s members effectively preventing pass-the-hash attacks against those accounts. However, it is only work with 2012 domain functional level.

Log off accounts forcefully – Force admins to logoff correctly and not just close RDP sessions on X button. Credentials stay in memory until you logoff. You can do this via GPO settings for RDP service.

Smart Cards

Smart cards can protect you from some types of credential theft, but pass-the-hash is not one of them.

In fact, network based login(except RDP) is not involve smart cards at all. What happens when you enforce smart card login with:

Is that domain controller is going to generate a password and a ntlm hash for your account and then send this hash to your PC. When you going to access some shares it will use this ntlm hash for authentication. So, as you can see it is not really any different when smart card is not used, attacker can still dump this hash and use it. The hash itself is generated when option “Smart card is required for interactive login” is enabled, so the same hashes can be stored potentially for ages. It is a good idea to regularly re-enable this option to generate a new hash. You can use a powershell script to cycle this option periodically, available here.

Disable NTLM

As you can see, there is a lack of real solution unless you upgrade to 8.1 and 2012 Windows. The only true solution is to disable NTLM altogether. This will be hard to do, so your better audit your NTLM usage first. Here is my configuration:

However, it is vaguely documented and working weird. In my testing I wasn’t able to block NTLM traffic to DC for some reason, despite seemingly correct GPO settings. And I wasn’t able to make exceptions work for particular host.

Conclusion

Credentials theft is a huge problem in Windows environment and pass the hash just part of the problem. It is a design flaw, so even with mitigations problem is not solved completely and probably never will be.

There is a couple of mitigations you can apply, but most effective ones require you to upgrade to the last version of OS.