JWT格式:
Header.Payload.Signature
Header:{"alg":"HS256","typ":"JWT"}
其中 alg:表示使用的算法默认是HS256 ,typ:表示token类型
然后再用Base64URL 算法进行机密生成一串字符串
Payload: 也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。
{
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (NotBefore):生效时间
iat (IssuedAt):签发时间
jti (JWTID):编号
}
当然也可以在这一部分存储自己定义的端
Signature:这一部分就是 base64UrlEncode(header)+ base64UrlEncode(palyoad)+密钥
使用alg的算法进行加密
JWT原理:
web345
抓包访问/admin页面看到有这样一个内容,将这个内容进行base64解码
可以看到有前面两部分,在alg对应的是none就是没有加密方式
{"alg":"None","typ":"jwt"}?[{"iss":"admin","iat":1718866523,"exp":1718873723,"nbf":1718866523,"sub":"user","jti":"0212359dcd5afaabef646309ffb86792"}]
我们将内容复制进脚本里面
import jwt
payload ={"alg":"None","typ":"jwt"}
headers ={"iss":"admin","iat":1718865117,"exp":1718872317,"nbf":1718865117,"sub":"admin","jti":"503a4a179e5645e7be5c19a88450c618"}print(jwt.encode(payload,"", algorithm="HS256", headers=headers))
然后生成将生成的内容复制进/admin下的cookie里面
最终得到flag
web346、347、348
同理抓包
但是这次不同的是有了密钥加密所以后半部分无法解密,前两部分是明文base64加密,后部分是加密后的,所以无法正常解密
{“alg”:“HS256”,“typ”:“JWT”}
{“iss”:“admin”,“iat”:1718868269,“exp”:1718875469,“nbf”:1718868269,“sub”:“user”,“jti”:“f070150b78098e9f337a230ecac7d729”}
使用工具爆破出key是123456
然后我们使用脚本进行加密
修改提交即可
可以使用爆破,一般4位数字的可以爆破出来
可以尝试将加密算法改成none,只生成前两段
web349
/* 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');}});});
这段代码是一个使用 Express 框架构建的 Node.js 应用程序,处理 GET 和 POST 请求,并使用 JSON Web Token (JWT) 进行身份验证。代码逻辑如下:
GET 请求处理
- 设置响应类型为 HTML:
res.type('html');
- 读取私钥:
var privateKey = fs.readFileSync(process.cwd()+'//public//private.key');
从文件系统读取存储在
public/private.key
的私钥。这将用于签署 JWT。
- 生成 JWT:
var token = jwt.sign({user:'user'}, privateKey,{algorithm:'RS256'});
使用私钥签署一个 JWT,负载是
{ user: 'user' }
,签名算法是
RS256
(RSA SHA-256)。
- 设置 Cookie:
res.cookie('auth', token);
将生成的 JWT 设置为名为
auth
的 Cookie。
- 响应结束:
res.end('where is flag?');
发送响应并结束请求,响应内容是
'where is flag?'
。
POST 请求处理
- 设置响应类型为 HTML:
res.type('html');
- 获取存储的 flag:
var flag="flag_here";
- 获取 JWT:
var auth = req.cookies.auth;
从请求的 Cookies 中获取
auth
JWT。
- 读取公钥:
var cert = fs.readFileSync(process.cwd()+'//public/public.key');
从文件系统读取存储在
public/public.key
的公钥。这将用于验证 JWT 的签名。
- 验证 JWT:
jwt.verify(auth, cert,function(err, decoded){if(decoded.user==='admin'){
res.end(flag);}else{
res.end('you are not admin');}});
使用公钥验证 JWT。如果验证成功且
decoded.user
为
'admin'
,返回
flag
。否则,返回
'you are not admin'
。
总结
- GET 请求: 生成一个包含
{ user: 'user' }
负载的 JWT,签署后存储在名为auth
的 Cookie 中,并响应'where is flag?'
。 - POST 请求: 从请求的 Cookies 中读取
auth
JWT,使用公钥验证它,如果 JWT 有效且user
字段为'admin'
,返回flag
;否则,返回'you are not admin'
。
dirsearch 扫到文件
将私钥加载进去
将user改为admin,重新生成然后复制进去
web350
下载源码
观察到有解密算法,且解密代码中未提及算法。所以尝试更改算法为对称加密,将pubulic.key作为密钥
将RS256算法改为HS256(非对称密码算法=>对称密码算法)
HS256算法使用密钥所有消息进行签名和验证。
而RS256算法则使用私钥对消息进行签名并使用公钥进行身份验证。
创建test.js生成jwt
var jwt =require('jsonwebtoken');var fs =require('fs');var privateKey = fs.readFileSync('./public.key');var token = jwt.sign({ user:'admin'}, privateKey,{ algorithm:'HS256'});
console.log(token)
然后以post方式发包(带着jwt)
原文链接:https://blog.csdn.net/c1516175954/article/details/133095091
web834
打开操作页面,没有发现明显问题,尝试注册一个用户
尝试注册haha,密码为123456
尝试一下修改密码这个功能,在提交新密码的时候发现了问题,发现了jwt
爆破key,然后将haha改为admin
提示admin修改密码成功
密钥爆破仅针对与HS256
篡改算法只能是RS256->HS256
版权归原作者 清风实验室 所有, 如有侵权,请联系我们删除。