扫码领资料
获网安教程
通过PortSwigger上的JWT关卡来浅析学习下JWT token认证的绕过。
BurpSuite中有一个JWT Editor Keys插件可以用来识别使用JWT认证的包,安装好就行。
在history处会被直接标记出来.
这里提一下Inspector的编辑功能,对于能解码的字段,可以在那里编辑后,直接应用更改。
不过安装了这个插件后,存在JWT的可以直接利用JSOn Web Token来修改了。
JWT的结构
JWT由三个部分组成:header.payload.signature,同颜色对应部分,蓝色的这里是为RSA256的签名。
header部分
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,然后把最后面的签名给删掉,记得不要把.
也删除了。
成功绕过。
signature
保护Token的完整性,生成方法是把header和payload的两个部分连接起来,根据header部分指定的算法,计算出签名。
JWT弱密钥爆破 伪造签名
若是JWT使用的私钥是弱密钥,可以尝试用hashcat来爆破,字典可以用这个上面的。hashcat -a 0 -m 16500 JWT_Token ./jwt.secrets.list
爆破出来密钥是
secret1
。在burp里面添加上这个密钥,选择 New symmetric Key(新的对称密钥),位数不用管,直接把k替换成secret1的base64,然后保存就好。
然后再Request处打开JSON Web Token,修改sub用户为administrato后sign签名,就伪造好管理员的JWTtoken了。
当然也可在jwt.io上签名,签名出来是一样的。
成功过关。
JWT herader注入
通过 jwk 标头注入绕过 JWT 身份验证
服务器应该是只使用公钥白名单来验证JWT签名的,但对于一些相关配置错误的服务器会用JWK参数中嵌入的任何密钥进行验证,攻击者就可以利用这一行为,用自己的RSA私钥对修改过的JWT进行签名,然后在JWK头部中嵌入对应的公钥进行bypass。
生成一个RAS key
然后在Request处 attack选择Embedded JWK ,这样嵌入公钥。可以看到生成的JWT Token嵌入了我们的公钥。
然后就可以越权绕过了。
利用JKU获取公钥
有的服务器不会直接在JWK的header里面写入公钥,选择使用JKU(JWK Set URL)来远程应用一个包含公钥的页面,那么就可以自己构造JKU参数来实现。
首先还是生成RAS公钥,右键选择复制JWK公钥。
复制出来是这样的。
{
"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的环境是直接给了映射页面的。
然后需要修改JWK中的kid为公钥的kid,修改jku为映射公钥地址,修改sub为管理员。然后使用此公钥就行sign签名,就可以成功修改公钥绕过验证了。
JWT header路径遍历
补充两个知识点
1./dev/null
文件,这是linux的空设备文件 详情解释它是0字节大小,对于写入的内容统统丢弃掉。
2.base64编码的空字节为AA==
生成对称密钥,修改k为空字节。
修改sub为管理员,kid修改成目录遍历到null文件,再利用生成的otc密钥进行sign。
![JWT的认证bypass JWT的认证bypass]()
通过算法混淆bypass
使用RSA密钥来签名和验证token。但是由于实现上的缺陷,这种机制可能会遭受到算法混淆攻击。
1.首先要获取服务器公钥。Labs是通过公开的页面的 /jwks.json。2.取出keys包含的RAS公钥内容,新建RAS密钥。
3.使用复制的PEM格式公钥base64,作为k生成对称密钥。
4.修改alg加密方式为HS256,sub为管理员,使用刚才生成的对称密钥来进行签名。然后就可以用此Token绕过。
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
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论