JWT渗透与攻防

前言

JSON Web Token(JWT)作为一种广泛使用的认证机制,因其简单、有效和灵活性而受到开发者的青睐。然而,随着JWT使用的普及,其安全性问题也逐渐显现。本文将探讨JWT的渗透测试方法,分析常见的安全漏洞,并提供相应的防护措施。

JWT的基本概念

JWT是一种用于信息交换的开放标准(RFC 7519),它以紧凑的URL安全格式编码信息。JWT通常由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。这种设计使得JWT能够在不同的系统之间安全地传递信息。

它遵循JSON格式,将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验证token,通过token验证用户身份。基于token的身份验证可以替代传统的cookie+session身份验证方法。这使得JWT成为高度分布式网站的热门选择,在这些网站中,用户需要与多个后端服务器无缝交互。

JWT识别

1、标头(Header)

Header是JWT的第一个部分,是一个JSON对象,主要声明了JWT的签名算法,如”HS256”、”RS256″等,以及其他可选参数,如”kid”、”jku”、”x5u”等

alg字段通常用于表示加密采用的算法。如”HS256″、”RS256″等

typ字段通常用于表示类型

还有一些其他可选参数,如”kid”、”jku”、”x5u”等

2、有效载荷(Payload)

Payload是JWT的第二个部分,这是一个JSON对象,主要承载了各种声明并传递明文数据,用于存储用户的信息,如id、用户名、角色、令牌生成时间和其他自定义声明。

iss:该字段表示jwt的签发者。

sub:该jwt面向的用户。

aud:jwt的接收方。

exp:jwt的过期时间,通常来说是一个时间戳。

iat:jwt的签发时间,常来说是一个时间戳。

jti:此jwt的唯一标识。通常用于解决请求中的重放攻击。该字段在大多数地方没有被提及或使用。因为使用此字段就意味着必须要在服务器维护一张jti表, 当客户端携带jwt访问的时候需要在jti表中查找这个唯一标识是否被使用过。使用这种方式防止重放攻击似乎让jwt有点怪怪的感觉, 毕竟jwt所宣称的优点就是无状态访问

签名(Signature)

Signature是对Header和Payload进行签名,具体是用什么加密方式写在Header的alg 中。同时拥有该部分的JWT被称为JWS,也就是签了名的JWT。

对Header和Payload进行签名,具体是用什么加密方式写在Header的alg中。

同时拥有该部分的JWT被称为JWS,也就是签了名的JWT。

第一部分:对 JSON 的头部做 base64 编码处理得到

第二部分:对 JSON 类型的 payload 做 base64 编码处理得到

第三部分:分别对头部和载荷做base64编码,并使用.拼接起来

使用头部声明的加密方式,对base64编码前两部分合并的结果加盐加密处理,作为JWT

JWT安全

1、空加密算法(攻击头部不使用加密)

签名算法可被修改为none,JWT支持将算法设定为”None”。如果”alg”字段设为”None”,那么签名会被置空,这样任何token都是有效的。

我们通过ctfshow靶场演示(web345)


这里可以看到我们解码后看到加密算法为None ,没有任何加密这里我们直接将jwt面向的用户改为admin即可绕过

替换后得到flag

2、未校验签名(攻击签名不使用签名认证)

算绕绕过签名(web346)

通过解码看到加密算法为HS256

我们通过插件json web tokens 直接更改加密算法为none,对象索引改为admin

如果“alg” 字段设为“ None”,那么签名会被置空,这样任何 token 都是有效的

3、暴力破解密钥(攻击签名知道密钥实现重组)

针对是对称加密算法(非对称没有用)

非对称要使用方法:获取源码或者公钥私钥文件

某些签名算法,例如HS256(HMAC+SHA-256),会像密码一样使用一个任意的、独立的字符串作为秘密密钥。这个秘钥如被轻易猜到或暴力破解,则攻击者能以任意的头部和载荷值来创建JWT,然后用密钥重新给令牌签名。

弱口令爆破(web347)

使用工具破解 jwt-tools

利用项目:https://github.com/ticarpi/jwt_tool

#安装必要库
python3 -m pip install pycryptodomex
# 自定义修改生成
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

这里我们只能弱口令top1000爆破得到密钥为123456


通过jwt官方网站替换密钥为123456后重新生成jwt提交得到flag

4、源码泄漏密匙

web(349)

该题采用RS256非对称加密,所以不能使用爆破的方式

且代码文件中泄露了公钥私钥存储位置,公钥私钥泄露,访问/private.key、/public.key得到公钥密钥

源码中私钥生成jwt,利用公钥解密jwt,只要有私钥就可以重新生成JWT

pyhton 安装这个库

利用私钥文件重新生成

import jwt
public = open('private.key', 'r').read()
payload={"user":"admin"}
print(jwt.encode(payload, key=public, algorithm='RS256'))

利用重新生成的jwt访问

源码了里显示提交方式是post,我们切换提交方法即可得到flag

web350(密钥混淆攻击RS256=>HS256)

这题和上题一样通过私钥生成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)
觉得有帮助可以投喂下博主哦~感谢!
作者:明弟有理想
版权声明: 本站所有文章,如无特殊说明或标注,均为本站原创发布。转载请注明文章地址及作者。
如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
文章声明:
文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任,本人坚决反对利用文章内容进行恶意攻击行为,推荐大家在了解技术原理的前提下,更好的维护个人信息安全、企业安全、国家安全,本文内容未隐讳任何个人、群体、公司。请注意,本文并非文学作品,请勿过度理解。请大家自觉遵守《网络安全法》,感谢您的理解与支持!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇