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!