用户账号密码验证通过后,服务器将用户信息存储到 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年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
715502360440)]
[外链图片转存中…(img-CohFPTGa-1715502360440)]
[外链图片转存中…(img-LFsFRpi8-1715502360440)]
[外链图片转存中…(img-2qE6ucfG-1715502360440)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!