Sunday 22 February 2015

Windows Server DC - MS14-068 vulnerability

The last week I had the awesome opportunity of performing my first internal infrastructe pentest on a major industry company. I was a bit insecure because it was my first time but the first day I had some guidance from my great mentor who has amazing technical skills.
So he told me that one of the method we should try was to use the MS14-068 vulnerability which is kind of recent and the admins probably haven't patched their servers yet.

So I started to investigate about this vulnerability. Since i wanted to play with it at will, I decided to setup my own home network using virtual machines.

So I got Windows Server 2008 R2 patched until June 2013, and a Windows 7 machine up and running.
On the Windows Server i configured it as a domain controller of my domain TESTDOMAIN.CORP and also setup DNS and DHCP roles. I named my windows server "networkdc".

I created a user called "lowprivuser" and assigned the group Domain\Users group to it, and then I configured my Windows 7 machine to use the DC with this user.

After all was configured correctly, i also connected my Kali machine to the same network and started to check about this vulnerability.

First thing we need is a low privileged account. This is something that we could get easily because on real networks, with so many workstations and servers it's highly likely that there is some misconfiguration somewhere that can use to your advantage to get remote code execution. I was actually amazed by the amount of servers running web apps with default credentials...

So lets assume we got remote code execution on some machine and we manage to dump passwords from memory and got a password for this low privilege user.

We will also need a way to get this user's SID. We can get this information using the following methods:
Using wmic:
   wmic useraccount get name,SID
Using whoami:
   whoami /all
using powershell:
   $objUser = New-Object System.Security.Principal.NTAccount("lowprivuser")
   $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
   $strSID.Value
using meterpreter session:
   meterpreter > run post/windows/gather/enum_logged_on_users

The SID for my lowprivuser is:
lowprivuser    S-1-5-21-2861132802-2779959731-2634832200-1102

Thats about it for our requirements.
We get the latest version of PyKek (Kerberos Exploitation Kit) from https://github.com/bidord/pykek
and we launch ms14-068.py specifying the username, domain, SID and the target domain controller's NETBIOS name.



There are some things here that are quite important:
  • Don't use IP addresses, always use NetBIOS names
  • The domain must be the FQDN (Fully qualified domain name)
So in this case if I just put TESTDOMAIN, it won't work and the script will throw an exception with the ASN1 parse error as this one:
pyasn1.error.PyAsn1Error: TagSet(Tag(tagClass=0, tagFormat=32, tagId=16), Tag(tagClass=64, tagFormat=32, tagId=30)) not in asn1Spec: TgsRep()

If everything does alright, PyKek will generate this golden ticket for our low privilege user but with high privileges assigned to it. Great so we got our golden ticket.
But first lets do a quick test. Let's use our user credentials to try to list files on the domain controller on the C$ share:



As expected, we don't have permission to browse DC's files.
Let's try to use our golden ticket.
In linux, we need to copy/move this ticket to /tmp/krb5cc_0 for applications to use kerberos authentication.

# cp TGT_lowprivuser@TESTDOMAIN.CORP.ccache /tmp/krb5cc_0

At this point we can now use this ticket to perform cool stuff. Let's try again the smbclient but using this ticket by issuing the options -k:

We're in. We can now browse any folder in the DC's disk.
We can also use this ticket to execute commands remotely with winexe:

 
This is kind of confusing because if we check winexe's options, we don't see -k option described as this.


So we would expect -k option just to have a "yes" or "no" word. Instead we need to pass our FQDN as parameter for it to work.

We can also invoke a remote shell:


Since we have administrator privileges, we can even add a new user to the domain admins:

And we confirm that the new user is actually there:

That's it: Game over! We are now domain admins on the vulnerable server. 

A piece of advice though... winexe isn't very stable. I had some headaches while testing this vuln with winexe. After some time, I tried to issue the same commands and the program just outputted an "Aborted" message.
The best way to actually exploit this vuln is to copy the generated ticket to a windows machine and then use mimikatz to inject it in memory.
You only need access to a windows box with valid domain credentials. You can access it through RDP, copy the ticket and mimikatz to it and then execute mimikatz.
Lets start by trying to access the C$ share on the DC:
We also should clean current tickets to make sure that we will use just the injected one later.
Now we run mimikatz with the kerberos::ptc option:
If we get the "Injecting ticket: OK" message then we are all set.
I had some issues with this at first. Some things that can cause mimikatz not to inject the ticket could be:
  • Old Windows - Mimikatz author states that old versions of Windows don't support the Pass-the-Ticket technique. It seems that you need to be running mimikatz on a NT 6 platform at least (XP/2003 are not supported). Reference: http://blog.gentilkiwi.com/securite/mimikatz/golden-ticket-kerberos
  • Wrong architecture - Make sure you are running mimikatz in the right architecture mode. If the machine is running Windows 64 bits, run mimikatz x64.
  • IP instead of NETBIOS - Like I already stated, make sure you used the NETBIOS name when the ticket was generated.
  • Also check if the the ticket is still valid by checking the "End date" value on mimikatz output.
With the ticket successfuly injected, let's repeat the previous command to access files on the C$ share on the network domain controller:
We can even access the private dirs in Windows:
Since we now have full permissions we can add a new user as Domain admin:


And that's it, we have now a user with full permissions over the domain.

To get remote code execution on the domain controller we can use tools like psexec that will also use the kerberos ticket to authenticate:
There you have it.... a command shell on the network domain controller with full privileges.

Hope you enjoyed this article, it was fun to investigate this vulnerability.