DOM XSS in jQuery selector sink using a hashchange event

Description

This lab contains a DOM-based cross-site scripting vulnerability on the home page. It uses jQuery's $() selector function to auto-scroll to a given post, whose title is passed via the location.hash property.

To solve the lab, deliver an exploit to the victim that calls the print() function in their browser.

Approach

After accessing the home page, I pressed CTRL+U to read its code and found an interesting script:

<script>
$(window).on('hashchange', function(){
var post = $('section.blog-list h2:contains(' + decodeURIComponent(window.location.hash.slice(1)) + ')');
if (post) post.get(0).scrollIntoView();
});
</script>

This jQuery script uses the $() selector function to auto-scroll to a given post, whose title is passed via the location.hash source. To exploit this vulnerability, I needed to make the victim visit the home page where I control the location.hash source and trigger the XSS by navigating to the appropriate select element. I crafted this simple payload:

<iframe src="https://0a8100e504f84a8585cf678800930059.web-security-academy.net/#" onload="this.src+='<img src=1 onerror=print(1)>'">

Once the victim visits my payload, the home page of the website will load with the element focused on #, which points to the home page itself. The onload event handler will be triggered once the page is loaded, and it will append <img src=1 onerror=print(1)> to the actual src of the iframe using this.src+=.

The final step was to open the exploit server, paste this payload into my malicious HTML page, and then click on Store and Deliver exploit to victim. The lab was successfully solved.