0


JWT安全漏洞以及常见攻击方式

前言

随着web应用的日渐复杂化,某些场景下,仅使用Cookie、Session等常见的身份鉴别方式无法满足业务的需要,JWT也就应运而生,JWT可以有效的解决分布式场景下的身份鉴别问题,并且会规避掉一些安全问题,如CORS跨域漏洞,CSRF漏洞等。

JWT简介

JWT即Json Web Token的缩写,顾名思义,是Token的一种。它常被用来在向服务器发起请求时用作身份认证。使用JWT作为身份认证的优势在于:它不需要在服务端去保留用户的认证信息。仅需要对该Token正确性进行校验即可,这就意味着基于token认证机制的应用,不需要去考虑用户在哪一台服务器登录了,为应用的扩展提供了便利。

新技术带来便利的同时也会带来新的安全问题,如果JWT本身安全存在问题,那么整个身份认证机制就会得不到保障。

JWT由三部分组成,类似于

xxx.yyy.zzz

,前两部分是base64编码的内容,第三部分是加密的签名部分

  1. 第一部分被称为header,会说明字符串的类型以及加密方式,当然还会包含其他一些字段,在介绍JWT安全问题时会涉及到部分。在这里插入图片描述
  2. 第二部分被称为payload,包含用户的身份id,是否是管理权限等字段,这部分中的相关字段可以根据实际情况自行定义。在这里插入图片描述
  3. 第三部分是加密部分,对前面的“xxx.yyy”用头部中声明的加密方法进行加密,保证JWT的完整性。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

JWT常见安全问题

JWT相关CVE漏洞

下面是JWT相关的一些CVE漏洞

(CVE-2015-2951) alg=none签名绕过漏洞
(CVE-2016-10555) RS/HS256公钥不匹配漏洞
(CVE-2018-0114)密钥注入漏洞
(CVE-2019-20933/CVE-2020-28637)空白密码漏洞
(CVE-2020-28042)空签名漏洞

弱签名算法(无算法)

更改头部中声明的加密算法

例如将下面的HS256更改为none,可以只篡改前两部分,而不改变第三部分签名的情况下进行绕过,或者删除第三部分,但是记得保留“.” 这个符号,以保证符合JWT的格式

在这里插入图片描述

存在这种漏洞一般是第三方JWT库存在问题,或者是代码编写错误,生成JWT的代码中使用了none,如下所示
在这里插入图片描述

弱密码

如果JWT使用HS系列(对称加密)的加密方法,而且使用较为简单的Key进行加密,那么使用工具就极有可能能够得到key,之后就可以随意的篡改JWT了。

常用的工具

1.jwt_tool
2.hashcat

使用工具破解下面的JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.dQknU80__AHPVDmZPFavWdML1XKrVYPLeOXNMo

利用kid标头

在JWT的头部中,除了存在typ 以及alg之外,还可以存在其他内容。KID 标头是一个密钥标识符。kid是RFC标准中用来表示密钥存储位置的地方,服务端可以根据这个提示来寻找解密密钥。
根据代码的编写情况,可能存在以下问题

  1. SQL注入
  2. 目录遍历
  3. 命令执行

SQL注入

这种情况是密钥存储在数据库中,使用kid字段查询相关内容,代码如下所示
在这里插入图片描述

目录遍历

kid的值表示的是密钥存储的文件,通过构造payload,就可能会造成目录遍历漏洞

在这里插入图片描述

命令执行

kid的值会被带入到要执行的命令之后,代码如下所示

在这里插入图片描述

利用JKU标头

jku头是用来获取jwks(json web keys)文件的,这是一个json文件,用来指定获取密钥。我们可以简单地托管我们自己的 JWKS 文件并将他的 jku 指向我们的服务器。

在这里插入图片描述

出现此问题的主要原因是应用程序必须解码令牌并使用它来获取 jwks,以便它可以构建公钥并验证令牌。

因此,如果应用程序在没有任何验证的情况下简单地信任 jku,那么这可能会被滥用。

jwks 文件的格式

在这里插入图片描述

利用步骤如下

  1. 创建公私密钥对
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
  1. 创建我的jwk 文件,通过在线工具 https://russelldavies.github.io/jwk-creator/

public Key Use 选择 sigining,
Algorithm 选择JWT头部中声明的算法
Key id与 头部中声明的一致
然后将生成的公钥的值粘贴框中

在这里插入图片描述

  1. 修改并保存JWKS文件,根据原来JWKS文件中的kid的值,替换对应的部分,用生成jwk替换掉原来的部分,然后就可以篡改JKU头指向我们托管的服务器,以及payload中对应的值,然后进行利用公钥签名,向服务器发送我们构造的JWT即可,可以使用在线工具jwt.io,或者python以及java代码利用私钥生成篡改的JWT。

易受攻击代码示例
在这里插入图片描述

利用 X5C 标头

x5c 标头包含可用于验证JWT的 x509certificate/x509certificate 链。正常流程是提取证书中的公钥,然后验证JWT,如果信任x5c中的值,而不进行验证,那么我们可以生成自己的证书和然后用私钥签名篡改后的内容即可。

在这里插入图片描述

攻击流程

  1. 创建证书并提取公私密钥
openssl req -x509 -nodes -days -newkey rsa:2048 -keyout attacker.key -out attacker.crt
openssl x509 -pubkey -noout -in attacker.crt > publicKey.pem

2.篡改令牌并用您的 x509 证书代替 x5c 声明。

3.修改token,用私钥签名。

易受攻击代码示例
在这里插入图片描述

利用X5U标头

x5u标头的问题与juk的问题一致,只不过是地址指向的是存储证书的位置,它用于从 Web 服务器获取 x5c 证书,该证书将用于从中创建公钥并验证令牌。
在这里插入图片描述

利用流程

  1. 创建证书和公私 rsa 密钥对
openssl req -x509 -nodes -days -newkey rsa:2048 -keyout attacker.key -out attacker.crt
openssl x509 -pubkey -noout -in attacker.crt > publicKey.pem

2.托管证书

3.篡改token并用私钥签名

易受攻击代码示例
在这里插入图片描述

其他

exp标头

除了上面的问题,如果头部中没有exp标头声明JWT的过期时间,那也是存在风险的,一旦获得该令牌,那么就可以重复使用。

跨服务中继攻击

三个组件,下面两个可以会向用户发送JWT令牌,然后令牌服务在签发令牌时不进行必要的验证,那么可能两个应用在具有相同的用户名时,签发相同的令牌,那么就可以替代其他用户登录到另外一个应用中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XIhLYyzc-1676723092959)(https://note.youdao.com/yws/res/25671/WEBRESOURCE2506b4ff96fa8638ce1e8d9c3c03745b)]

实验部分

https://portswigger.net/web-security/all-labs

未验证签名

成功登录后,可以看到获得的Cookie内容就是JWT格式的,

在这里插入图片描述

eyJraWQiOiJhZThiOTNhMC01ZWJjLTQzZWYtOWY3My04ODVmMzY1NzdjZWEiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsInN1YiI6IndpZW5lciIsImV4cCI6MTY3NjU1NjMxOX0.LM-PYrwNfxoSYvh13Fx4iWP46dYNPhNrq_X1PbVH4JBdtAwolKEIu5ICe_XLUI668CKgwTrlcLzQq8g7gsVvyAttwJKpdfICI-Mncn1CRx6vkxBPxrYhOniRR9G3b_dSwWuuyrpHPV2Zncl8_6wrRO1lB5Yd0zO4TZhATv5hq60iO8F75kRSyD8WnllvNOJVUtTPatmdkq-G8R-bJ0PPlhsXzCXRuWKOlkKl5nyE_aF-tiCAryK6cN_u5pQlc4fYtPds6fnxrPtp7fKPFHCoUSUG7HaA48WqGF603uiKdtLbtia0eEwtSjfT_Wk15Blau4wcGwzCnHeF4Tp2SxWSpA

因为该问题是程序不会对签名部分进行任何验证,因此直接修改payload部分,然后任意输入私钥生成JWT即可

再次构造payload

在这里插入图片描述

访问成功,之后可以发现删除用的URL,成功删除用户。

无算法漏洞

  1. 登录后获得Cookie中的JWT
  2. 然后将头部中的alg更改 none,payload中的用户名替换为administrator,base64编码后替换原来的部分,然后删除签名部分,记得保留点号,保证格式正确,然后就按照第一个实验中的步骤删除用户即可。

使用弱密钥加密

  1. 成功登录获得到JWT后进行解码查看,可以看到JWT使用的HS256,这个是对称加密算法,存在使用所密钥的该路,可以使用jwt_tool,等工具尝试对密钥进行猜解。在这里插入图片描述
  2. 破解的密钥结果为secret1,那我们就可以对JWT进行篡改了。
  3. 使用jwt.io网站生成JWT,然后按照上面两个实验的步骤删除用户即可。

在这里插入图片描述

JWK标头注入

安装bp扩展 JWT Editor,然后使用JWT Editor Keys生成RSA密钥对,点击确认

在这里插入图片描述

在JSON Web Token选项卡 的底部,单击Attack,然后选择Embedded JWK。出现提示时,选择您新生成的 RSA 密钥并单击确定。在这里插入图片描述

jku标头注入

  1. 使用扩展生成RSA密钥并保存,然后选择Copy Public Key as JWK,并按照JWKS文件的格式保存到攻击者的服务器。
  2. 添加jku头,值为对应jwks文件对应的url
  3. 将生成的kid替换原来的kid,用来标识用户的用户名,然后选择对应的密钥进行签名,之后不走与上面的实验一致。在这里插入图片描述

利用kid标头绕过

上面的知识部分有讲过kid是用来帮助寻找密钥的,有一种情况就是保存在指定路径的某个文件中,文件名是kid的值。

攻击这个靶场时,我用windows上面的burp怎么样都没办法进行签名,怀疑时burp版本问题,换了个版本也不行,打开虚拟用kali里面的burpSuit,就成功了。

  1. 首先修改kid的值,为…/…/…/…/…/…/dev/null,然后将sub修改为administrator。

2.生成密钥,然后保存,记得将k的值修改为AA==,其实也就是空,

在这里插入图片描述

混淆算法

这个漏洞应该是在程序中没有指明算法导致的问题。

1.首先访问jwks.json文件,将keys的值,也就是框起来的部分,粘贴出来
在这里插入图片描述

2.然后使用JWT Editor的插件,生成RSA密钥,选择生成JWT的,生成之后,将上面的值替换掉里面的内容,然后点击确定,保存
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ADaGHWJG-1676723092962)(https://note.youdao.com/yws/res/5/WEBRESOURCE05646bbbd8300f603fd7ab75987f5b55)]

3.然后对保存的密钥右键,copy as public pem,去进行base64的加密。然后选择生对称加密的密钥,将加密后的值替换到k中,然后保存

在这里插入图片描述

4.然后,将加密算法更改为HS256,用户名标识改为administrator,然后就有管理员权限了,之后的步骤就是删除用户,没什么好写的。

在这里插入图片描述

参考

https://www.freebuf.com/articles/web/303200.html
https://www.jianshu.com/p/576dbf44b2ae
https://zhuanlan.zhihu.com/p/86937325
https://medium.facilelogin.com/jwt-jws-and-jwe-for-not-so-dummies-b63310d201a3
https://systemweakness.com/hacking-jwt-d29f39e202d5
https://lazyhacker.medium.com/jwt-vulnerabilities-list-simple-explanation-134c4dcc5e61


本文转载自: https://blog.csdn.net/qingzhantianxia/article/details/129104228
版权归原作者 烟雨醉沉浮 所有, 如有侵权,请联系我们删除。

“JWT安全漏洞以及常见攻击方式”的评论:

还没有评论