In this post, we’re going to be solving the lab: “DOM XSS in jQuery selector sink using a hashchange event”:

To solve the lab, we need to send a victim an exploit that leverages the lab’s vulnerability to execute the print() function.
First of all, let’s access the lab:

In this case, we don’t see any search bar or feedback page as has happened in other XSS challenges. However, if we go to the source code, we find the following piece of code:

This code basically searches for a value on the website when something is specified in the URL after a hashtag and scrolls to the match.
For example, if we go all the way down to the bottom of the lab, we can see that there’s a post that has the word “Resume” in the title:

Knowing this, we’re going to search for:
<URL>/#Resume

We press enter.

And although it can’t be appreciated in the image, it automatically redirects us to the post that contains the word.
To see how to exploit this, let’s bring back the code:

As we can observe, what really happens in the code is that when we specify something after the hashtag, jQuery tries to find an h2 element that contains what we said. When it finds the element, it’s stored in the post variable, so now what it contains is a jQuery element that looks like this:

Note: a different lab URL shows up because this is a screenshot I took at another time :P
Subsequently, if the post variable has any stored data, the first element of the jQuery object is obtained and the scrollIntoView() method is used.
Here the vulnerability as such is found in the first line, in the jQuery selector sink ($()):


Note: this image is also from another time :P
If it’s not sanitized properly, what happens approximately in the code is the following:
$('section.blog-list h2:contains(' + decodeURIComponent(window.location.hash.slice(1)) + ')');$('section.blog-list h2:contains(' + Hello + ')');
Therefore, if we put a payload like the following:
<img src=/ onerror=print()>
More or less, something like this would happen:
$('section.blog-list h2:contains(' + <img src=/ onerror=print()> + ')');
This way, it would be interpreted. Let’s test it:

We press enter:

And indeed it executes. Now we need to create an exploit that we send to the victim and makes use of this vulnerability. To do this, we go to the exploit server:


In this case, the idea is to automate the exploitation using a simple <iframe>:

Before sending it, let’s see what it would look like:


The victim when visiting a website with our code would see what we’re seeing, a small iframe of the website, and immediately after the website loads, the print() function would execute:

So, seeing that it works, we simply save it and send it to the victim:


This way, we successfully solve the lab:

