Credential theft is a huge problem, if you care to look at Verizon Data Breach reports over the years, you will see that use of stolen credentials was lingering at the top intrusion method for quite some time. They also prevalent in APT attacks. And why wouldn’t it be? You don’t need expensive zero days or sophisticated malware when people willingly share their credentials with you and very few organizations have an ability to detect use of stolen credentials.
Windows use and store all kind of secrets like passwords, hashes, tickets and tokens. In previous article we looked into pass-the-hash attack, but there is plenty of other secrets to steal and use for attackers.
Red team perspective
Again we found ourselves with compromised user PC and hunting for credentials. Due to the fact that Windows store secrets in memory of lsass.exe process, we are going to just use mimikatz to dump passwords from memory:
Yes, it’s that easy! Now that we have a clear text password – it is a game over at this point. Any domain user account that wasn’t properly logged-off (even logging off sometimes isn’t helping) will leave their credentials hanging on those computers until reboot. For servers, this could mean user session might hang there for months or even years. How many admins connect via RDP and then just close rdp client on X to reconnect a month later? Okay, you might not be that lucky and have domain admin logged-on on the first box you pop, but you can be creative – I’ve read somewhere about attacker messing with user PC, so user would call helpdesk and ask for help, after helpdesk logged on to this user PC the whole domain was compromised, because attacker dumped password of this helpdesk user and he was a domain admin. Even with simple user account and password you can accomplish a lot.
Why bother with pass-the-hash when we can have a nice RDP session to your servers.
What if we can’t upload mimikatz tool? There is plenty of mimikatz implementations like Invoke-Mimikatz powershell script or meterpreter module that work in memory and avoid any detection.
But let’s assume we have access to secure server that allow only Microsoft signed binaries to execute, think we can’t dump passwords there? One way to bypass it, would be to use Invoke-Mimikatz powershell script, because powershell binary is indeed signed by MS, but we going to use a different method.
Mimikatz can operate offline on memory dumps, so we going to use Sysinternals procdump, which is signed by Microsoft, to make a dump of lsass process and use it to dump creds offline:
By the way, there is even a command with a message to Mark Russinovich in mimikatz, I find it amusing since those two tools work so well together:
When you log in into your system, Windows assign you an access token, which is an object, that contain all security context information about user and his privileges. Those tokens applied to processes and threads in OS, so it could make an authorization decisions.
They are somewhat similar to temporary web cookies and it might be easy for you to think of them that way.
There are two main types of tokens:
Primary – all processes have one and they usually represent a security context of a user who started a process. By default, all child processes and threads inherit parent security context. There is also a filtered token since Vista, which is the same as Primary token, but with admin privileges removed.
Impersonate – this is for threads that need to run under different security context temporarily. It is usually used by servers to check authorization of connected users.
Impersonate tokens has four additional levels, that designates what can be done with it – anonymous, identity, impersonate(double impersonate is confusing, I know) and delegate.
The most interesting ones are:
Impersonate – Those will show up on network logons and usually will be present on various servers. For example, file server need to temporarily login as user that is connecting to it or impersonate.
Delegate – Those will show up mostly on interactive logons and can be present everywhere, where people login interactively, workstations, servers etc. For example, common case for admins is to use some intermediary server – jump server and “double-hop” from it elsewhere, this is when delegate tokens are used.
As you might imagine, if we pop a box and someone is logged on there, we can steal their delegate token and move around just like in pass-the-hash attack or if we pop a server we could stole impersonate token of user and access his files there, run processes under him, etc.
So we poped a box, let’s look at what is running there:
Hm, seems admin is doing some work there too. Let’s steal his delegate token then!
Now, consider another scenario when we poped a box, that share some software over the network share.
Hm, looks like admin user is downloading software from this box. Let’s grab his impersonate token!
As you can see, you can’t use impersonate token for moving around the network, so it is not that useful, but it is give you full access to particular machine under this user – no password needed 🙂
Windows cache and store domain user credentials(10 by default). This is used to validate domain users locally when domain controller is inaccessible, i.e. when traveling.
They stored in a special format, so you can’t use them for pass-the-hash attack – you can only brute force them. It can be a good source of additional domain creds, if passwords are weak.
So, let’s dump them:
Now let’s crack it:
Note the format generated for john by cachedump doesn’t seem to work, just use login:hash format instead.
Windows also store credentials(including domain users) for services, that configured to run under specified user in a special place called LSA secrets. In this place Windows also store a password for user when auto logon feature is configured and domain computer account password. Later is not particularly useful, but account for services can be another source of useful domain creds.
Windows have special vault for storing various credentials, which include saved passwords for scheduled tasks user accounts and saved network passwords. When you check remember password and don’t ask me again or run some scheduled task under user account with saved password – this is where they’re going to be saved. It can also include passwords from Terminal Services, third-party software and web sites.
So, lets go ahead and dump it with mimikatz:
Detecting this activity is hard, since all of this methods involve legitimate credentials or hijacked sessions, so there is nothing to alert on. When Bob in accounting start to accessing systems all over the network, it’s easy to understand that something is wrong, but it’s hard to define that as “rules” or “policies” for existing, static security solutions like SIEM or IDS, especially when we don’t know what is normal and what is not. What is needed – is some kind of behavioral system that can track user logons over time and alert when pattern change. Example of such systems is Microsoft Advanced Threat Analytics and Rapid7 Userinsight
Personally, I didn’t used them, but they look very promising.
Here is some ideas on detection:
Look where privileged accounts log in over the network. Track logon types 3 and 10. You need to answer the following questions: 1) Where does admin logins coming from? 2) Where does admins connecting to? To answer those: Filter on account name and aggregate on Source Network Address or Workstation Name. Review them periodically. Pay attention to after hours logons.
In Windows 2012 logon logs now include impersonation information that can be useful in tracking access token usage. Unfortunately, it wasn’t backported to 2008\7 environment.
Look closely at VPN logs – attackers like to use stolen creds with VPN. People usually log in mostly from the same places like home computers and another office. You could try to script some stuff like collecting source Ips and geolocation for each user and alert when it suddenly changes, of course it won’t work if you have lots of sales people traveling all over the world, but still better than nothing.
Alert on common names of tools like mimikatz.exe, wce.exe and the like. Of course, it is trivial to bypass, but it doesn’t require much effort on your part, so why not? Might catch some lazy hackers. Don’t forget tools like procdump too.
For invoke-mimikatz powershell script log powershell as advised in my previous article
AV nowadays is detecting those tools, so alert on your AV event for those tools, as it could mean attacker compromised host and trying to move deeper at this very moment.
Enable command line logging and alert on common options like sekurlsa, as those is harder to change.
Use yara rules to detect those tools more accurately. Benjamin Delpy was nice enough to write them for mimikatz detection(included with mimikatz).
Alert on attempts to dump a registry like reg save HKLM\SAM. There are ways around this, but still useful to monitor.
Monitor for installation of new services – event 7045 in System log, since some tools rely on them to work.
Alert on injections in lsass.exe process – monitor CreateRemoteThread events with Sysmon and alert. It won’t work with mimikatz, but you can catch wce for example:
Unfortunately, many tools operate in memory only and tools for live memory detection just isn’t there yet, so there is no way to detect those.
Honeypots is a powerful concept to catch attackers by luring them to attack and compromise fake servers. The concept is easy, very powerful and can be extended to pretty much anything. I am a big fan of internal honeypots, but this is a topic for another article.
Turns out there is also a so called “Honey hashes” – fake in memory credentials, that attacker will see when he dump passwords in memory. Since they don’t exists, any attempt to use them will result in dashboards lit like a Christmas tree. It is a very cool idea and simple to use, so I highly recommend to make use of them, because logs doesn’t help us much with detection. There are ways to detect those, for example, attacker could check first, if such user is exist by querying AD. But you can go further and create a real account with all network access disabled for him(just don’t make him an admin 😉 ), that way it will be much harder to spot a trap. Hell, you could even create a full fake employee with convincing story, manager and welcome email from HR if you really want to. Just try to make a realistic AD attributes for him, as it is one way to spot those kind of users.
Deception and trickery goes a long way with honeypots.
Okay, let see those honey hashes in action.
To create them you have an option to use runas command like this:
runas /user:microsoft.com\administrator /netonly cmd.exe
or you could use the following powershell script
Please note, that you have to leave cmd.exe running with runas command for credentials to stay in memory, they will be removed as soon as cmd.exe terminates. Powershell script does the same, it just hides cmd.exe.
Let’s try the first method and dump the passwords with mimikatz:
Here is our fake admin user. Cool, huh? And now let’s try to log in under this admin user.
Hm, why it didn’t work, attacker might wonder? But at this point – it is already too late for him.
On DC it generated the following log message:
Let’s try psexec:
And here is what in logs:
Depending on how access was attempted, there will be different logs generated, so just alert on Logon Account with your fake user name appear anywhere in all event ids. So, make sure you are collecting all additional authentication logs, not just 4624 and 4625.
To push this over domain you could use powershell script mentioned earlier or create a logon script based on runas command.
You can also fill Credential Manager, create services and scheduled tasks with fake credentials in a similar fashion.
Some general advice on mitigation:
Use two factor authentication – two factor authentication, such as smart cards can prevent from some credential theft methods.
Password complexity and rotation – complex passwords and regular rotations of them can limit window of opportunity for an attacker.
Force logoff for idle RDP sessions – Lots of methods outlined depend on existence of user sessions, if there is no user sessions – there is nothing to steal. So enforce an auto log off, at least for admin users, so they don’t leave they session’s hanging forever. Just account for long running processes that admins might run within RDP. You can do this by configuring the following GPO settings:
Computer Configuration\Policies\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Session Time Limits
Network Segmentation – We already touched on this, don’t let anyone connect to anyone inside the network. Segment it based only on a real need.
Settings hardening – use settings like:
to have more granular controls over who can log in where and how.
Protect privileged accounts – protect all privileged accounts, ideally, don’t use them for anything other than working on domain controllers.
In addition to this, recommendations from pass-the-hash article can be applied here as well.
Now, to a more detailed mitigations.
In windows 8.1/2012 credentials is no longer stored in memory in clear-text form, by default. So dumping clear text passwords from memory is no longer possible. This was back-ported to 7/2008 in KB2871997, so install it ASAP. However, you need to manually disable storage of clear text passwords by setting the following registry key UseLogonCredential to 0, located at:
Also, it is good idea to monitor access to this key, since attackers may try to change it back to 1 and dump clear text passwords again(to change it – reboot is required).
This patch is also bring some fixes to ensure that credentials is cleared after log-off from memory.
Here is mimikatz on a patched system:
As you can see – no passwords there.
As you might noticed, those tools rely on ability to inject itself into lsass process, so on Windows 8.1/2012 Microsoft provide ability to run lsass.exe as protected process as explained here
At first glance, this looks like a complete fix, unfortunately it isn’t. Protection is guaranteed by kernel, so anything running at kernel level can disable this. Because mimikatz includes a kernel driver with valid, but expired signature – it is able to bypass this protection and simply remove protection from the process. Why can it do that with expired cert is a really good question, though. Turns out, this is how code-signing certs work, here is quote from Comodo CA:
Timestamping ensures that code will not expire when certificate expires. If your code is timestamped the digital signature is valid even though the certificate has expired. A new certificate is only necessary if you want to sign additional code. If you did not use the timestamping option during the signing, you must re-sign your code and re-send it out to your customers.
So, you basically sign it once and it will be trusted forever, even after expiration as long as the code is not modified. Not sure, if revocation affecting this or not.
However, it is indeed broke other tools:
And even procdump approach:
This was fixed in Windows 10 with Credential Guard feature, check this for more details.
Attacking tools can be a valid approach, as most attackers will be unable to do anything without those tools.
Let’s see how AVs deal with mimikatz:
Not bad. But I find it interesting, that Symantec does not detect it.
What about popular powershell version?
Well, not so good…
Let’s look at WCE:
Again, not bad, but once again Symantec and Sophos do not detect it.
Well, I wouldn’t count on AV too much, as there is just way too many ways around them, but wouldn’t discard them completely either.
For delegation tokens mitigation is simple – just use account option:
for your privileged accounts. Then delegation token would not be passed to systems:
However, it is not feasible to restrict delegation for all user accounts and it is not covering Impersonation tokens, so you could still steal those.
It is impossible to completely protect from this, because it is simply how Windows authentication work by design. So, you just should be aware that tokens can be stolen and protect at least privileged accounts.
Simply disable caching of credentials for most users, except those, who travel a lot via GPO:
Then there would be nothing to steal:
LSA Secrets and Credential Manager
There is no way you can actually prevent stealing credentials from LSA secrets and credential manager. However, you can greatly restrict access for those accounts, if there is a legitimate need to run scheduled tasks or services under domain users.
Credential theft is a tough problem to solve. We can’t take back decisions made with SMTP protocol that allow spoofed senders, same can be said for design decisions made for authentication subsystem for Windows. Once it is deployed – it is there to stay. Good news is that Microsoft works on fixing those issues and each new OS version is better protected by comparison. However, the bad news is exactly this – you have to upgrade, which leaves a lot of networks in a sad state. In those cases you need to focus heavily on detection, which is itself a big problem too.