Solution for PortSwigger Academy Lab: Reflected DOM XSS
The following is my documentation on PortSwigger’s Academy labs.
End Goal: Create an injection that calls the alert() function
Reflected DOM XSS attack that calls the alert() function, brûléed
1
servings3
minutes10
minutes∞
kcalIngredients
1 (one) 4 oz BurpSuite Community Edition
1 (one) cooked XSS payload escaping backslash
1 cup Coffee, brewed
This lab explores injecting a payload that takes advantage of the eval() function in JavaScript. But what is the eval() function?
“The eval() function evaluates JavaScript code represented as a string and returns its completion value. The source is parsed as a script.”2
We’ll keep an eye out for this function in the backend as we solve the lab.
Using BurpSuite Proxy to intercept our request
First, we’ll open BurpSuite after starting our lab and turn our Intercept tool on. Next, we’ll type in a random string into the search box so as not to accidentally return anything real on the blog. In my case, I used “1nfornography” because I have an ego. Make sure to send our request to the Repeater tool and turn “Intercept” off.
Investigating our JSON response
When inspecting our results we see that our string shows up inside of a <h1> tag, but we should always be on the lookout for a script tag, as its contents will inform us further.
We quickly find an instance, but it is not one that we have come across in these labs before. the source URL means that the script is being loaded from an external file. Our response is called “search-results” and appears to be pulling from “searchResults.js”. Interesting. The “.js” extension tells us that this is JSON. Let’s dig deeper and try to find “searchResults.js”. To do so we’ll check out our “Network” tab in Firefox’s Web Development Tools.
In our investigation, we found that searhResults.js has the following: eval(‘var searchResultsObj = ‘ + this.responseText) The script calls the eval() function, passes searchResults as part of a string, then it concatenates this.responseText to the string before sending it to the dispalySearchResults function. So… why is this bad? Our good friends at MDN say that
“…eval() executes the code it’s passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user’s machine with the permissions of your webpage / extension. More importantly, allowing third-party code to access the scope in which eval() was invoked (if it’s a direct eval) can lead to possible attacks that reads or changes local variables.”3
Okay, good, never use it, got it. So how do we use it to do bad stuff? Well…
“The argument of the eval() function is a string. It will evaluate the source string as a script body, which means both statements and expressions are allowed”4
This means that eval() will run whatever script is given to it because “both statements and expressions are allowed”. Further, when we check our Response for “/search-results?search=1nfornography” in our Development Tools we see a JSON object made up of two keys, one of them being “searchTerm”.
Remember our friend, “responseText”? We found it here:
eval('var searchResultsObj = ' + this.responseText)
It just so happens that “searchTerm” is stored inside of it. We can go back to our search box and inject whatever script we want into it, and eval() will concatenate whatever is stored in this.responseText (that being “searchTerm”) with the searchResultsObj and evaluate whatever we searched.
Unfortunately, we run into a problem…
Yes. My lab timed out again because I was taking too long in my research. ADHD just keeps on giving. But our other problem…
JSON escaping quotation marks and what to do next
When we checked our results for “/search-results?search=1nfornography” we quickly saw that our string was placed into double quotation marks. We’ll have to escape them, but we know how to do that from previous labs. Let’s get our request into BurpSuite’s Repeater tool for ease of use.
Next, we’ll insert a double quotation at the end of our string and send it just to test if this will be as easy as we think it will be.
We can see in our Response tab that JavaScript has placed a backslash before our double quotation. Java does this to neuter the meaning of special characters. The fun part is that backslash is a special character. We can escape it with another backslash.
We’ve broken out. We just have an isolated double quote we need to comment out (with double forward slashes), and a curly bracket at the end of our alert() function to close the
“…JSON object early and comment out what would have been the rest of the object.”5
Our final payload looks like this: 1nfornography\"-alert(01)}//
All we have to do now is insert it into our search box, hit “Search” and…
And there we have it! We’ve solved our Reflected DOM XSS lab.
Notes
In making this write-up I used z3nsh3ll’s video on the subject as a resource with the articles mentioned in the footnotes.
Footnotes
- MDN never use eval() documentation. ↩︎
- MDN eval() documentation. ↩︎
- MDN never use eval() documentation ↩︎
- MDN seriously you guys, never use eval() documentation ↩︎
- Reflected DOM XSS Solution ↩︎
Share this:
Filed under: Cybersecurity,Pentesting,PortSwigger Academy,XSS attack - @ December 29, 2023 12:36 am