JWT介绍&空加密&暴破密钥&私钥泄露&密钥混淆&黑盒_jwt泄露

用户账号密码验证通过后,服务器将用户信息存储到 Session 里(Session 存放在服务端),并返回用户唯一的 session_id 写入到客户端 Cookie 里(Cookie 存放在客户端)。

用户下次请求会带上 Cookie 中的 session_id,然后服务器以此验证用户身份。

  • 2、基于 Token 验证流程

用户账号密码验证通过后,服务器会签发一个 Token(比如 JWT)给客户端,客户端收到后会将 Token 存放在 Cookie 或其他字段里。

用户下次请求会带上 Token,然后服务器使用密钥解密并验证用户身份。

以下为 JWT 认证的流程图:

3、JWT 的组成三个部分

以下为 JWT 的组成示意图,由头部、声明、签名三个部分组成。

  • Header(头部):用于声明加密算法(alg字段)、JWT类型(typ字段)等
  • Claims(声明):用于存储用户信息,如JWT面向的用户(sub字段)、JWT过期时间(exp字段)等
  • Signature(签名):用于对 Header 和 Claims 进行 Base64 编码和算法加密,拥有该部分的 JWT 被称为 JWS,也就是签了名的 JWT

以下为 JWT 解密后的示意图,需要补充的是加密算法 HS 表示对称加密,SA 表示非对称加密。

  • HS 的签名和验证都使用同一个密钥
  • SA 的签名使用私钥,验证使用公钥

4、JWT 的流量特征识别

对于人工识别而言,JWT 一般存在于 Authorization、Cookie 或者请求体里面,由 . 号分割为三个部分,并且 Header、Claims 都是以 eyJ 开头的 Base64 编码。

在工具的角度,可以使用 BurpSuite 插件配合 JWT 在线解析来识别。

BurpSuite 插件:Hae、JSON Web Tokens

JWT 在线解析:JSON Web Tokens - jwt.io

Hae 正常导入 jar 包后替换一下 config.yml 文件,JSON Web Tokens 直接到 Burp 商店下载就行,整体效果就是能通过颜色清晰的看到相关的流量包。

0x02 JWT 漏洞利用

利用工具(jwt_tool):https://github.com/ticarpi/jwt_tool

1、空加密算法(Header 中加密算法为 None)

JWT 支持将加密算法 “alg” 字段设定为 “None”,此时签名会被置空,任何 JWT 都是有效的。

以 CTFShow - Web345 为例,观察到返回包中指示访问 /admin 以获取 Flag。

访问 /admin 后观察返回包,并未发现 Flag,考虑是 JWT 的问题。

解密数据包中的 JWT 值,发现用户是 user 而不是 admin,尝试修改为 admin,但是发现无法在线修改。

将 JWT 值发到 Burp 的 Decoder 模块,先进行 Base64 解码,将 user 替换为 admin 后,再 Base64 编码得到 admin 用户的 JWT 值。

重新访问 /admin,带上 admin 用户的 JWT 值,得到 Flag。

以 CTFShow - Web346 为例,同样观察到返回包中指示访问 /admin,解密访问 /admin 的 JWT 值,观察到加密算法为 HS256,面向用户为 user。

因为这里的 JWT 使用了 HS256 加密,也就是签名有效且会对 Header 和 Claims 进行编码和加密处理,所以当不清楚密钥的情况下,直接修改 user 为 admin 是不行的。

这里考虑两种思路:1、爆破密钥,显然难度较大;2、尝试将加密算法置空,也就是 alg=none

同样,将 JWT 值发到 Decoder 模块,先 Base64 解码,将 HS256 替换为 none,user 替换为 admin 后,再 Base64 编码。

但需要注意的是,使用此方法要先将 Signature 部分删除掉,因为加密算法为 none 必须将签名置空,并且需要将 Header 和 Claims 分别处理后再用 . 号连接,因为实测直接一起处理是不行的。

最终的格式为:Header.Claims.(注意最后面还有一个 . 号)

重新访问 /admin,带上 admin 用户的 JWT 值,得到 Flag。

上述方法略为复杂,更方便的当然是使用工具,比如 jwt_tool、Burp 插件 JSON Web Tokens 等。

使用插件 JSON Web Tokens,将 HS256 替换为 none,user 替换为 admin,并删除 Signature 部分,重新发包即可。

jwt_tool 常用命令如下:

# 使用None算法
python3 jwt_tool.py JWT_HERE -X a
# 自定义修改生成
python3 jwt_tool.py JWT_HERE -T
# 使用字典破解
python3 jwt_tool.py JWT_HERE -C -d dictionary.txt
# 指定密码测试
python3 jwt_tool.py JWT_HERE -C -p password_here

需要注意的是,jwt_tool 最好是在 Linux 上运行,我使用的 Kali 运行,并且需要先导入几个包,命令如下:

python3 -m pip install termcolor cprint pycryptodomex requests

然后启动 jwt_tool,使用 -T 自定义修改模式,根据提示将 HS256 替换为 none,user 替换为 admin,最后会自动生成对应 JWT 值。

复制生成 JWT 值并删除 Signature 部分,重新发包即可获取 Flag。

2、暴力破解密钥

以 CTFShow - Web347 为例,同样访问 /admin 得到的是 user 的 JWT 值,尝试空加密算法无果。

由于加密算法为 HS256 对称加密,比较容易爆破密钥,所以考虑使用 jwt_tool 爆破密钥,最终得知密钥为 123456。

python jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMTM3NTE3NywiZXhwIjoxNzAxMzgyMzc3LCJuYmYiOjE3MDEzNzUxNzcsInN1YiI6InVzZXIiLCJqdGkiOiJhMDE3MDdmNDRmN2RmOGI1Y2JlNWUxMjlhMGY1YzMxMSJ9.Vjqa5vYv9uRUqiaQpsDxlswGfK5n2umAp-NrY0p39bg -C -d key_dictionary.txt

在 jwt.io 输入密钥,修改 user 为 admin,重新生成 admin 用户的 JWT 值,发包即可获得 Flag。

3、源码泄露私钥(JWT中私钥用于签名,公钥用于验证)

以 CTFShow - Web349 为例,这一关给了一个 JS 文件,模拟的是源码泄露,具体代码如下:

***代码解释***

1、当GET请求发送到根路径(‘/’)时,会执行以下操作:

使用res.type()方法将响应的内容类型设置为html

使用fs.readFileSync()方法读取当前工作目录下的public/private.key文件,并将其内容赋值给privateKey变量

使用jsonwebtoken库的sign()方法生成一个JSON Web Token(JWT),其中包含用户信息为’user’,使用privateKey进行签名,使用RS256算法

使用res.cookie()方法将生成的JWT写入名为’auth’的cookie

使用res.end()方法发送响应内容为’where is flag?'的响应


2、当POST请求发送到根路径(‘/’)时,会执行以下操作:

设置响应内容类型为html

获取名为’auth’的cookie的值赋值给auth变量

使用fs.readFileSync()方法读取当前工作目录下的public/public.key文件,并将其内容赋值给cert变量

使用jsonwebtoken库的verify()方法验证auth变量中的JWT是否有效,使用cert公钥进行验证。

如果JWT中的用户信息为’admin’,则发送包含flag的响应;否则,发送包含’you are not admin’的响应

通过解密 JWT 得知其使用的加密算法为 RS256,和前面的不同是这里是非对称加密。

***在使用非对称加密算法的 JWT 中,私钥用于签名,公钥用于验证。***这是因为公钥是公开的,如果用公钥进行签名,那么攻击者便很容易伪造 JWT 了,显然不合理。

于是我们只要拿到用于签名的私钥,便可伪造 admin 用户的 JWT 拿到 Flag。这里通过泄露的 JS 代码得知私钥存放位置为当前目录下,于是直接访问下载 private.key。

拿到了私钥之后,利用其重新生成 admin 用户的 JWT 值。

这里我使用 Python 来生成,具体代码如下***(需要注意这段代码需要导入两个包,JWT 和 PyJWT)***

pip install JWT PyJWT

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

715502360440)]

[外链图片转存中…(img-CohFPTGa-1715502360440)]

[外链图片转存中…(img-LFsFRpi8-1715502360440)]

[外链图片转存中…(img-2qE6ucfG-1715502360440)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 26
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值