Exploiting server side parameter pollution in a query string
Description
To solve the lab, log in as the administrator and delete carlos.
Approach
After accessing the lab, I enabled the FoxyProxy extension to proxy all my requests through Burp Suite. Two requests got my attention: one fetching a JavaScript file and the other a POST request to /forgot-password.
Starting with the GET /static/js/forgotPassword.js, there is an interesting part in the JavaScript script:
forgotPwdReady(() => {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const resetToken = urlParams.get('reset-token');
if (resetToken)
{
window.location.href = `/forgot-password?reset_token=${resetToken}`;
}This part is responsible for getting the value of reset_token and verifying it. If it exists, it redirects with a GET request to /forgot-password with that reset_token.
From this information, I can build an attack path to get the administrator's reset_token, reset their password, log in as them, and delete the user Carlos.
I started working on how to get the reset_token of the administrator. I went to the POST /forgot-password request and sent it to the repeater in Burp Suite to start working on it.
POST /forgot-password HTTP/2
Host: 0ad9005904e93da6830b064c00c100e6.web-security-academy.net
Cookie: session=XX4y2Xd8qFXhlYM0Idm6QkEykmDJKSrs
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0
...
csrf=lUkBK6PRsgjJbI2kT8jKumH5v93cmXHK&username=administratorFirst, I tested for server-side parameter pollution by trying to truncate the query string using the # character and URL encoding it.
I received an error:
Since I truncated the query, there was still a parameter that didn't get its value, and the error indicated it was the field parameter. So I tried adding it to see what I would get:
I received an error indicating an invalid field:
Referring back to my earlier findings about the reset_token, I tried passing it to see if it could be reached:
I received the token in the response:
By simply sending a GET /forgot-password?reset_token=100oji58dtnwesl7euzmeri075etmhwd, I could access the password reset page for the administrator. I right-clicked the response, clicked Show response in browser, copied the URL, and pasted it into my browser. I reset the administrator's password, logged in as him, and deleted the user Carlos, solving the lab.