Intro
This post is dedicated to XSS related Labs at Portswigger Web Academy
TOC
- Intro
- Finding a XSS
- Reflected XSS into HTML context with nothing encoded
- Reflected XSS into attribute with angle brackets HTML-encoded
- Reflected XSS in canonical link tag
- Reflected XSS into a JavaScript string with single quote and backslash escaped
- Reflected XSS into a JavaScript string with angle brackets HTML encoded
- Reflected XSS into a JavaScript string with angle brackets and double quotes HTML-encoded and single quotes escaped
- Reflected XSS into a template literal with angle brackets, single, double quotes, backslash and backticks Unicode-escaped
- Reflected XSS into HTML context with most tags and attributes blocked
- Reflected XSS into HTML context with all tags blocked except custom ones
Finding a XSS
- Test every endpoint
- Submit random alphanumeric values.
- Determine the reflection context.
- XSS between HTML tags
- XSS in HTML tag attributes
- XSS into JavaScript
- XSS via client-side template injection
- Test a candidate payload.
- Test alternative payloads.
- Test the attack in a browser.
Reference: https://portswigger.net/web-security/cross-site-scripting/reflected
Reflected XSS into HTML context with nothing encoded
This lab contains a simple reflected cross-site scripting vulnerability in the search functionality.
To solve the lab, perform a cross-site scripting attack that calls the alert function.
So we need to trigger an alert.
This payload does the job: <script>alert(1)</script>
We’ve injected <script>
tag into <h1>
as there is no sanitization on the server-side (or even client-site) present:
Reflected XSS into attribute with angle brackets HTML-encoded
This lab contains a reflected cross-site scripting vulnerability in the search blog functionality where angle brackets are HTML-encoded. To solve this lab, perform a cross-site scripting attack that injects an attribute and calls the alert function.
We can check how our payload is injected by issuing search. I’ve used simple testing
string.
We can use payload like " onmouseover="alert(1)
to get out of attribute and create our own.
Reflected XSS in canonical link tag
This lab reflects user input in a canonical link tag and escapes angle brackets.
To solve the lab, perform a cross-site scripting attack on the home page that injects an attribute that calls the alert function.
To assist with your exploit, you can assume that the simulated user will press the following key combinations:
ALT+SHIFT+X
CTRL+ALT+X
Alt+X
Please note that the intended solution to this lab is only possible in Chrome.
Payload used: ?%27accesskey=%27x%27onclick=%27alert(1)
.
We can see the inject here:
accesskey="x"
This sets the X key as an access key for the whole page. When a user presses the access key, the alert function is called.
Here another reference: https://security.stackexchange.com/questions/205975/is-xss-in-canonical-link-possible
And Wikipedia on Link Canonical in general and what’s its purpose: https://en.wikipedia.org/wiki/Canonical_link_element
Reflected XSS into a JavaScript string with single quote and backslash escaped
This lab contains a reflected cross-site scripting vulnerability in the search query tracking functionality. The reflection occurs inside a JavaScript string with single quotes and backslashes escaped.
To solve this lab, perform a cross-site scripting attack that breaks out of the JavaScript string and calls the alert function.
I used random string to see where our possible injection might be:
So it’s in the Javascript string as the titel already says - obviously.
Simply escaping using single quote won’t do the job as it get’s escaped. We can however close the script and run our own using following payload: </script><script>alert(1)</script>
This is what happens:
Portswigger says: The reason this works is that the browser first performs HTML parsing to identify the page elements including blocks of script, and only later performs JavaScript parsing to understand and execute the embedded scripts.
Who would have thought, huh!! :)
Reflected XSS into a JavaScript string with angle brackets HTML encoded
This lab contains a reflected cross-site scripting vulnerability in the search query tracking functionality where angle brackets are encoded. The reflection occurs inside a JavaScript string. To solve this lab, perform a cross-site scripting attack that breaks out of the JavaScript string and calls the alert function.
Now we’re injection again into String in Javascript, however if we try following payload as in the lab before </script><script>alert(1)</script>
, then we’ll see this:
… we didn’t get far, did we?
We’re still lucky as now single quote does not get encoded.
This is the payload that i’ve used '; alert(1) //
, but this would also work '-alert(1)-'
Reflected XSS into a JavaScript string with angle brackets and double quotes HTML-encoded and single quotes escaped
This lab contains a reflected cross-site scripting vulnerability in the search query tracking functionality where angle brackets and double are HTML encoded and single quotes are escaped.
To solve this lab, perform a cross-site scripting attack that breaks out of the JavaScript string and calls the alert function.
I’ve just entered the string qwr
to see where it does get reflected:
Let’s try with string qw/-#\"r
. We’get 'qw/-#\\"r'
in response. We get escape on single quote and double quote HTML encoded. If we prepend backslash we can escape the escaped backslash for single quote:
\'-alert(1)//
which becomesvar searchTerms = '\\'-alert(1)//';
Reflected XSS into a template literal with angle brackets, single, double quotes, backslash and backticks Unicode-escaped
This lab contains a reflected cross-site scripting vulnerability in the search blog functionality. The reflection occurs inside a template string with angle brackets, single, and double quotes HTML encoded, and backticks escaped. To solve this lab, perform a cross-site scripting attack that calls the alert function inside the template string.
Enter <>"'()
Since we have injection into JavaScript Template literal, we don’t need to terminat, but can use ${..}
like ${alert(document.domain)}
which also is solution for this lab.
Reflected XSS into HTML context with most tags and attributes blocked
This lab contains a reflected XSS vulnerability in the search functionality but uses a web application firewall (WAF) to protect against common XSS vectors.
To solve the lab, perform a cross-site scripting attack that bypasses the WAF and calls the print() function.
Note
Your solution must not require any user interaction. Manually causing print() to be called in your own browser will not solve the lab.
Let’s try something
If we input tags like a, img, script we’ll get a message that Tag is not allowed. I will sent all Tags into intruder to see which might work.
We can take body
.
Regarding events we can do same as it has been done with tags
. We can just copy the events from XSS cheatlist
Now we would prefer an event where no user interaction is needed. If we take resize, we need a manual resize action, or else the payload won’t trigger. Since we’re sending this to a victim, we can esize a window of iframe.
Payload:
1
<iframe src="https://0a8200dd0430075fc1530929004900c8.web-security-academy.net/?search="><body onresize=print()>" onload=this.style.width='100px'>
Reflected XSS into HTML context with all tags blocked except custom ones
This lab blocks all HTML tags except custom ones.
To solve the lab, perform a cross-site scripting attack that injects a custom tag and automatically alerts document.cookie.
For this lab we need custom tags. Portswigger has a great cheat sheet for that:
Worked for me: <xss autofocus tabindex=1 onfocus=alert(1)></xss>
Deliver the payload to the victim using the exploit server.
1
2
3
<script>
location = 'https://0ab4004c046a1cd880762c14003c005d.web-security-academy.net/?search=<xss autofocus tabindex=1 onfocus=alert(document.cookie)></xss>';
</script>