Tuesday, February 14, 2017

Password Maths Hurt the Brains

Every now and again I find myself figuring out the answers to some math questions related to passwords.  The answer usually revolves around me writing the equation on a napkin and then punching the numbers into my cell phone calculator and then moving on with my life.  I finally got around to making a generic spreadsheet that does all the heavy lifting for me, more on this later.

One of the fundamental tenets of cryptography is that the strength of the cryptography needs to outlive the usefulness of the data being encrypted.  For example, transactional data that has a useful lifetime of a few minutes or less doesn't need to be encrypted at the same strength that something that needs to remain secret for 20+ years.  We are specifically talking about hashed passwords that are used for a variety of things from logging into a system to protecting documents.

Most of the questions revolve around cracking passwords with the latest technology.  These numbers tend to move around quite a bit, but there have been some benchmarks posted with hashcat and multi-gpu rigs.  This gist has numbers from a rig of 8 NVIDIA GTX 1080 cards from Sagitta (https://sagitta.pw/) running benchmarks for Hashcat Beta 3.0. Mucho Kudos for posting those numbers, as I'm using this as the basis for my calculations... more on that later on... first some math...


Password Calculation Basics

UPDATE - I like to be as technically correct as I can when it comes to stuff I put out.  I want to thank @scoobzt for correcting me here on something I overlooked.  Keyspace = CharacterSetLength ^ PasswordLength.  So in all of the following, the word 'Keyspace' is used incorrectly and should be substituted with CharacterSetLength.  At some point in the future I will get around to updating the images below...

It all starts with a basic equation, shown below.


In this equation, there are 4 variables we can solve for, Hashrate, Time, Keyspace, or Password Length.  Now, we know the values for Hashrate (from the gist posted above for the various hashing algorithms) so in reality we are solving for one of the remaining three values.


Solving for Password Length

Since Password Length is an exponent of Keyspace, we need to use logarithms to get the answer.  


It is worth noting that the base of the logarithm is immaterial, so we will use the typical 10 as the base.  You could use natural logarithms and the numbers will be the same.  Yay math!

Solving for Password Length yields:



Solving for Keyspace

Solving for Keyspace size (in characters) involves solving for the Password Length root of the left side of the equation as shown below.



Solving for Time

Solving for Time is the most straightforward of the bunch since it is simple division of the original equation


Let's talk about hashing algorithms

Various hashing algorithms perform differently based on a number of different factors from the age of the algorithm to salting to brute-force cracking resistance (increasing the rounds of encryption required or making the algorithm require a lot of memory to run, etc)...  A discussion of these topics are beyond the scope of this post.

The benchmark mode for Hashcat provides a hash calculation rate for only a single hash, so cracking multiple hashes will naturally degrade the performance.  However, for the numbers I am using, I took the aggregate numbers from the gist and averaged it by 8, namely the number of cards provided.  I also added 10% to assume some measure of overclocking or some other sort of efficiency.


Ok, so what?

So why is this at all interesting?  

First, I often field questions from customers relating to passwords and how often then should change them.  There is a lot of numbers thrown around, but not a ton of explanation as to why those values are chosen.  Doing the math makes some of these discussions easier.

Secondly, when developers have to choose a hashing algorithm, once again, there is often a lot of noise regarding what they should choose.  Providing some real numbers can help guide the decisions appropriately.

Thirdly, sometimes you just want a napkin calculation regarding how quickly you can brute force some password for whatever reason...  

The moment you have all been waiting for...

Here is the link to a google spreadsheet which does the math for you.  You will need to make a copy of it to be able to edit it. Notes:
  • Generally speaking, both the 'password hash type' and the 'keyspace' are selectable values from a list on the second page (except when keyspace is being solved for).  
  • The values in the green cells are what are being solved for
  • Hashrate gets looked up based on the hash value
  • Yes, symbols have 33 values, don't forget the 'space' character...
  • No, I didn't use anything other than plain US ASCII characters
  • These numbers should be considered highly optimistic, YMMV
  • You can generally edit the following values unless they are being solved for: number of GPUs, length of time (days), length of password

Thanks to Andrew for helping make the spreadsheet pretty...

Thursday, June 2, 2016

I'm PKDC, your Personal Kerberos Domain Concierge for the Whatever_domain

So in my last post I demonstrated how you can use Samba to replicate a domain and then create a giant keytab full of keys to use.  You can then use the Heimdal Kerberos implementation to log in as any user you want.

That's neat and all, but what if I want to query the information I pulled offline? We know that Samba can function as a domain controller, but is there a way to coax Samba to be able to present the into to us in a usable format?  IE can we query group membership?

Well, as it turns out, the answer is yes and more...  I'm going to show you how to make your own personal Kerberos Domain Concierge for the domain you just dumped.


Wait what do you mean 'concierge'?

 A popular definition of the word 'concierge' (at least here in the states) is a hotel employee who assists guests with local information, such as maps, restaurant suggestions, event tickets, etc... They are usually at the front of the establishment (at some more touristy locations they have their own office / desk area).

Within the context of pentesting, what I want to do is gather enough information from a site to replicate my own personal domain controller, query it for information and ultimately be able to authenticate against it instead of the target domain.  In other words, literally stealing a domain controller and putting it under my control.

Sound evil?  Yes.  Yes it is.

Moving from Replication Dump to Kerberos Domain Concierge

One of the nifty things that the replication did for us was create a samba config file for us.  Here's what that looks like.


Fairly straightforward.  The config claims to be DC1, and starts up a bunch of services.  For what we need, I'm going to turn off stuff that will likely be noisy.  For example, I don't want our Concierge to replicate anything.  So I'll remove both 'wrepl' and 'drepl' from the list.  I'll also nuke 'dnsupdate' and 'nbt' (netbios over tcp/ip) since DNS might try to update and netbios is noisy as hell...

I also want to bind the instance to localhost.  This actually requires a couple of lines because just saying 'use this interface' isn't enough, you have to put in 'no really I mean it' as well :/  The two lines that get added to the 'global' section are 'interfaces = lo' and 'bind interfaces only = yes'. So here is my finished config.



So I now start up samba with 'samba -s /root/tmp/dc_copy/etc/smb.conf' and see what complains....  I try using the user1 hash to authenticate to get information about user1 using the 'net' command.


And it fails.  Ok something isn't happy.  Let's look at the logs...


So winbindd is complaining about not having a local password to add.  So I do a little digging and discover that I need to add something to 'private/secrets.tdb' for the machine password.  I create a dummy password and insert the key using 'tdbtool', kill / restart samba and try again...


Holy !@$!@# it worked!  Now, let's see if we can coax it to give us a ticket for kerberos...  In order to do this, I make a slight change to the krb5.conf file.  I changed the KDC from dc1 to 127.0.0.1.


From here, I do the 'kinit' using the previously generated keytab.  And voila! I get a ticket from our own personal Concierge....


And here's the wireshark capture showing that the traffic went across localhost


So what happens if we try to use this ticket to authenticate to DC1?  On the localhost side, we get a request for a service ticket, which is to be expected.


On the 10 side we see that there is a pause between the DNS query for the address and the SMB connection.  This is where the Concierge was asked about giving us access to the CIFS share on the domain controller.


Here's the list of the tickets we ended up with.


So like a true professional, our Concierge got us tickets to whatever we wanted without complaining ;-)

Ramifications

Ok.  So this is cute, so what?  Why should somebody care about this?

Well... aside from the fact that I now have a Domain Controller that I can authenticate against that the other side has no visibility into, this is sort of the penultimate demonstration of domain compromise.  Standing up your own domain controller for their environment.  Unless they are looking for / logging replication traffic, they would have no idea WTF is going on.  I *believe* that some of the next generation detection capabilities depend on being able to watch authentication traffic on the DC, so not authenticating against that would cause some serious problems detection wise.

Other Thoughts / Ideas

Right now this is a localhost only copy of the database.  It would be entertaining to see if this could be extended so that other people / VMs could authenticate against this on an assessment.  Getting this working on the *NIX side should be straight forward.  I REALLY want to see if I can get my Windows attack platform to authenticate to it.  That aught to be fun...  We'll see how this goes...







Wednesday, June 1, 2016

*NIX Kerberos + MS Active Directory fun and games

So one of my favorite techniques on the Windows side is to use what Benjamin Delpy (@gentilkiwi) called 'overpass the hash' to get a legit Kerberos ticket from a KDC once I've fully compromised the domain.  This technique requires the use of a password hash (hence the need for domain compromise, although you could simply have gotten somebody's password as well).

Quick Review of Overpass-the-hash


In case you don't remember, the way that you get a TGT (ticket granting ticket) in Active Directory is via a process called 'pre-authentication'.  Essentially the way this works is you take a timestamp (hence the requirement that the time be synced with domain controllers) and encrypt it with the user's shared secret (the password hash) and send it off to the Domain Controller.  The DC will verify the blob by decrypting it with the copy of the key the DC has and seeing if the resulting timestamp fits in the window of time configured. Assuming that all is well, the DC will send the client a TGT.

So, in essence, to get a TGT you need 1) correct time 2) username 3) key for username 4) name of DC / domain.  Ben's 'overpass the hash' method uses Mimikatz to set the hash/user/domain in memory on a Windows box.  Then when you request a service using that credential, Windows will automagically ask for the TGT and any subsequent service tickets.  Sometimes it is a bit fiddly to get the right Kerberos information to make it work since some places prefer to use the netbios name everywhere, but it's not too hard to figure out if you have enumerated the domain controllers.

Kerberos and *NIX

Kerberos is a central authentication service that started on *NIX and is currently being used by several organizations in various flavors.  Integrating *NIX Kerb with AD has always been challenging as some of the changes to MS Kerb are different than the traditional Kerb implementations on the *NIX side.

There are 2 primary implementations of *NIX Kerb, MIT and Heimdal.  Both are in use today.  MIT is considered the more stable while Heimdal is considered the most progressive.  Samba generally prefers Heimdal for its Kerb interactions.

Recently I've had several clients who had large integrations of *NIX machines within their AD environment using a product called Centrify (https://www.centrify.com/).  This allows users to sign into *NIX hosts with their Windows credentials using Kerberos via SSH.  Essentially the *NIX boxes become domain joined and there are some interesting things you can do, such as push out Group Policy Objects (GPOs) to the *NIX machines.

So the issue I ran into was, since I popped the domain, how can I leverage this to log into the *NIX environment?  I have all this Windows Kerberos functionality thanks to Mimikatz.  How can I make it work with *NIX?

Quick Into to *NIX Kerberos Commands

Getting Kerberos up and going quickly on Kali (Debian base) is fairly straight forward.  I'm going to recommend using Heimdal rather than MIT based on experiences.  

Simply "apt-get install heimdal-clients" and it should pull in a all the required dependencies.  We aren't quite done yet, however.

First, you need to point your name resolution to the domain controller.  There's a lot of magic that gets figured out with Kerberos and DNS, so pointing the resolv.conf to the DC just makes life easier.  Trust me.

Secondly, you need a working '/etc/krb5.conf'.  I managed to steal re-purpose one from a working Centrify config.  It is worth noting that you need to get the case correct here.  Kerberos realms are capitalized.  It took me forever to re-learn this, so you've been warned.  I recommend starting with a known good / working configuration and then modify to suit your needs.    Here it is from my internal 'exploits.com' domain in the lab (Windows 2008R2 domain at 2008R2 functional level):
[libdefaults]
 default_realm = EXPLOITS.COM
 default_tgs_enctypes = aes256-cts aes128-cts arcfour-hmac-md5 des-cbc-md5 des-cbc-crc
 default_tkt_enctypes = aes256-cts aes128-cts arcfour-hmac-md5 des-cbc-md5 des-cbc-crc
 permitted_enctypes = aes256-cts aes128-cts arcfour-hmac-md5 des-cbc-md5 des-cbc-crc
 dns_lookup_realm = true
 dns_lookup_kdc = true
 passwd_check_s_address = false
 noaddresses = true
udp_preference_limit = 1
 ccache_type = 3
 kdc_timesync = 0
 kdc_timesync = 0
[domain_realm]
 dc1.exploits.com = EXPLOITS.COM
 .exploits.com = EXPLOITS.COM
 exploits.com = EXPLOITS.COM
[realms]
EXPLOITS.COM = {
 kdc = dc1.exploits.com:88
 master_kdc = dc1.exploits.com:88
 kpasswd = dc1.exploits.com:464
 kpasswd_server = dc1.exploits.com:464
}

Logging into a Kerberos domain is fairly straight forward.  Assuming that you have everything configured correctly, you issue the command 'kinit user1@EXPLOITS.COM'.  It will prompt you for a password.  Then if it is successful, it will simply return you to a command prompt.  To see if you actually got a ticket, use the command 'klist'.  If everything went smoothly, then your output aught to look something like this:



You can also get a 'verbose' listing of the information in the ticket by sending the '-v' flag to klist.


The Kerberos tickets are stores in a file in /tmp called 'krb5cc_0' in a *NIX Kerberos format called CCACHE.  The number at the end is the UID of the currently logged in user.  If you are on a multi-user system you may see several files in /tmp with different UIDs.  Keep in mind that Kerberos tickets are portable..... (and if you are root, easy to grab files with multiple tickets potentially in them) ;-)

Once you have a TGT you can generally simply use the '-k' flag with any of the samba utilities to log into Windows assets using the Kerberos ticket rather than credentials.  You don't even need to specify a username either, since that's all in the ticket.  

Round Uno

Initially when faced with logging into the *NIX assets I hadn't figured out a good way of leveraging the keys I had recovered from the AD compromise to move into the *NIX assets.  So I'm going to briefly describe what I did, however, there is a much simpler / cleaner way now, so I'm not going to give too much detail here.

Essentially I started with the overpass-the-hash from above and then exported the tickets using Mimikatz. From here, I converted the TGT from the .kirbi format into the .ccache format by using another tool from Ben called kekeo.  I copied the resulting file over to my Kali box as '/tmp/krb5cc_0' and voila, I now had a TGT I could then work with.  However, this is a multi-step process and a serious pain in the genitals, so I wanted to try to find a cleaner way, and in the end discovered something much much cooler...

Round Two.... FIGHT!

After digging through the Heimdal code and asking Ben some questions on twitter, he pointed me to a utility I wasn't aware of called 'ktutil'.  This utility is used to manage 'keytab' files, which can include actual keys.  I have keys, lots of them in fact from a domain compromise, it can't be that easy, can it?

Yup.

This is using Heimdal.  Use Heimdal.  The 'ktutil' on MIT is interactive and is much more painful to use.  Hence my recommendation to use Heimdal.  Heimdal.  Heimdal.

From my Twitter post:


So you can specify a file to use as the keytab (-k) the username (Principal in Kerb lingo) , the encryption type (arcfour-hmac-md5 is used for NTLM auth), the password (-w <hash>) , specify that the password is actually a key in hex (--hex) and the version a capital V (-V 5).  Now I used 5 thinking that this is kerberos 5, but this version might be some other version, so I'm not entirely sure.  YMMV.

Then when you use kinit, you specify the keytab file to use (-t) and then magic happens.  You end up with a TGT. MUHAHAHAHAH.  Overpass-the-hash with Kerberos using native tools.  I feel really silly for not having figured this out sooner.  Seriously.  However, digging into it a little more, I found something much much cooler, if you can imagine that.

Round Three - Dude, You're Screwed!

So whilst I was digging around, I thought about trying to automate using the keytab to just store all the keys for the domain and simply pick which one I wanted based on what I needed at the time.  So I approached the problem from the direction of maybe writing a script to automate dumping all the keys into a keytab.  I was poking around when I found something magical.

You can actually coax Samba to do all the work for you!  For every key in AD for every user / computer.  With built-in tools. From a non-domain-joined computer.

So, as it turns out the newer versions of Samba have the ability to replicate from a domain controller and then you can convert that into a huge keytab.

To use this 'feature' you need a newer version of Samba.  This means compiling from scratch.  Beyond the scope of what I'm writing about here, but it wasn't hard.  Couple annoying dependencies and some multi-core compiling later I have a new build in /opt/smb.

This magical command is called 'samba-tool'.  You can use it to replicate a remote DC (with an admin user of course) and it will dump the contents to a directory of your choosing.  Plus you can use Kerberos, so you can simply use an existing ticket you received from OPTH. ;-)

You need to invoke samba-tool thusly (Note, this is what worked in my lab, might be fiddly, YMMV):

samba-tool drs clone-dc-database --include-secrets --targetdir=<dir> <DOMAIN in CAPS> -k1 

You need to specify 'targetdir' and the domain obviously.  The '-k1' tells it to use kerberos.  My test domain has a large number of objects (computers / users/ groups ) that I created using Joeware's admod to give it some size.




So, this scrolls on for a bit until it's pumped the DC dry.  The next step takes the data from here and generates a keytab file with everything in it.  Note this step takes a long time.  On my machine it took a few hours.  There might be a way to optimize things a tad if you don't want everything.

Anywhoo... without further ado:

samba-tool domain exportkeytab <filename> -s <path to configfile>


Note that the new keytab can be whatever you want it to be, however the config file was actually generated by the previous command.  Like I said earlier, this command takes a while for my largish domain, but I ended up with a keytab file with all keys (AES, NTLM, DES) from the domain.  And in a much more compact format.  My combined file for the domain is ~6meg.

You can list the keys contained in a keytab file using ktutil and can even get the actual keys themselves if you tack on '--keys'.  Muahahahahahahahahaha



Final Deep Thoughts with @Passingthehash

So digging into it a tad, it looks like samba-tool is just a bunch of python code, so I think it should be possible to make some changes to make it more useful for the average pentester.  For example, rip out the code to just do the domain replication.  Also, make it an option whether or not to have computer accounts in the keytab, or limit the keytypes recovered.  That aught to make things go much faster.  Anyways, enjoy and have fun kids!

Sunday, April 5, 2015

No, Microsoft Hasn't "Fixed" Silver Tickets

Contrary to what many folks might think, I don't wait around on the Internet for somebody to be wrong to blog about it.  However, when somebody misrepresents research that myself and others have worked on, there's something to talk about.  Especially if this "advice" leads to sweeping incorrect statements that could lead C-level folks to think that an entire class of problems has been fixed when they haven't.  This is a problem :/

The post is here: http://blog.varonis.com/microsoft-fixes-kerberos-silver-ticket-vulnerability/

It's also a bit old, from December of last year, but @Gentilkiwi (Ben / Author of Mimikatz) recently pointed it out.

And it makes enough mistakes and confuses enough concepts that I felt it necessary to make sure at least one source on the web corrects the misconceptions....

What He Got Right

The author did a decent job in previous blog entries (at least from a skim) of explaining the Kerberos process and has a decent grasp on Golden Ticket Attacks.  I'll also forgive him for not updating the post or referencing in a new post Microsoft's official KRBTGT changing script found here: (blog) http://blogs.microsoft.com/cybertrust/2015/02/11/krbtgt-account-password-reset-scripts-now-available-for-customers/
(download) https://gallery.technet.microsoft.com/Reset-the-krbtgt-account-581a9e51

Where Things Go South

So things start getting a little misunderstood talking about Service Tickets.  There's a couple points I would like to make.  Generally speaking : 

1) Service tickets destined for something the target computer deals with (file shares, rpc calls, etc) use the target computer's AD account to sign the service ticket.  The computer account is (by default) changed every 30 days or so and has a long random unicode password.  You in all likelihood will never be able to guess this password.  However, with local admin on the box or physical access, they are trivial to recover.

2) Service tickets destined for a service running as a different account (SQL server, Exchange Server, etc) will use the service account password for that particular service as the signing key for Kerberos requests.  There is a chance you can guess these passwords, since they are service accounts.  Tim Medin's research focuses on getting something to crack offline by creating a fake SPN (service principal name) and requesting service ticket(s) ( https://github.com/nidem/kerberoast / http://www.irongeek.com/i.php?page=videos/derbycon4/t120-attacking-microsoft-kerberos-kicking-the-guard-dog-of-hades-tim-medin )

Silver tickets allow an attacker to generate arbitrary service tickets when the attacker has the service account hash / password.  PAC validation is disabled by default for accounts running as services.  For more details, refer to one of my previous posts which quotes the official MS specs : http://passing-the-hash.blogspot.com/2014/09/pac-validation-20-minute-rule-and.html

No, MS14-068 Did NOT Fix Silver Tickets

Joe Bialek from Microsoft did a great job of talking about the vulnerability fixed by MS14-068 here: http://blogs.technet.com/b/srd/archive/2014/11/18/additional-information-about-cve-2014-6324.aspx

The short version is that prior to this patch there was an edge case in the Kerberos spec that could allow an attacker with a user account password/hash to modify the PAC and then the KDC would validate it as legit. The end result was an elevated TGT account.  This is completely unrelated to silver tickets.  This was an exploit against Kerberos.

Silver tickets will continue to work with the MS14-048 patch installed.

A Note to the Author

Mr. Green, feel free to reach out to me, @gentilkiwi, or @josephbialek if you need any more clarification.


Saturday, February 14, 2015

Microsoft Finally Releases Guidance and a Script to Change the KRBTGT Account

So Microsoft recently released a zipfile which contains both a document and a powershell script that can be used to change the KRBTGT in a domain.  Before doing anything, RTFM that comes with it and obviously run it in a test environment and make sure that it doesn't eat kittens in your environment...

The basic functionality of the powershell script is that it changes the KRBTGT and it will force replication to update the KRBTGT account and validate that it has replicated.

I haven't (and likely won't ) spend a lot of time on the script itself.  However, one of the things that came up on Twitter from @scriptjunkie1 was that the password being set wasn't using a decent random source, so the password wouldn't be as random as it could be.

However, based on conversations I've had with folks at Microsoft, this password doesn't matter.  This is of course undocumented and honestly, this could potentially lead to problems with clever administrators, however I will get to this a little later...

So, in this case I set up a throwaway Windows 2008 R2 domain controller.  I used Mimikatz to dump the KRBTGT hash.





So, by default, the KRBTGT account has a random 32 byte unicode password assigned to it that is completely unprintable, so it's easiest to just see the hash...




I am using this 8 character complex, yet terrible, password.  If an actual account was set to this, the NT hash would look like the above screen.





Using the 'net user' command, we can set the password for the KRBTGT account, but as you can see above, the hash from setting the password to '1qaz@WSX' is not the same hash from above.  Ok, what happens if we do it again? 



So, the hash changes again.  Even though we set it to the same password, it changes again to a random password / hash.

One thing to note, even though the password is completely ignored, it needs to clear whatever the password policy is in play on the domain.

So, why is this behavior a bad thing?  Well Microsoft's unofficial stance is that they want people to use strong passwords (even though it's completely ignored).  However, a clever administrator would INCORRECTLY believe that they could type in the same password on each DC and shortcut the replication process.

So would this completely brick your environment if you did this? Honestly I don't know.  Late last year @mubix talked about an environment where the KRBTGT was changed on a semi-constant manner and it didn't break the environment.  So (offline) myself and a few others fiddled with it a bit and it looks like that could work, but only because when the tickets are invalidated the credentials that are cached in memory are immediately resubmitted and new tickets are issued.

So what happens if you fsck up the KRBTGT across multiple domain controllers?  Honestly I don't know and don't really have a good way to easily test this. Do you really want to find out in your environment?


Correction 1:

Benjamin Delpy (@gentilkiwi) says that the KRBTGT password is a 32-byte random password (which would actually be 16 unicode chars).  Since he's poked around in memory on DC's far more than I have, I'm going with his answer :-)  Corrected in the post

Saturday, September 27, 2014

PAC Validation, The 20 Minute Rule and Exceptions (BHUSA 2014 part deux)

First off, I apologize for not being quicker about getting this post out.  However, Wasteland 2 came out recently, and I have been playing far too much of it for my own good ;-)

Anyways onto the topic at hand: PAC validation and the various excuses not to check it

What is PAC Validation and Why Do I Care?

 The PAC (Privilaged Attribute Certificate) is a structure contained in a Kerberos ticket that contains a list of privileges that the ticket is representing, along with some other stuff.  If we can forge the PAC we can do things to break the privilege model of Kerberos  in some very interesting ways ;-)

"PAC validation" is pretty much what it sounds like, the service receiving the ticket double checks the information contained in the PAC as being valid before either issuing service tickets (in the event of a Ticket Granting Ticket / TGT) or running the command/request/whatever (in the event of a service ticket being used).

The 20 Minute Rule 

What we're calling "The 20 Minute Rule" is taken straight out of the Microsoft's MS-KILE specification, specifically section 5.1.3 which states:

"Kerberos V5 does not provide account revocation checking for TGS requests, which allows TGT renewals and service tickets to be issued as long as the TGT is valid even if the account has been revoked. KILE provides a check account policy (section 3.3.5.7.1) that limits the exposure to a shorter time. KILE KDCs in the account domain are required to check accounts when the TGT is older than 20 minutes. This limits the period that a client can get a ticket with a revoked account while limiting the performance cost for AD queries."

So to translate, in the event that the TGT is more than 20 minutes old, the PAC contents are validated to ensure that the account is still valid.  However to flip this around, this means that there's a 20 minute window where the contents ARE NOT validated.  This is one of the primary things we brought up in our Black Hat talk.  As long as you have the KRBTGT hash you can put whatever information you want into the PAC inside the TGT, and service tickets will be issued, as long as the age of the TGT is less that 20 minutes old.  This includes bogus account / SID information, such as a non-existent user being a member of the domain admins group.  Because the information isn't validated during this first 20 minute window, service tickets will be generated that are good for several hours by default.  Additionally, since we can create our own TGTs, the 20 minute rule is never really a problem since we can simply create a new TGT every 20 minutes to get around this limitation.

Other PAC Validation Issues

So obviously, this can lead to some problems, but are there any other examples lurking out there?  I'm glad you asked!

Recently @gentilkiwi and I have been investigating another issue related to a failure of PAC validation that Ben has dubbed a 'Silver Ticket'.   Here's the section of relevant protocol specification from the holy Microsoft MS-APDS scripture Appendix A, Section 1.6.2:

"
  • Windows 2000 Server and Windows XP do not validate the PAC when the application server is running under the local system context or has SeTcbPrivilege, as specified in [MS-LSAD] section 3.1.1.2.1. Otherwise, Windows 2000 Server and Windows XP use Kerberos PAC validation.
  • Windows Server 2003 does not validate the PAC when the application server is running under the local system context, the network service context, or has SeTcbPrivilege. Otherwise, Windows Server 2003 uses Kerberos PAC validation.
  • Windows Server 2003 with SP1 does not validate the PAC when the application server is under the local system context, the network service context, the local service context, or has SeTcbPrivilege privilege. Otherwise, Windows Server 2003 with SP1 and future service packs use Kerberos PAC validation.
  • Windows Vista, Windows Server 2008, Windows 7, Windows Server 2008 R2, Windows 8, Windows Server 2012, Windows 8.1, and Windows Server 2012 R2 do not validate the PAC by default for services. Windows still validates the PAC for processes that are not running as services. PAC validation can be enabled when the application server is not running in the context of local system, network service, or local service; or it does not have SeTcbPrivilege, as specified in [MS-LSAD] section 3.1.1.2.1.
"

So, in general older versions of Windows don't validate the PAC when the process is running as SYSTEM or has the "SeTcbPrivilege" (Act as part of the operating system) privilege set.  Newer versions (Vista+) don't check the PAC for services. 

So, how is this useful?  Well, pretty much anything that you could want to do to a computer remotely is a service, such as access a file share, schedule a task, execute code, etc...

So, for Kerberos, services by default don't validate PAC settings... What could possibly go wrong here?  But wait! There's more!

Service Tickets and Kerberos 

The obvious question now arises, what do we need to issue a service ticket for a particular service?  How can we take advantage of this?

Service tickets SHOULD be issued by a TGS after getting a TGT and should be between 2 Kerberos principals.  So for example, if Bob wants to access a file share (CIFS) on ServerA, Bob would ask the TGS to give him a ticket for user CIFS@ServerA.  The TGS would then give Bob a ticket that he could present to ServerA that would give him access to the CIFS service.

With TGTs, the piece destined for the TGS would need to be signed by the KRBTGT account, the central account for trust to validate that the ticket is legit.  However, for service tickets, the target account is on the computer itself.  What is the long term secret key?  

In short, it depends.  For all services that run as System on the computer, it will be the computer account from AD.   If the service is operating as a particular user (typically like Sharepoint, Exchange,  MSSQL, etc...) it will be that account. 

Recovering the computer account is relatively trivial with physical access (think boot disk, grab the registry, decode at whim) and if you can run as admin, it's trivial as well...  If you can guess the service account password for a service that runs as a different user, that will work too...

Now, all you have to do is use Mimikatz to generate a Silver Ticket for the service and away you go...  an example that Ben posted to twitter can be seen here:



Since service tickets are identical in format to TGTs albeit with a different service name, all you need to do is specify a different service name and use the RC4 (NTLM hash) of the account password (either the computer account for default services or the actual account) and you can now issue service tickets for the requested service.  Note:  You can also use the AES keys if you happen to have them instead of the NTLM key and it will still work ;-)

It is worth noting, that services like MSSQL, Sharepoint, etc will only allow you to play with those services.  The computer account will allow access to CIFS, service creation, and a whole host of other activities on the targeted computer.  You can leverage the computer account into a shell with PSEXEC and you will be running as system on that particular computer.  Lateral movement is then a matter of doing whatever you need to do from there :-)

My next post I will perform some demos with screenshots, etc...  Stay tuned!

Thursday, August 21, 2014

Mimikatz and Golden Tickets... What's the BFD? BlackHat USA 2014 Redux part 1

So a couple weeks ago Benjamin Delpy (@gentilkiwi on twitter / author of Mimikatz ) and myself presented at Blackhat USA and, in a somewhat impromptu manner, the Wall of Sheep at DefCon as well...

The updated slides (from the WoS talk) can be found here: http://www.slideshare.net/gentilkiwi/abusing-microsoft-kerberos-sorry-you-guys-dont-get-it


Quick Oversimplified Kerberos Refresher

IF you read all the links on Kerberos there's talks about TGTs, service tickets, principals, etc... I want to present just a simple way to quickly visualize what's going on with Kerberos.

Imagine yourself as a kid.  Mom needs to pick up a gallon of milk and the dry cleaning but needs to wait in the car for whatever reason. Fortunately, the cleaners and 7-11 are right next door to each other.  She hands you her credit card and tells you to go get the milk and then the dry cleaning and get back to the car.

You walk into the 7-11, grab the milk, hand the credit card to the cashier and he lets you leave with the milk.  You then walk into the dry cleaners, tell them you're there for the pickup, hand them the credit card and you walk out with some shirts as well. 

In this highly oversimplified example, the credit card is how you gain access to the services of the convenience store (the milk) and the dry cleaners.  You don't understand how the card works, only that you show it to the cashiers and they allow you to leave with the items.

TGT (Ticket Granting Tickets) operate in much the same way.  When a kerberos principal (somebody who wants to access a service protected by kerberos) authenticates to the KDC, they provide their username and password and get a TGT in return.  This TGT operates in much the same way the credit card does.  Whenever the principal wants to access a service, they submit their request along with the TGT and based on the privileges contained in the TGT, the request will either be granted or denied.

The nice thing about this TGT is that it is valid for a period of time.  This means that the user doesn't have to get prompted for their password for a period of time.  The TGT can simply be passed on and reused until the ticket expires.

Why Does the Domain Trust the TGT?

So what grants the TGT its mystical powers?  It's because part of it is encrypted using the NT  hash of the KRBTGT account and the other part is encrypted by the NTLM hash of the principal requesting it.  

This means that in order for it to be legit, 2 different principals have to agree that it's legit.  In essence, each side of the conversation has some assurance that the other side is who they claim to be since "in theory" the only way the TGT could be valid is that both sides can read their part.

This is where Mimikatz comes into play.

So How Old is the KRBTGT on Your Network?

If we have a complete hashdump of the domain, then we have the password hash for the KRBTGT account.  Additionally, this account seemingly never changes its password.  The only instances where folks have reported that it changes is when the domain functional level changes during an upgrade, a point I will touch on in a sec.

So,  for example, this is from my demo domain from 2012 that is still up and running that I use to test PTH tools against:


Note that the password for the KRBTGT hasn't changed since March of 2012.  This is about the time I set the domain up to begin with.

So that means that regardless of the password policy in place on the network, this account has NOT changed its password in over 2 years.  Just in case you're wondering what your network looks like, try running "net user krbtgt /domain" from a command prompt on your local network.

So, when does this hash / password change?  There is only one circumstance where this password automatically changes.  The password for the KRBTGT account only changes when the domain functional level is upgraded from a NT5 version (2000/2003) to a NT6 version (2008/2012).  If you move from 2008 -> 2012R2 domain functional level, this hash won't change.

This hash can also be manually changed in a working AD, but this will cause all sorts of "Bad Things(tm)" to happen to your network, namely all Kerberos tickets will simultaneously die and in all likelihood demons will be summoned and a lot of puppies and kittens will be killed.  Not to mention Sysads.

Seriously though, this process is as of right now unsupported by Microsoft and there has not been any official documentation regarding how this should take place and what the effects will be.  This will be forthcoming in the "Not Too Distant Future(tm)" as well, so keep an eye out for that.

So, the net result is that your KRBTGT account is only as old as your transition from a NT5 domain funtional level to NT6.  If that happened back in 2008, then you hash is at least 6 years old.  If you are still on a 2003 domain, then it is even older.

Assume that "N" is the amount of time since the KRBTGT account has changed.  Ultimately, if you have a password hash dump somewhere on your network from something less than N years ago, then the KRBTGT account could have been compromised. (Of course, said password dump could also be on pastebin too and archived by Google...) If you have a poorly configured backup of a domain controller on your network from less than N years ago, the KRBTGT account could have been compromised.  If there's an old domain controller that has been decommissioned but is still in your virtual machine library, ditto.  If there was a poorly redacted  pentest report showing the first few lines of a hashdump, ditto... and the list goes on....

So, what's the BFD with this account?

The bottom line is this : If somebody has compromised the KRBTGT account and they have the domain SID (Security Identifier) for your domain, they can generate a ticket that can impersonate any user and put them into any group.  The users do not need to be enabled or even exist in the domain and they can still be put into the highly privileged groups in the domain, such as the domain or enterprise admins.

So, this is definitely a Big Fscking Deal.

Well touch more on this in the next post.