官方公众号企业安全新浪微博
FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。
FreeBuf+小程序
jwt全称json web token,顾名思义json格式的web令牌。我用几个关键词知识点将其概括:
- json格式
- 用户信息加密到token里
- 服务器不保存任何用户信息
- 服务器只保存密钥信息
- 通过使用特定加密算法验证token
- 通过token验证用户身份信息
- 基于token的身份验证可以代替cookie,session身份验证方法
- 由三部分组成
header.payload.signature
header:
header部分有两个常见的字段:
alg:alg用来声明使用的是哪种加密算法:一般来说,rsa和hmac算法最为常见。在这个字段里rsa会写作rs256,而hmac通常写作hs256。
typ:声明类型为jwt。
header一般来说长这个样子:
{
"alg" : "rs256"
"typ" : "jwt"
}
payload:
payload中的数据一般是为用户数据和声明一些权限的数据。
如下:
{
"user_role" : "jack" //当前登录用户
"iss" : "administrator" //该token的签发人
"iat" : 1573440582, //该token的签发时间
"exp" : 1573940267, //过期时间
"nbf" : 1573440582, //该时间前不接受处理该token
"domain" : "baidu.com" //面向的用户为baidu
"jti" : "dff4214121e83057655e10bd9751d657" //Token唯一标识
}
signature:
signature翻译过来的意思为签名,它的功能是保护token的完整性。
生成方法:
签名=用alg中指定的加密算法将header和payload加密
signature = HMAC-SHA256(base64urlEncode(header) + '.' + base64urlEncode(payload), secret_key)
一个完整的jwt为:
header.payload.signature
其中header和payload是由base64url加密,而signature是由alg中的指定算法加密。
攻击方式:
- 通过修改加密算法进行攻击
- 将alg字段设置为none以及将signature置为空
- 将rsa加密算法修改为hmac加密算法
- 爆破密钥
- 修改参数
- 修改kid
- 任意文件读取
- sql注入
- 命令注入
- 修改jku或x5u
- 修改kid
- 信息泄露
攻击手法大概就是这些:
1-1.将alg字段设置为none以及将signature置为空:这种方法一开始是用于调试,不过也有可能开发人员疏忽造成这种漏洞,这种疏忽就是开发人员在生产环境中开启了空加密算法,也就是缺少加密算法,不对加密算法进行校验,jwt失去了它保证信息不被篡改的功能。从而达到了攻击者伪造身份的目的。
1-2.将rsa加密算法修改为hmac加密算法:hmac为对称加密算法,公钥私钥用同一个。而rsa为非对称加密算法,公钥和私钥不为同一个(私钥加密明文,公钥解密密文)。在这两种算法中,都是使用私钥进行加密,只有拿到了加密时使用的私钥,才可能伪造token。
所以相比于rsa的私钥来说,hmac的的私钥通过信息收集更容易得到。
如果一个token是由rsa加密的,但是你通过抓包,然后修改其中的alg参数为hmac,并将信息收集来的hmac的私钥对token进行签名,然后发送到服务器端,服务器端可能会把该token认为成是通过rsa私钥加密来的,从而使用rsa的公钥对其解密。从而达到了伪造身份的目的。
2.爆破密钥:有几个条件:知道加密算法是哪种,一个已经签名过的jwt,密钥不能太复杂。所以条件比较苛刻。
3-1.修改kid:kid是header中的一个可选参数,全称key id,用于指定加密算法的密钥,因为这个参数可以由用户输入,所以会有安全问题。
3-1-1.任意文件读取:因为kid是一个可以读取路径的参数,所以如果后端为对该参数进行过滤,可能导致该漏洞。
3-1-2.sql注入:kid可以从数据库中读取数据,通过构造sql注入的payload也可能导致该漏洞。
3-1-3.命令注入:如果后端使用的是ruby,在读取密钥的时候使用了open函数,则可能存在该漏洞。
3-2.修改jku或x5u:这两个的用法跟kid类似。
4.信息泄露:payload部分是base64url编码,相当于明文,可能会泄露敏感信息。