On a past assessment, we found a Domain Controller that was vulnerable to the infamous MS14-068 exploit. While trying to get the exploit working properly, we ran into some random issues that we had to work through. I wanted to document the process we used for successful exploitation, as well as the fixes we developed along the way.
I don’t intend to go in depth on exactly how MS14-068 works. If you want a detailed explanation, you can find a fantastic one here. At a high level, the logic that verifies the cryptographic signing of a certain part of the Kerberos Tickets was broken, allowing you to forge information contained within it. Microsoft’s documentation specifies that the only valid cryptographic algorithms for signing a ticket are HMAC_MD5, SHA1 AES128 and SHA1 AES256, all very strong algorithms. Unfortunately, the flaw allowed you to use a whole slew of other algorithms, including CRC32, RC4, and just plain MD5.
Included in part of the ticket is the Privilege Attribute Certificate (PAC), which determines what groups in the domain a user belongs to. By forging the PAC, we can decide what groups we’re in ourselves (convenient!). There’s one particular group that’s of significant interest to us, Domain Admins.
To exploit MS14-068, you need a few pieces of information and access. The first thing you need is a valid user name and password for a user on the domain. I’m going to go ahead and assume you have this already. The next thing you’ll need is the IP of a vulnerable domain controller.
Getting a Domain Controller
An easy way to identify the domain controllers for the domain you’re targeting is through PowerView, using the Get-NetDomainControllers cmdlet. Here’s how that looks using Cobalt Strike’s Beacon:
Alternatively, you can do it using dig on your Kali box provided you know at least one DNS server for the target domain, using the command:
dig SRV _ldap._tcp.dc._msdsc.domain.name@<ip of dns server>
Getting a Security Identifier (SID)
The next thing you need is the Security Identifier (SID) of the user whose credentials you have. There’s a few ways to grab this. The first is using the tool rpcclient and the lookupnames tool.
Alternatively if you have PowerShell/Beacon handy, you can get the SID using native PowerShell/.NET commands. The following command is provided courtesy of @harmj0y:
A third alternative, provided you’re logged in with your user somewhere, is just to use the Windows whoami command with the /user flag.
Save this SID somewhere, because we’re going to need it in a bit.
Exploiting the Flaw and Generating a Ticket
As of writing this, there are three seperate tools which will exploit the flaw in Kerberos. The first tool is PyKEK (Python Kerberos Exploitation Kit), which can be found at https://github.com/bidord/pykek. Invoking it will generate a .ccache file.
A second way of exploiting the flaw is using the Metasploit Framework. Metasploit provides the module ms14_068_kerberos_checksum to exploit this issue. The Metasploit module will generate a .bin file.
A third method is using @gentilkiwi’s Kerberos Toolbox, Kekeo. It’s worth noting that kekeo compiles to an executable, therefore limiting you to running it on Windows. However, kekeo lets you skip step 2, as it can lookup the user’s SID itself. Kekeo will export a ticket in the KrbCred format.
Converting MSF/PyKEK Tickets
Kekeo already exports tickets in the KrbCred format used by Mimikatz. However, the tickets generated by both Metasploit and PyKEK are not compatible with the format expected by either Beacon or Mimikatz. However, converting it to a usable format is possible in a couple different ways. The first method you can use is with mimikatz.
Unfortunately, this requires you to have a windows installation handy, or dropping Mimikatz to disk, which isn’t generally a great idea on engagements. This is where my KrbCredExport script comes in. It’s writting in Python, so usable anywhere you have python handy. You can grab it from https://github.com/rvazarkar/KrbCredExport. Using it is as simple as giving it an input and output file.
Using the Ticket
Now that we have a ticket in a usable format, it’s time to use it. You can import it into Mimikatz or Beacon using kerberos_ticket_use. If you’ve run this exploit before, it’s a good idea to run kerberos_ticket_purge to clear any currently loaded Kerberos tickets that might interfere with authentication.
After applying the ticket, we successfully get a directory listing on our Domain Controller, whereas before, we didn’t have the permissions. Now all that’s left is to get code execution on that Domain Controller and call it a day.
Since we’re already having fun with shell commands, I suggest an old school, but still awesome method…using the at command! Combine it with something like Cobalt Strike’s Web Drive-By, and you get a nice shell back.
Ticket and Back Again
There are a few tools that can accept CCache files for authentication instead of KrbCred tickets. SMBClient, as well as Winexe both accept CCache files. The first allows you to connect to remote SMB shares from a Linux machine, and the second lets you execute commands remotely using SMB Authentication (although the functionality of the -k flag is currently broken as documented here). When a Golden Ticket is generated using Mimikatz, it exports in the .kirbi format. KrbCredExport supports converting a KrbCred back to a CCache, letting you use that awesome Golden Ticket with other tools.
Since the release of the 14-068 exploit, more work has been done on detecting the exploit. Sean Metcalf (@pyrotek3) has an excellent post on his site that document’s the many ways to look for the exploit being performed, both at the network level, as well as from Windows Event Logs.
Kerberos file structures aren’t particularly well documented. Even places where they are described, there tends to be errors or inconsistencies. Benjamin Delpy @gentilwiki did a fantastic job of reversing a lot of the Kerberos structs and file formats, and used them in Mimikatz. Unfortunately, my understanding of C isn’t exactly fantastic, and I found a lot of the code in Mimikatz was way over my head. So I decided to actually go learn Kerberos file structures instead of just ripping the code from Mimikatz directly to Python. One of the best sources I found when researching the structure of the KrbCred, which is the actual name of our tickets, was Apache’s Kerberos documentation. Parsing out the ccache file was a much easier prospect thanks to the fantastic documentation done by GNU for shishi (which can be found here).
It took a while to fully understand the various structs, but it makes a lot more sense when you realize that a good chunk of the ticket file is the actual ticket data, and a whole bunch of bytes are just identifiers or size constants. After figuring out that the byte \x82 and the following 2 bytes denoted the remaining length of the file, things became a lot easier. The entire file structure actually does a great job of letting you know what goes where, with different sections being identified by the byte \xAX, where X is a number between 0 and 9. After figuring this out, it was just a question of investigating where different points of data cross-reference and looking at different pieces of documentation. Overall, it’s a fun exercise, even if it is very frustrating. The upside is I’ve properly documented all of the Kerberos Structs used in KrbCred/CCache conversion and vice versa, so it should be easier for anyone else trying to dive into it.
The problem of not being able to do a single step on your attack system seems almost like a trivial problem, but it definitely complicated our attack chain while on the assessment. Writing the KrbCredExport script took several weeks of research for a seemingly trivial problem, but it should simplify the process of running this exploit chain, and possibly enable others in the future.