【Try to Hack】JWT安全

📒博客主页:开心星人的博客主页
🔥系列专栏:Try to Hack
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📆首发时间:🌴2022年6月28日🌴
🍭作者水平很有限,如果发现错误,还望告知,感谢!

内容来自一下文章
https://blog.csdn.net/qq_41286145/article/details/120726638
https://www.freebuf.com/articles/web/290668.html
JWT攻击靶场
https://www.freebuf.com/articles/web/337347.html

https://paper.seebug.org/3057/

📌导航小助手📌

JWT简介及作用

JWT(JSON Web Token)是一种用于在网络应用环境中进行安全信息传递的开放标准。用于在各方之间作为JSON对象安全地传输信息。此信息是可以验证和信任的,因为它是经过数字签名的。

它由三部分组成:
头部(Header),通常包含令牌的类型和使用的加密算法;
载荷(Payload),包含声明,比如用户身份信息、权限等;
签名(Signature),用于验证消息的完整性和真实性,防止被篡改。

JWT 的主要优点是无状态,服务器不需要保存会话信息,减轻了服务器的存储负担。它常用于身份验证和授权,比如在单点登录、微服务架构等场景中。用户在登录成功后获取 JWT 令牌,后续的请求携带该令牌,服务器通过验证令牌的有效性来确认用户身份和权限。

【Try to Hack】Cookie和Session
传统的session认证:
1、session的创建:session是在客户端与服务器交互的过程中,由服务器创建的,并且会返回一个session的Id给客户端,一个会话只能有一个session对象;
2、在此后的交互过程中,客户端在请求中带上这个ID;
3、服务器可根据此Session ID获取到对应的保存在服务器内存中的session内容,以便于识别用户并提取用户信息。

传统session认证缺点:
1、所有的session都在服务端进行保存,当用户量不断增大的时候服务器的开销也会随之增大。
2、在一个应用的服务器有多台的情况下,针对一个用户,就必须在每台服务器上都维护一个相同的session,或者引入Redis等中间件对session进行统一的管理。

JWT认证步骤:
1、客户端向服务端发送账号密码进行认证。
2、服务端在校验账号密码正确之后,生成token字符串返回给客户端。
3、客户端收到token之后进行保存,并在之后的每一次请求中将该token放到请求头中一并发送。
4、服务端在收到客户端传递的token之后,对token进行验证,判断是否合法。
5、使用token进行认证的话,服务端不需要保存任何会话信息或者用户信息,所有的信息都分散保存在客户端中,客户端每次请求的时候自己带上token即可

JWT构成

JWT是由三部分构成的,第一部分是头部(header),第二部分是载荷(payload),第三部分为签名(signature)。它们之间由.分隔,经过了Base64加密

header.payload.signature

在这里插入图片描述

header一般由类型和加密方法组成,例如

{
  'typ': 'JWT',
  'alg': 'HS256'  //HMAC SHA256 or RSA.
}

然后将头部进行base64加密后去掉=号,构成第一部分
ewogICd0eXAnOiAnSldUJywKICAnYWxnJzogJ0hTMjU2Jwp9

payload和header结构类似,但存放的是数据。存具体的业务数据比如用户 id 等等。

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

iss: 该JWT的签发者
sub: 该JWT所面向的用户
aud: 接收该JWT的一方
exp(expires): 什么时候过期,这里是一个Unix时间戳
iat(issued at): 在什么时候签发的

signature,用于验证消息在发送过程中是否被更改,还可以验证JWT的发送者是否是它所说的那个人。通常是对header和payload进行hash,your-256-bit-secret是salt

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  your-256-bit-secret)

在这里插入图片描述
Base64 有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。这就是 Base64URL 算法

JWT安全

验证是否使用JWT

[= ]ey[A-Za-z0-9_-]*\.[A-Za-z0-9._-]*-稳定的JWT版本
[= ]ey[A-Za-z0-9_\/+-]*\.[A-Za-z0-9._\/+-]*-所有JWT版本(可能误报)

由于Header和Payload部分是使用可逆base64方法编码的,因此任何能够看到Token的人都可以读取数据。
因此Token不能随意公布,发送的数据不得包含任何敏感数据(例如密码)

签名为none
在JWT的Header中alg的值用于告诉服务器使用哪种算法对令牌进行签名,从而告诉服务器在验证签名时需要使用哪种算法,目前可以选择HS256,即HMAC和SHA256,JWT同时也支持将算法设定为"None",如果"alg"字段设为"None",则标识不签名,这样一来任何token都是有效的,设定该功能的最初目的是为了方便调试,但是若不在生产环境中关闭该功能,攻击者可以通过将alg字段设置为"None"来伪造他们想要的任何token,接着便可以使用伪造的token冒充任意用户登陆网站

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

防御措施:JWT配置应该指定所需的签名算法,不要指定”none”。(也就是必须是用此种算法得来的token才会被接受s)

暴力破解密钥
https://github.com/wallarm/jwt-secrets/blob/master/jwt.secrets.list

hashcat -a 0 -m 16500 <jwt> <wordlist>

Hashcat会使用单词列表中的每个密钥对来自JWT的报头和有效载荷进行签名,然后将结果签名与来自服务器的原始签名进行比较,如果有任何签名匹配,hashcat将按照以下格式输出识别出的秘密以及其他各种详细信息

无效签名攻击
无效签名是指当用户端提交请求给应用程序,服务端可能没有对token签名进行校验,这样,攻击者便可以通过提供无效签名简单地绕过安全机制。导致攻击者只需要更换user参数就可以实现越权访问,可能是横向越权也可能是纵向越权

算法混淆攻击
算法混淆攻击(也称为密钥混淆攻击)是指攻击者能够迫使服务器使用不同于网站开发人员预期的算法来验证JSON web令牌(JWT)的签名,这种情况如果处理不当,攻击者可能会伪造包含任意值的有效jwt而无需知道服务器的秘密签名密钥。

算法混乱漏洞通常是由于JWT库的实现存在缺陷而导致的,尽管实际的验证过程因所使用的算法而异,但许多库都提供了一种与算法无关的方法来验证签名,这些方法依赖于令牌头中的alg参数来确定它们应该执行的验证类型

function verify(token, secretOrPublicKey){
    algorithm = token.getAlgHeader();
    if(algorithm == "RS256"){
        // Use the provided key as an RSA public key
    } else if (algorithm == "HS256"){
        // Use the provided key as an HMAC secret key
    }
}

如果服务器接收到使用对称算法(例如:HS256)签名的令牌,库通用verify()方法会将公钥视为HMAC密钥,这意味着攻击者可以使用HS256和公钥对令牌进行签名,而服务器将使用相同的公钥来验证签名(备注:用于签署令牌的公钥必须与存储在服务器上的公钥完全相同,这包括使用相同的格式(如X.509 PEM)并保留任何非打印字符,例如:换行符,在实践中您可能需要尝试不同的格式才能使这种攻击奏效)

防御措施:JWT配置应该只允许使用HMAC算法或公钥算法,决不能同时使用这两种算法。

修改KID
kid(key ID)是JWT的header部分的可选参数,作用是用来指定加密算法秘钥。
开发人员可以用它标识认证token的某一密钥

{
"alg": "HS256",
"typ": "JWT",
"kid": "1"         //使用密钥1验证token
//“kid”:/home/jwt/1.pem”  //这个kid参数还可以是文件路径
}

由于kid参数是用户可控的,那么攻击者就可以用来构造攻击,比如服务器更新了密钥,但是旧的密钥并未删除且该密钥已经被攻击者所知,或者通过ftp等渠道上传了密钥,那么就会导致攻击者能够直接控制签名验证从而绕过签名

“kid”:1 ' UNION SELECT 'key';--//使用字符串"key"验证token  。KID也可以用于在数据库中检索密钥
“kid”: "key_file" | whoami;            //有时候服务器会直接通过函数对KID文件进行调用
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心星人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值