This lab using a strict CSP that blocks outgoing requests to external web sites.
To solve the lab, first perform a attack that bypasses the CSP and exfiltrates a simulated victim user's token using Burp Collaborator. You then need to change the simulated user's email address to hacker@evil-user.net
.
You must label your vector with the word "Click" in order to induce the simulated user to click it. For example:
<a href="">Click me</a>
You can log in to your own account using the following credentials: wiener:peter
After logging in with the provided credentials, I navigated to the /my-account
page where I found the update email functionality. I noticed that the URL contained an id
parameter. I replaced the id
parameter with the email
parameter to see what would happen:
Upon doing this, I noticed that the input was reflected in an input tag:
Additionally, I observed another input field with the CSRF token:
I kept this in mind and tried to escape the value
attribute in the email input field and inject another tag:
Injecting this payload worked. I saw an image placeholder on the page, though no image appeared since the link provided didn't exist. I also noticed this interesting header in the request intercepted by BurpSuite:
This Content Security Policy (CSP) header indicated that images could only be loaded from the same origin due to the img-src 'self'
directive. I observed that links in canonical tags were not restricted, meaning I could use external links. I tested this payload:
A new link appeared on the page, and clicking it redirected me to Google, confirming that links in the canonical tag worked.
Next, I planned to steal the victim's CSRF token. I explored two methods for achieving this, understanding the nuances of CSP injection better.
Since I could make the victim visit a host I controlled (the exploit server), I needed a way to send the CSRF token to my host. From PortSwigger's XSS cheat sheet, I found a payload in the Dangling markup section:
This payload passes markup data through window.name
using the base target
attribute. To exploit this, I crafted the following payload:
When injected, it looked like this in the email input field:
The target
attribute isn't closed, so it captures data until it finds a closing ">
, which in this case is at the end of the CSRF token's value attribute. This base tag passes all this data to the visited page (http://evil.com
), storing it in the window.name
property.
To steal the CSRF token from the victim, I built this final payload:
Using the exploit server as my evil host, my payload looks like this:
This script checks if window.name
is filled; if yes, it contains the CSRF token and sends it to the exploit server. If window.name
is empty, it redirects the victim to the lab page with my XSS payload to pass the CSRF token value through the base target tag.
After clicking Store
and Deliver exploit to victim
, I checked the access log and found this GET request with a lot of data URL encoded:
After URL decoding this data, I extracted the CSRF token value mGJwHU12TI9Km421XY41nkbcAhb43Cwr
.
I closed the previous form of the change-email function and injected a new form that sends a GET request to my exploit server. Since it's a form action, the CSRF token will be present in the request:
I used this payload in my exploit server HTML page:
When the victim visits my exploit server, they are redirected to the lab page with my payload, which includes a form that sends a GET request to the log endpoint of my exploit server. A button labeled "Click me" will trigger the victim to press the button and submit the form. This form ignores the original form and submits the malicious form instead.
After clicking Store
and Deliver exploit to victim
, I checked the access logs and found:
Now that I had the CSRF token, I needed to use it to change the victim's email. However, I didn't have the victim's session cookie to submit the form as the victim, so I made the victim submit the form instead. I hosted a malicious HTML page on my exploit server with the email change form filled with the values I needed:
After clicking Store
and Deliver exploit to victim
, I confirmed that the lab was solved, indicating the victim's email had been changed.
TThis method is inspired by , where I use the form tag to steal the victim's CSRF token.