Issue uploading a file with cURL to WebSecurityAcademy Lab on PortSwigger.com
I want to solve an apprentice-level lab on PortSwigger.com focused on file upload vulnerabilities; the lab is called Remote code execution via web shell upload. The labs on PortSwigger.com encourage the use of Burp. However, while Burp is convenient, I've been able to complete most of the labs with Firefox's Inspect Elements feature, cURL, FFUF, and my script files (.zsh
).
In the lab, once you've logged into your account with your credentials (wiener, peter), you are taken to a page that contains a form field. I can upload a MIME type file with the Upload
button. However, attempting this with cURL leads to the website responding back with 403
:
HTTP/2 403
date: Thu, 04 Jan 2024 20:19:53 GMT
server: Apache/2.4.41 (Ubuntu)
content-type: text/html; charset=UTF-8
x-frame-options: SAMEORIGIN
content-encoding: gzip
content-length: 130
Sorry, there was an error uploading your file.<p><a href="/my-account" title="Return to previous page">� Back to My Account</a></p>
I'm using WSL Kali with zshell. The contents for the request headers -H
and multipart formposts -F
I collected with Firefox's inspect tool (Network tab):
#! /user/bin/env zsh
printf "sending request method: POST ..\n"
curl -X POST \
"https://0a03007104c431728258f2ab002d0022.web-security-academy.net/my-account/avatar" \
-H 'Host: 0ad8002a0462a98881c3e838005100e7.web-security-academy.net' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0' \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' \
-H 'Accept-Language: en-US,en;q=0.5' \
-H 'Accept-Encoding: gzip, deflate, br' \
-H 'Content-Type: multipart/form-data; boundary=---------------------------39790241744060408523443555752' \
-H 'Content-Length: 38849' \
-H 'Origin: https://0ad8002a0462a98881c3e838005100e7.web-security-academy.net' \
-H 'Connection: keep-alive' \
-H 'Referer: https://0ad8002a0462a98881c3e838005100e7.web-security-academy.net/my-account?id=wiener' \
-H 'Cookie: session=xaY31bjOUNnKSpOsO9Pm8jovAqL9d8PR' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'Sec-Fetch-Dest: document' \
-H 'Sec-Fetch-Mode: navigate' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Sec-Fetch-User: ?1' \
-H 'TE: trailers' \
-F 'name=avatar' \
-F 'filename=animeGirl-1.jpg' \
-F avatar=@animeGirl-1.jpg \
-F 'name=user' \
-F 'user=wiener' \
-F 'name=csrf' \
-F 'csrf=WkcqiRG3sycESWznv1lhlBqLeapxHdT0' \
--compressed -i > resp.txt
printf "displaying response: matches found ..\n"
response="(HTTP/2)|(200|302)|(duration)"
account="(login|my account)|(admin|wiener|carlos)"
mimeType=".(html|(jpeg|jpg))"
formPosts="(form|input type)"
grep -iE \
"("\
"${response}"\
"${account}"\
"${mimeType}"\
"${formPosts}"\
")" \
resp.txt -A 10