JWT的认证bypass

admin 2024年2月9日00:44:44评论10 views字数 4500阅读15分0秒阅读模式

扫码领资料

获网安教程

JWT的认证bypass

JWT的认证bypass

通过PortSwigger上的JWT关卡来浅析学习下JWT token认证的绕过。

BurpSuite中有一个JWT Editor Keys插件可以用来识别使用JWT认证的包,安装好就行。
在history处会被直接标记出来.
JWT的认证bypass
这里提一下Inspector的编辑功能,对于能解码的字段,可以在那里编辑后,直接应用更改。
JWT的认证bypass
不过安装了这个插件后,存在JWT的可以直接利用JSOn Web Token来修改了。
JWT的认证bypass

JWT的结构

JWT由三个部分组成:header.payload.signature,同颜色对应部分,蓝色的这里是为RSA256的签名。

JWT的认证bypassheader部分

alg和typ两个字段最常用,alg指定加密算法(HS256或者RS256)kid字段用于标记公钥的id,jwk里面包含附带的RAS密钥信息,jku是远程获取公钥信息地址,cty(内容类型)如果已经找到了绕过签名验证的方法,可以尝试注入cty参数,将内容类型改为text/xml或application/x-java-serialized-object,这有可能为XXE和反序列化攻击提供新的向量。

{
"kid": "549751c3-0954-4589-acbc-dbb46cd506ac",
"typ": "JWT",
"alg": "RS256",
"jwk": {
"kty": "RSA",
"e": "AQAB",
"kid": "549751c3-0954-4589-acbc-dbb46cd506ac",
"n": "wjTvn0odoodK5RygAz1U7q1WU8ZUOogKplYxMz7QU_P0vJGwQg1Mk1JHWvLq4I5Pu05szqsizP_PpeH02OPxPQkBYZQkkjacT0VQiOrX1_NAKYx3heQ86BglHA9NMyKrMQWvQ0cVocYO49sifdop1b0boqS9wdCL-9CI9xPm6d3PBAgy75vrPFpEMxHq6W9vTJRPNbrO4NBBWFrYER6bLf1op-NuTzuxJwaUNMmcUvipUP4mPVufmbGB5a3xxkbllJvWtD82TXTdp-52JdbbxH7L35m3qrqOqUCTDPoCxnvAKpB7AWr5FtVc87ga6Lp5aZ8-XWHigYFME4ejlCFTYQ"
}
}

RS256:采用SHA-256的RSA签名
HS256 :带有SHA-256的HMAC
HMAC 指的是 Hash-based Message Authentication 哈希运算消息认证码。
HS256(带有SHA-256 的 HMAC 是一种对称算法,双方之间仅共享一个密钥。由于使用相同的密钥生成签名和验证签名,因此获取到密钥即能伪造)

payload部分

用户数据以及一些元数据有关的声明
sub字段指的是当前token所认证的用户,exp为时间戳 过期时间
iss当前JWT的签发者,nbf该时间之前不接收处理该Token
domain 面向的用户,jti Token唯一标识符

JWT的sub绕过

对于不验证签名的,直接修改sub后面的用户为administrator然后编码发送,就可以获得administrator权限。

{

    "sub" : "administrator",    //当前登录用户

    "iss": "admin",          //该JWT的签发者

    "iat": 1573440582,        //签发时间

    "exp": 1573940267,        //过期时间

    "nbf": 1573440582,         //该时间之前不接收处理该Token

    "domain": "example.com",   //面向的用户

    "jti": "dff4214121e83057655e10bd9751d657"   //Token唯一标识

}

JWT的alg绕过

设置签名验证参数为none,然后把最后面的签名给删掉,记得不要把.也删除了。
成功绕过。
JWT的认证bypass

signature

保护Token的完整性,生成方法是把header和payload的两个部分连接起来,根据header部分指定的算法,计算出签名。

JWT弱密钥爆破 伪造签名

若是JWT使用的私钥是弱密钥,可以尝试用hashcat来爆破,字典可以用这个上面的。
hashcat -a 0 -m 16500 JWT_Token ./jwt.secrets.list
JWT的认证bypass爆破出来密钥是secret1
JWT的认证bypass在burp里面添加上这个密钥,选择 New symmetric Key(新的对称密钥),位数不用管,直接把k替换成secret1的base64,然后保存就好。JWT的认证bypass然后再Request处打开JSON Web Token,修改sub用户为administrato后sign签名,就伪造好管理员的JWTtoken了。
JWT的认证bypass当然也可在jwt.io上签名,签名出来是一样的。
JWT的认证bypass成功过关。
JWT的认证bypass

JWT herader注入

通过 jwk 标头注入绕过 JWT 身份验证

服务器应该是只使用公钥白名单来验证JWT签名的,但对于一些相关配置错误的服务器会用JWK参数中嵌入的任何密钥进行验证,攻击者就可以利用这一行为,用自己的RSA私钥对修改过的JWT进行签名,然后在JWK头部中嵌入对应的公钥进行bypass。

生成一个RAS key

然后在Request处 attack选择Embedded JWK ,这样嵌入公钥。
JWT的认证bypass可以看到生成的JWT Token嵌入了我们的公钥。

JWT的认证bypass然后就可以越权绕过了。
JWT的认证bypass

利用JKU获取公钥

有的服务器不会直接在JWK的header里面写入公钥,选择使用JKU(JWK Set URL)来远程应用一个包含公钥的页面,那么就可以自己构造JKU参数来实现。
首先还是生成RAS公钥,右键选择复制JWK公钥。
JWT的认证bypass复制出来是这样的。

{
"kty": "RSA",
"e": "AQAB",
"kid": "549751c3-0954-4589-acbc-dbb46cd506ac",
"n": "wjTvn0odoodK5RygAz1U7q1WU8ZUOogKplYxMz7QU_P0vJGwQg1Mk1JHWvLq4I5Pu05szqsizP_PpeH02OPxPQkBYZQkkjacT0VQiOrX1_NAKYx3heQ86BglHA9NMyKrMQWvQ0cVocYO49sifdop1b0boqS9wdCL-9CI9xPm6d3PBAgy75vrPFpEMxHq6W9vTJRPNbrO4NBBWFrYER6bLf1op-NuTzuxJwaUNMmcUvipUP4mPVufmbGB5a3xxkbllJvWtD82TXTdp-52JdbbxH7L35m3qrqOqUCTDPoCxnvAKpB7AWr5FtVc87ga6Lp5aZ8-XWHigYFME4ejlCFTYQ"
}

需要加上keys头,格式要求。

{
"keys": [
{
"kty": "RSA",
"e": "AQAB",
"kid": "549751c3-0954-4589-acbc-dbb46cd506ac",
"n": "wjTvn0odoodK5RygAz1U7q1WU8ZUOogKplYxMz7QU_P0vJGwQg1Mk1JHWvLq4I5Pu05szqsizP_PpeH02OPxPQkBYZQkkjacT0VQiOrX1_NAKYx3heQ86BglHA9NMyKrMQWvQ0cVocYO49sifdop1b0boqS9wdCL-9CI9xPm6d3PBAgy75vrPFpEMxHq6W9vTJRPNbrO4NBBWFrYER6bLf1op-NuTzuxJwaUNMmcUvipUP4mPVufmbGB5a3xxkbllJvWtD82TXTdp-52JdbbxH7L35m3qrqOqUCTDPoCxnvAKpB7AWr5FtVc87ga6Lp5aZ8-XWHigYFME4ejlCFTYQ"
}
]
}

把此处的公钥映射到服务器上,labs的环境是直接给了映射页面的。
JWT的认证bypass

然后需要修改JWK中的kid为公钥的kid,修改jku为映射公钥地址,修改sub为管理员。
JWT的认证bypass然后使用此公钥就行sign签名,就可以成功修改公钥绕过验证了。
JWT的认证bypass

JWT header路径遍历

补充两个知识点
1./dev/null 文件,这是linux的空设备文件 详情解释它是0字节大小,对于写入的内容统统丢弃掉。
2.base64编码的空字节为AA==生成对称密钥,修改k为空字节。JWT的认证bypass修改sub为管理员,kid修改成目录遍历到null文件,再利用生成的otc密钥进行sign。
JWT的认证bypass

JWT的认证bypass

通过算法混淆bypass

使用RSA密钥来签名和验证token。但是由于实现上的缺陷,这种机制可能会遭受到算法混淆攻击。

1.首先要获取服务器公钥。Labs是通过公开的页面的 /jwks.json。
JWT的认证bypass2.取出keys包含的RAS公钥内容,新建RAS密钥。
JWT的认证bypass

3.使用复制的PEM格式公钥base64,作为k生成对称密钥。
JWT的认证bypass

4.修改alg加密方式为HS256,sub为管理员,使用刚才生成的对称密钥来进行签名。
JWT的认证bypass然后就可以用此Token绕过。
JWT的认证bypass

kid参数注入

kid参数用于指定加密算法的密钥ID,由用户可控,或许会存在一些安全问题。
此处就先记录下。

{
"kid": "../../../../../etc/passwd",
"alg": "HS256"
"typ": "jwt"
}
{
"kid": "fa30a68d-05a7-4e72-b033-e092f83b9132 '|| union select user() -- ",
"alg": "HS256"
"typ": "jwt"
}
{
"kid": "fa30a68d-05a7-4e72-b033-e092f83b9132 | whoami",
"alg": "HS256"
"typ": "jwt"
}

对kid参数过滤不严也可能会出现命令注入问题,但是利用条件比较苛刻。如果服务器后端使用的是Ruby,在读取密钥文件时使用了open函数,通过构造参数就可能造成命令注入.
这些情况暂时还没发现。

小结

JWT用作身份验证,攻击多种多样,其目的是越权访问,或许某些情况下能造成SQL注入、RCE。
主要的漏洞为:签名未校验、弱密钥、算法缺陷被篡改、伪造密钥、密钥篡改这些。

- 使用最新的 JWT 库,虽然最新版本的稳定性有待商榷,但是安全性都是较高的
- 对 jku 标头进行严格的白名单设置
- 确保 kid 标头不容易受到通过 header 参数进行目录遍历或 SQL 注入的攻击
- 始终为颁发的任何令牌设置到期时间戳
- 尽可能避免通过URL参数发送令牌
- 提供aud声明(或类似内容),以指定令牌的预期接收者,防止其应用在不同网站
- 让颁发服务器能够撤销令牌
文章来源:https://www.freebuf.com/articles/web/356652.html文章作者:Erichas如有侵权,联系删除

声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权

@

原文始发于微信公众号(白帽子左一):JWT的认证bypass

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月9日00:44:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   JWT的认证bypasshttp://cn-sec.com/archives/2471299.html

发表评论

匿名网友 填写信息