Protecting Windows Networks – Kerberos Attacks

MEDIA NOTE: This is not a new flaw, just a good write-up! I don’t know why media reporting this as a new flaw.

Kerberos is an authentication protocol that is used by default in Windows networks and provide mutual authentication and authorization for clients and servers. It does not require you to send a password or a hash on the wire, it is instead rely on a trusted third party for handling all the details.

Although, it is considered a secure protocol, it has some flaws in Windows environments with devastating consequences.

How does it work?

Kerberos is a rather complex protocol, so let’s just have a look at how a typical authentication looks like:

kerberos_scheme

 So, we have the following components:

  • User – which is called User Principal in Kerberos terminology.

  • Service – which is called Service Principal in Kerberos terminology.

  • KDC(Key Distribution Center) – which is a central entity responsible for all the authentication tasks. It is itself consists of Authentication Server(AS) and Ticket Granting Server(TGS). This service is run on domain controllers.

  • Ticket-Granting Ticket(TGT) – this ticket is granted by AS for user after initial authentication and is necessary to request service tickets. It is cached on user PC and valid for 10 hours by default. Basically, it is an object that represent a user in kerberos after he is authenticated. It is also include information about user group membership in so called Privileged Attribute Certificate(PAC).

  • Service Ticket – this ticket is granted by TGS when user want to access a particular service and used to authenticate to this service. It is cached and valid for 10 hours too.

If you’re still confused about Kerberos or interested in more details – I’ve suggest to look here and here.

Here is the important facts to us:

  • Secret keys derived from user passwords, this includes KDC secrets and service secrets too.

  • Secret keys as well as tickets is stored in memory.

  • Secret keys that use RC4 algorithm is not salted and use NTLM hash of the user as a key, so NTLM hash = RC4 secret key. Yeah, this will be your WTF moment.

  • KDC use secret key derived from krbtgt user password, although account itself is disabled and not used.

  • krbtgt user password is rarely changed(only when domain functional level changes, sometimes) after initial installation, so it stay valid for years. What is more interesting, is that previous password is valid too. By the way, transition from 2008 to 2012 is not changing a password, only from 2003 to 2008\2012.

  • TGT ticket is encrypted and PAC data is signed by krbtgt secret key.

  • User account validated only after TGT is more than 20 minutes old. For example, if account is disabled or even exist.

  • Service ticket is encrypted and PAC data is signed by service account secret key, except KDC PAC data which is signed by krbtgt.

  • PAC data in service ticket is rarely validated. Usually, if service running under SYSTEM it is not validated.

Attacking the Kerberos

Pass-the-key(Overpass-the-hash)

How do we prove to KDC, that we who we are and request a TGT? Well, we just encrypt current timestamp with our secret key. That’s how a normal process looks like. So, if we have an access to the key – we can repeat this process on behalf of the user and gain legitimate kerberos tickets, and thus access. Essentially skipping the part of kerberos authentication, where user secret key is created from his password. Recall that rc4 secret key is an NTLM hash of the user account, so we can reuse it any time we want, once we get it. It is very similar to pass-the-hash, hence the name. Of course you can also do this with newer AES keys, just NTLM hash is more convenient and there are multiple ways to obtain it.

Okay, suppose we’ve obtained an NTLM hash, but turns out this system have ntlm disabled:

kerberos_failed_ntlm

All hope is lost? We can’t pass-the-hash? Of course not!

Let’s use this NTLM hash in pass-the-key attack:

kerberos_ptk

And what you will see on the wire is the normal kerberos authentication:

kerberos_ptk_normal

You will also see, that we are indeed using RC4 for session key:

kerberos_ptk_rc4

Of course, if you are in position and have someone logged on – you could just steal their AES key too:

kerberos_ptk_aes

And then use it the same way:

kerberos_ptk_aes_mimi

Even though we’re under local(we’re not even a domain user!) user account on a completely different computer, we have an admin ticket:

kerberos_ptk_tickets

This way – as long as we have a valid NTLM hash or aes key – we can impersonate those users anytime we want from any machine! And they will stay valid until password is changed.

By the way, if you have trouble with mimikatz(like in pivoting scenario) on the separate machine to carry out this attack – you could also just spawn any bogus process on any machine in the domain, where you’ve got a shell and then just steal a token of this process via meterpreter or something.

Pass-the-ticket

Recall that TGT is representing an authenticated user in kerberos and service ticket is representing an authenticated user for a particular service. Also, recall that they’re cached in memory and valid for 10 hours. This means, if we’re able to steal those tickets and somehow insert them into our own system – we would be able to request any service ticket on behalf of this user or access a service directly with service ticket. Because for the KDC or the service we will look like a legitimate, already authenticated user. This way we can impersonate this user and gain access for the lifetime of the ticket. This will be 10 hours by default, which is plenty of time to do anything we want.

So, let’s do this:

kerberos_ptt_export

So, we dumped all tickets into files:

kerberos_saved_tickets

As you can see, we got a bunch of service tickets(those with LDAP, HOST and cifs in file name) and even TGT(those are with krbtgt in the file name). So, you can then download them to any other machine and re use – to become an admin.

Here is our machine at the moment:

kerberos_ptt_no_tickets

Let’s try service ticket first:

kerberos_ptt_service

And here is what happens now:

kerberos_ptt_service_pwn

And we’ve got access – simple as that!

Of course, we can’t access smb service on another machine – because we don’t have a ticket for this service.

And on the wire you will see that we authenticate to SMB service via kerberos:

kerberos_ptt_service_sniff

Notice that we bypassed steps 1-4 of our kerberos scheme and went straight to 5 and 6.Cool, huh? What if we want to access other machines too, but we don’t have service tickets there?

No problem, we also got a TGT ticket, remember?

kerberos_ptt_tgt

So, let’s see now:

kerberos_ptt_tgt_pwn

Awesome! We successfully got a service ticket for another machine with our TGT.

And here is what you see on the wire:

kerberos_ptt_tgt-Sniff

Notice that we bypassed steps 1-2 of our kerberos scheme and went straight to 3-4 and 5-6.

Golden ticket

Recall that everyone has a secret key and KDC is using krbtgt user account password to create a key. Recall also, that KDC is encrypting and signing TGT tickets with it’s own key – which means a secret key of a krbtgt user account. And don’t forget that TGT contain all the group membership data. So, if we can obtain a secret key of this user – we can create our own TGT tickets and essentially impersonate KDC service. There’s more, since PAC data is also signed by this key – we can also create any user and group information in our TGT, which means we can grant any user any privileges. Pretty cool, huh?

It is incredibly powerful persistence trick, allowing you full access to the whole domain under any user and do crazy stuff like access resources with disabled or even non-existent users.

How can we do that?

It’s just an account in domain controller database, so your obviously need access to DC or it’s data.

After that, you can:

  • Dump it from memory on DC

  • Dump it from ntds.dit database(along with everyone else)

  • Steal it from backups or volume shadow copy

  • Steal it from VM infrastructure, like snapshots or whole disk image of the DC, if they are virtualized.

  • Or just, you know, replicate it by impersonating a DC(all you need is to run mimikatz under admin privileged account). Check this for details.

kerberos_dcsync

Okay, suppose we compromised the DC and dump it from memory:

kerberos_krbtgt_dumped

You can use either aes or rc4 key.

You also need a domain SID – just copy a SID of any user and delete last block with user ID.

Let’s create a golden ticket!

kerberos_golden

So, we created a ticket for user with admin SID and he is also in all the typical admin groups like Domain Admins, Schema Admins and Enterprise Admins.

Note, you can create it on any machine, even offline.

Now, just pass it:

Once again – no tickets:

kerberos_golden_no_tickets

kerberos_ptt_golden

Now let’s try to access something:

kerberos_golden_pwn

The funny thing is – godmode user is not even exist:

kerberos_golden_no_user

Yet, there are tickets for him:

kerberos_golden_tickets

Of course, you only have 20 minutes to get as much service tickets as possible with such users, after 20 minutes KDC will validate account information. But you can create a new golden ticket again and again to have unlimited time, if you really want.

At this point – you can do anything you want, you can simply reuse existing accounts or be extra sneaky and grant some regular user account admin privileges, even though, if anyone look him up – he will not have any. You can even use other user accounts and add them with /groups option, to create a kind of super user that impersonate several other users at the same time.

Silver Ticket

Recall that service ticket created with secret key of either computer account or service account. So, if we know a secret key for this account, we can create forged service tickets to access a service. Since service is usually doesn’t validate PAC data and don’t communicate with DC – we can easily impersonate any user. It is a kind of similar to golden ticket, but limited to specific service.

Computer account passwords is randomly generated and change every 30 days automatically, I think previous one is still valid too, but I didn’t test. You can pull secret keys from memory or get an NTLM hash(rc4 key) from lsa secrets.

So, let’s get a password hash for a computer with kerberos::ekeys command:

kerberos_silver_dump

Now, let’s create a silver ticket:

kerberos_silver

 So, we granting non-existent user silver with domain admin privileges and ticket for this service.

And let’s try to access it:

kerberos_silver_pwn

Once again you can do whatever you want, just like with golden tickets, you just will be limited to this particular service.

Forged PAC

There was also a bug(MS14-068), that allowed to create an arbitrary PAC and insert it into a legitimate TGT ticket, so effect was similar to a golden ticket, but you was able to do that with any domain user and krbtgt user key was not needed. Nice write up is here.

Skeleton Key

Early this year Dell Secureworks reported that they found a so called Skeleton Key malware installed on DC of the victim. This allowed attackers to authenticate as any domain user with a secret password, but it didn’t affect users and they still could logon with their own credentials.

It works by patching lsass.exe process on DC and it was implemented in mimikatz. It is not persistent and reboot of DC will clear it.

To install it, you will need to have an admin rights.

Suppose we got a domain admin creds and want to leave a backdoor, so let’s plant a skeleton key on DC:

kerberos_skeleton

So, now we have a secret password – mimikatz(hardcoded), that should allow us to log in as any user!

Let’s try it:

kerberos_skeleton_pwn

It’s also work for interactive log in, so you could use it for RDP and even physical log in.

Detection

Detecting this activity is a very hard challenge, since we deal with legitimate credentials.

You should heavily focus on detecting tools that used to carry out this attacks and manual monitoring for privileged accounts(this include accounts of executive and other regular employees, who have access to information attacker might want to get). So you would at least have an idea where people regularly logon to and it would be easier to spot a difference.

Check my previous article for more details.

There are still value in logs, so don’t forget to enable logging of kerberos – event ids 4768-4773.

One of the inconsistencies I’ve found is with domain name, when attacker accesses resources as a result of various attacks, so aggregating on Domain name and investigating suspicious entries might be a good idea. Usually, domain name in logs will be in capital letters, but mimikatz send them in lower characters. Take a look for domain names aggregated on a week of data:

kerberos_det_domain

As you can see, events with low count definitely look suspicious and need to be investigated(they are in fact from attacks). However, after testing on real life data I’ve found that is not a consistent indicator as you will have quite a bit of lowercase realms, because capitalization of realm is merely a recommendation in Kerberos RFC. But it still can be useful to slice data into smaller chunks. On a full day of data I’ve got about half a million uppercase domains and about 35000 lowercase ones. Unfortunately, it is still a lot of data to manually look at and it doesn’t necessary mean this is a result of attack.

Mimikatz also leave a signature string in domain for golden and silver tickets – oe.eo, so definitely add this too.

Another useful thing to look for – is use of RC4 cipher, since modern Windows(from Vista) use AES by default and lots of attacks rely on RC4. For this – you need to aggregate on Ticket Encryption Type. You need to look for 0x17 or 0x18 as this means an RC4. 0x12 means AES-256 and 0x11 AES-128. Don’t mind 0xfffffff – this is some kind of code when error is occurred and seen in legitimate, unsuccessful ticket request.

Full table of codes for all options is here.

kerberos_det_cipher

So, unless you have a bunch of XP and 2003 machines or some third party systems – you should never see RC4 used.

Another way to get this data is to monitor network traffic, since most of the meta data is not encrypted, however not much systems support Kerberos. The good news is Bro recently added support of Kerberos traffic and produce the following data:

kerberos_bro

 Unfortunately, not everything is parsed, but still very useful, especially when getting logs is not possible. There is also some problems with the parser, sometimes RC4 detected as AES for some reason.

I’ve also created a wrapper around tshark to detect those attacks. It works, but you need to have no gaps in packet capture. Packet loss or just gaps in kerberos packets ruins the detection and produce a lot of FP as a result. It’s on my github here. It works on any linux machine with tshark version 1.12+

Let’s take a closer look for each attack.

Pass-the-key(Overpass-the-hash)

It is hard to spot this attack, because it’s looks exactly like a legitimate activity process. However there is still some artifacts we can use.

If RC4 key is used – then it can be easily spotted via logs or traffic as described above, granted you have a modern environment. With AES it won’t be so obvious. As mentioned above it’s also leave domain name in lower case, that can be useful for detection:

kerberos_det_ptk_domain

Another thing I’ve noticed, is that Encryption Types is set strictly to a ticket algorithm like only AES 256 or only RC4. This is unusual and easily stand out, because normally OS announce support of all algorithms:

kerberos_det_ptk_enctype

And here is legitimate request:

kerberos_det_ptk_legit

Let’s detect it with our script:

kerberos_script_ptk

If you got matches on AES, it is a very good chance this a pass-the-key. On RC4 it could also match on some legacy systems, so don’t jump to conclusion with it. I say it is pretty accurate, I didn’t get any FP on real traffic.

Pass-the-ticket

Once again detecting this activity is hard. Logs doesn’t help us much here, since there is no obvious artifacts and all you would see a legitimate entries that tickets was requested or access was granted to a particular user. One way to detect it – is to look what people access. If tickets reused somewhere else, you will see, for example, that admin user requesting service tickets from a bob machine and this is weird. So look for a mismatch between user principal and source IP where requests is coming from. If they are reused from the same machine – you’re out of luck, since they look 100% legitimate.

Another thing you can look in logs and in network traffic – is absence of certain Kerberos steps. For stolen TGT tickets there is no AS-REQ and AS-REP steps in traffic and no event 4768 in logs. For service tickets there is no TGS-REQ and TGS-REP steps in traffic and no event 4769 in logs.

Let’s detect them with our script:

kerberos_script_ptt

The key here is to get a complete packet capture without packet loss, otherwise you will get a bunch of FP. Also keep in mind you will have gaps in traffic when you start capturing in the middle of the sessions. It is pretty accurate, but you may get quite a bit of FP due to packet loss.

Golden Ticket

For non-existent users it is fairly easy to spot. You could obviously check all users if they exists or not and alert if you see successful logon with non-existent user(or any other impossible state, like disabled or locked). Another thing to look here is mismatch between Security ID field and Account Name and signature mimikatz string oe.eo in Account Domain.

Here is how it looks:

kerberos_det_golden_event1

This information is get populated in all kinds of logs where those fields is present.

When legitimate user is impersonated, this leaves only Domain indicator:

kerberos_Det_golden_event2

Please note, this signature can change in the future and skilled attackers can fix the code, so it would look legitimate.

We can also use similar detection method as with pass-the-ticket, since there is no AS-REQ and AS-REP steps for golden ticket:

kerberos_script_golden

Silver Ticket

It leaves the same artifacts as golden, so the same detection methods apply. Just make sure you’re collecting events from endpoint computers too, as this leaves no records on DC – all events will be on accessed computers and servers.

Once again we can use detection from pass-the-ticket attack, since there is no TGS-REQ and TGS-REP for silver tickets:

kerberos_script_silver

Forged PAC

This attack also relies on RC4 for getting a forged TGT, so you can look for that. Because it send only rc4-md5-hmac as supported cipher:

kerberos_forged_pac_md5

Another easy thing to look at, is request without PAC. This will never occur in legitimate traffic:

kerberos_forged_pac_no_pac

Let’s detect it with our script:

kerberos_script_forged_pac

Skeleton Key

The simple way to detect it – is to try default password ‘mimikatz’ yourself.

Mimikatz implementation is a kind of downgrade attack, so after installing skeleton key all users will be downgraded to RC4 cipher, so on Kerberos events you will see they will be using 0x17 Encryption Option, so this is already a huge tell. Especially if they used AES keys in the past.

This only relevant to service tickets. Here is how logon with secret password looks like:

kerberos_skeleton_log

So, if you suddenly have a lot of RC4 cipher used – then you’re definitely have a Skeleton Key, especially if it is a modern Windows systems – they will never default to RC4. Other than that, this doesn’t leave any artifacts in logs.

Another way to detect it – is to use the free script provided by Aorato:

kerberos_skeleton_aorato

Yet another way is with our script:

kerberos_script_skeleton

Mitigation

Mitigation of most of this attacks is not possible, as this is simply how Kerberos work in Windows environment. For some attacks, mitigation discussed in previous articles is useful and recommended. For the most part, you need to focus on protecting privileged accounts at all cost, because this is what attackers are after and protecting everyone is not possible. Otherwise you will lose control of your network really fast. The most effective mitigation at the moment seems to be Protected Users group and Credential Guard.

Let’s see for each attack type in detail:

Pass-the-key(Overpass-the-hash)

The Protected Users group prevent storage of keys in memory, so there is nothing to steal for members of this group, but other users will stay vulnerable. Complete mitigation is possible only with Credential Guard. You could also disable RC4 cipher(it is enabled by default even in 8.1/2012) if you don’t have any legacy systems(no XP and 2003) to prevent at least RC4 based pass-the-key, but it is hardly a real mitigation because they can use AES keys just the same. For 7/2008 this requires KB2868725.

Then use the following GPO settings:

Network Security: Configure encryption types allowed for Kerberos

kerberos_disable_rc4

And here is the result:

kerberos_ptk_disabled_rc4

Pass-the-ticket

Credential Guard is the only possible mitigation, Protected Users can’t help with this due to the need to store tickets in memory for normal operation.

Golden & Silver Ticket

Mitigation for this type of attacks is not possible. Only remediation steps – see below.

Forged PAC

This bug was fixed in KB3011780, so install it ASAP on each DC. I think 2012 DC is not affected by this.

Skeleton Key

I think Protected Users should help with this since it deny usage of RC4.

You can also disable RC4 cipher(described above) and it will break skeleton key even if it is installed, however keep in mind that attacker can enable support of RC4 back, so you need to keep monitoring it.

kerberos_skeleton_key_broken

Remediation

Remediation for those types of incidents is costly and time consuming. Since Kerberos doesn’t allow revocation of tickets, all remediation steps should assume that attacker still have access with tickets and wait out on expiration before any active action. You quickly lose control of domain and your network after compromise, allowing unlimited persistence for an attacker. So, you could take a risk and recover the same domain or rebuild the whole domain and forest, as this is the only way to be sure that attacker doesn’t leave any backdoors.

Pass-the-key(Overpass-the-hash)

If you’re suspecting that the key was stolen – you need to change the password(this will invalidate the key) of the account and possibly disable it too. You also need to forcibly logoff all active sessions from this user to be sure. However, it doesn’t affect granted tickets – see below.

Pass-the-ticket

The only thing you can dois to clean cached tickets with this script and wait out expiration time. However, this doesn’t cover cases where attacker could simply reload ticket from file or use it on machine outside your control. Of course, changing password of affected accounts is necessary too in case he got a key.

Golden Ticket

You need to change a krbtgt user password twice in a rapid succession to prevent any more tickets. You can also change it frequently yourself to limit potential exposure and window of opportunity for an attacker. Please note, this can cause disruption in access, so plan ahead. You can use MS provided script for this, available here.

Silver Ticket

You need to change a computer password – you can do this via Users and Computers MMC, netdom or Reset-ComputerPassword powershell script. I think previous password is stay valid too, so this means you need to reset it twice. However I didn’t test it. If your service is running under dedicated user account, then reset his password.

Forged PAC

Patch DC and use remediation from pass-the-ticket.

Skeleton Key

Reboot the DC. You might also reboot it time to time, just it case.

Reference

https://adsecurity.org/?p=556

http://www.slideshare.net/gentilkiwi?utm_campaign=profiletracking&utm_medium=sssite&utm_source=ssslideview

https://www.youtube.com/watch?v=-IMrNGPZTl0

https://www.blackhat.com/docs/eu-15/materials/eu-15-Beery-Watching-The-Watchdog-Protecting-Kerberos-Authentication-With-Network-Monitoring-wp.pdf

https://www.blackhat.com/docs/us-15/materials/us-15-Metcalf-Red-Vs-Blue-Modern-Active-Directory-Attacks-Detection-And-Protection-wp.pdf

25 comments

  1. […] The flaw cannot be fixed and the only solution is to introduce and use Microsoft’s Credential Guard program to prevent passwords from being stored in memory, according to his extensive blog post. […]

    Like

  2. Why did you not make references to Microsoft’s Mitigating Pass the Hash and Other Credential Theft whitepapers they Microsoft published on this for a number of years now (http://www.microsoft.com/en-us/download/details.aspx?id=36036)? There are many mitigations Microsoft lists in detail, and use of IPsec dedicated Admin Workstations for Domain Admins, randomizing local passwords, and deploying lateral traversal mitigations lowering the risks significantly of losing admin credentials that lead to these types of credential re-use attacks.

    Like

    1. Hey Troy,

      I’ve kinda covered those in my previous articles. Here , here and here.
      This article is specifically about Kerberos.

      Like

  3. […] researcher @dfirblog detailed various ways to attack Kerberos using pass-the-ticket, pass-the-hash, or a forged privilege […]

    Like

  4. […] The vulnerability cannot be fixed, and the only solution is to use Microsoft’s Credential Guard program to prevent passwords from being stored in memory, according to his extensive blog post. […]

    Like

  5. […] The researcher blog post that spawned the media coverage – Dfir blog […]

    Like

  6. […] jest niełamalny? To często powtarzany mit, a autor tego poradnika skutecznie go […]

    Like

  7. […] has stirred up new awareness of old, but dangerous flaws. Security researcher @dfirblog detailed[2] various ways to attack Kerberos using pass-the-ticket attacks, pass-the-hash[3] attacks or a […]

    Like

  8. Aaron Mason · · Reply

    Did anyone actually check that the KB number was correct? I went looking for it and couldn’t find it, only to discover that the KB article number is 3011780, not 3101780. It seems to have started from the AD Security blog and continually misreported since.

    Like

    1. Hi Aaron,

      Good catch, i fixed it.

      Like

  9. […] Lo peor es que, como informó The Guardian, la vulnerabilidad en Kerberos no puede solucionarse fácilmente, siendo la única opción el uso del programa Microsoft Credential Guard para impedir que las contraseñas sean almacenadas en memoria, como comenta en su post. […]

    Like

  10. […] degli utenti di rete basato su un sistema di crittografia a chiave simmetrica, è intrinsecamente vulnerabile ad attacchi che non possono essere fermati. Almeno per quel che riguarda le piattaforme Windows, […]

    Like

  11. […] described how an attacker could use pass-the-hash or Golden Ticket techniques with “devastating consequences” on Windows […]

    Like

  12. […] described how an attacker could use pass-the-hash or Golden Ticket techniques with “devastating consequences” on Windows […]

    Like

  13. […] described how an attacker could use pass-the-hash or Golden Ticket techniques with “devastating consequences” on Windows […]

    Like

  14. […] described how an attacker could use pass-the-hash or Golden Ticket techniques with “devastating consequences” on Windows […]

    Like

  15. […] described how an attacker could use pass-the-hash or Golden Ticket techniques with “devastating consequences” on Windows […]

    Like

  16. […] Protecting Windows Networks – Kerberos Attacks […]

    Like

  17. Many thanks for your blogs, do you have them to be downloaded for off line use

    Like

  18. MATA Kinda of detect such as attacks

    Like

Leave a comment