技术解析 | JWT弱点的利用方式

百家 作者:平安安全应急响应中心 2022-07-19 19:39:11


>>>0x01 背景介绍


JWT(Json Web Token)是⼀种基于json的,用于在网络上声明的令牌。JWT是由三部分组成:头信息(header),消息体(payload)和签名(signature)。它是为了在络应环境间传递声明而执行的⼀种基于JSON的开放式标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。


JWT的声明⼀般被用在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加⼀些额外的业务逻辑所必须声明信息,该token也可被直接用于认证,也可作加密。


>>>>0x02 准备工作

JWT 在线解析地址:https://jwt.io/


常见的JWT格式内容如下:



jwt的生成token格式如下,即:由 . 连接的三段字符串组成。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c


生成规则如下:


第⼀段HEADER部分,固定包含算法和token类型,对此json进行base64url加密,这就是token的第⼀段。

{"alg": "HS256","typ": "JWT"}


第⼆段PAYLOAD部分,包含⼀些数据,对此json进行base64url加密,这就是token的第二段。

{"sub": "1234567890","name": "John Doe","iat": 1516239022...}


第三段SIGNATURE部分,把前两段的base密文通过.拼接起来,然后对其进行HS256加密,再然后对hs256密文进行base64url加密,最终得到token的第三段。

base64url( HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), your-256-bit-secret (秘钥加盐) ))


最后将三段字符串通过 .拼接起来就生成了jwt的token。


>>>0x03 研究细节


针对JWT的安全隐患,主要存在以下几种攻击方式:


· 空加密算法


原理:JWT空加密算法的初衷是用于调试,有时候开发人员忘记在生产环境开启了空加密算法,缺少签名算法,那JWT保证信息不被篡改的功能就会失效。攻击者只要把alg字段设置为None,就可以在payload构造身份信息来伪造用户身份。


当前jwt指定的alg为HS256算法,如下:


header部分:

{ "alg":"HS256" "typ":"JWT" }


将其修改为None,然后输出:

import jwtprint(jwt.encode({"userName":"admin","userRoot":1001}, key="", algorithm="none"))


输出为:

eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VyTmFtZSI6ImFkbWluIiwidXNlclJvb3QiOjEwMDF9.


删掉最后的 "." ,然后带⼊原有的数据包进行发包测试,看 server 端是否接受 none 算法?若服务器接受,server就不会对payload内容进行签名校验,从而绕过了算法签名。


Tips:如果没有 jwt 模块,需要 pip install pyjwt 一下。


重点:建议使用burp插件Json Web Token Attacker 来尝试进行alg空算法攻击,因为不同none,None,NONE效果不⼀样。


· 爆力破解弱密钥


JWT密钥爆破需要在如下前提下进行:

  • 知悉JWT使用的加密算法

  • ⼀段有效的、已签名的token

  • 签名的密钥比较弱


爆破通常需要利用jwt-cracker工具,nom install --global jwt-cracker,如下图:



尝试爆破弱密码:



爆破需要运行⼀段时间,才能有结果。同时还有攻击hashcat工具都可以尝试利用爆破。


· 篡改 jwt kid参数


kid是jwt header中的⼀个可选参数,全称是key ID,它用于指定加密算法的密钥。

{ "alg" : "HS256", "typ" : "jwt", "kid" : "/home/jwt/.ssh/pem"}


因为该参数可以由用户输入,所以也存在安全隐患。


1) kid参数用于读取密钥文件,如果没有过滤kid参数,修改kid参数可以读取系统任意文件。

{ "alg" : "HS256", "typ" : "jwt", "kid" : "/etc/passwd"}


2) kid参数有时候从数据库中提取,所以也会造成SQL注入攻击,如下:

{ "alg" : "HS256", "typ" : "jwt", "kid" : "key11111111' || union select 'secretkey' -- "}


3)可能会造成命令注入,但是利用条件比较苛刻,前提是服务器后端使用的是Ruby,在读取密钥文件时使用了open函数,通过构造参数就可能造成命令注入。

"/path/to/key_file|whoami"

· 修改RSA加密算法为HMAC


原理:当header头部指向指定的签名算法为RSA非对称加密算法时,可以替换为HMAC对称加密算法,并且通过获取到的公钥重新做签名,服务器在签名校验时便可能会使⽤公钥做校验。


操作方法:可以修改 alg 为 HS256 对称加密算法,然后使⽤我们可以获取到的公钥作为 key 进行签名加密,这样⼀来,当我们将 jwt 传给 server 端的时候,server 端因为默认使用的是公钥解密,而算法为修改后的 HS256 对称加密算法,所以肯定可以正常解密解析,从而绕过了算法限制。


tips:当 server 端严格指定只允许使用 HMAC 或者 RSA 算法其中⼀种时候,这样攻击手段是没有效果的。


>>>> 0x04 总结


JWT中存在的安全风险,可以按照上述内容尝试利用。


>>>0x05 相关实验材料


下面是空加密算法和暴力破解两种攻击方式的实践,详情如下:


· JWT 空加密算法攻击


靶场地址:https://authlab.digi.ninja/JWT_None


利用操作:


1)在Vaildate Token 利用burp 可以找到JWT 认证token。



JWT token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoicm9iaW4iLCJsZXZlbCI6InVzZXIifQ.oYPuxIPnm6lYx3Zx_8zaMGVw7Np5nZtgJVnaMqlZcOQ


尝试解码内容如下:

{"alg":"HS256","typ":"JWT"}.{"user":"robin","level":"user"fQ.¡îÄç©XÇvq_ó6\;6gfØ VvªV\OQ


上述查看JWT利用HS256的加密算法,尝试改成None,加密payload数据{"user":"robin","level":"user"}


尝试将其修改为None,然后输出,参照"0x03中空加密算法"的方式:

import jwtprint(jwt.encode({"user":"robin","level":"user"}, key="", algorithm="none"))


输出为:


b'eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VyIjoicm9iaW4iLCJsZXZlbCI6InVzZXIifQ.


在burp中删掉最后的"." ,然后带入原有的数据包进行发包测试,结果如下:



尝试修改none攻击报错了,说明server不支持none。


实际测试如下显示,改不支持"none" signature



尝试使用:


burp的⼀款插件,名为Json Web Token Attacker,在Burp自带的扩展商店中便能找到安装。



再次尝试修改alg为None攻击,如下图:



攻击成功,上图可看出配置的alg:None,然后python编码默认支持none这种类型。所有使用python修改alg为none,攻击不成功。


该插件有⼀个优点,可以⽀持signature Exclusion,修改各种alg类型,如下图:



· 暴力破解


靶场地址:https://authlab.digi.ninja/JWT_Cracking


开始尝试获取easy默认密钥爆破,如下图:



内容为:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTM4MzE4NTksImxldmVsIjoidXNlciIsInVzZXIiOiJqYXNwZXIifQ.zUKmITL4IYkSV7bknQaxwcid8Ky-qN8jrd0SlTO7eRc


尝试使用c-jwt-cracker 进行爆破,如下图:



爆破得到hello,进⼊https://jwt.io/#debugger-io,使用获得的密钥重新签发token并修改Payload,



重新签发的token,验证发现有效,如下图:



>>>0x06 参考链接
  • https://blog.csdn.net/weixin_45329947/article/details/124671025【Json web token JWT攻防】

  • https://mp.weixin.qq.com/s?__biz=MzI2NDQyNzg1OA==&mid=2247487686&idx=1&sn=b6fabd8d7fa45
  • 198ba22e09d47d222b4 【Web基础技术|JWT(Json Web Token)认证】
  • https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/ 【Attacking JWT
  • authentication】
  • https://authlab.digi.ninja/JWT_Cracking 【Cracking JWT Keys】
  • https://blog.csdn.net/cdyunaq/article/details/122561096 【渗透测试-JWT攻击】
  • https://jwt.io/ 【JWT在线解析】

银河实验室

银河实验室(GalaxyLab)是平安集团信息安全部下一个相对独立的安全实验室,主要从事安全技术研究和安全测试工作。团队内现在覆盖逆向、物联网、Web、Android、iOS、云平台区块链安全等多个安全方向。
官网:http://galaxylab.pingan.com.cn/


往期回顾


技术

TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器

技术

TP-Link-WDR-7660 安全研究之固件分析

技术

C# 逆向入门

技术

【干货】cobaltstrike通信协议研究



点赞、分享,感谢你的阅读▼ 


▼ 点击阅读原文,进入官网

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接