测试和破坏 JWT 认证的几种实用方法 - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

测试和破坏 JWT 认证的几种实用方法

atp7bkil 资讯 2020-01-03 09:15:00
1055089
收藏

导语:WT (JSON Web Token)是一种流行的身份验证 / 授权协议。 它将加密签名集成到 JSON 对象中,以验证对象的完整性。 测试 JWT 安全性的方法比较系统的也相当简单。 目前,在 JWT 身份验证的安全性方面,已经有人做过几项研究。

引言

JWT (JSON Web Token)是一种流行的身份验证 / 授权协议。它将加密签名集成到 JSON 对象中,以验证对象的完整性。

测试 JWT 安全性的方法比较系统的也相当简单。目前,在 JWT 身份验证的安全性方面,已经有人做过几项研究。

涉及到的一些工具也是先前有人开发好的。然而,在评估了已公开的工具的质量之后,我得出一个结论,我们需要更好的工具来对 JWT 执行测试。我开发了一个脚本集合,我称之为“ jwt-pwn” ,目的是以稳定、简单和高效的方式测试 JWT 身份验证。脚本集非常简单,因为它可以直接与 JWT Python 库集成。

本文将介绍 JWT 的背景、错误的实现以及测试和破坏 JWT 的实用方法。它还将包含一部分建设性的批评,我将在其中讨论每个已知的测试 JWT 的公开工具,以及我在开发 jwt-pwn 时遇到的问题。

背景

下图解释了生成 JWT 的基本方法

 image.png

来源: https://jwt.io

JWT 由三部分组成:

· Header: 这个是作为如何操作的指南。头部包含用于生成签名的 JWT 算法

· Payload: 保存 JSON 对象,以及保留的声明(如果有的话)

· Signature: Header 和Payload 的 Base64编码表示形式。这个键可以选择性地添加到签名中。

测试实现

1. 暴力破解密钥

JSON web 令牌通常使用秘密密钥进行签名。密钥就是简单的密码或数字密钥。如果我们能够找到秘钥,那么我们就能够生成具有任何指定值的有效标记。

这个测试是针对使用密码生成的任何令牌进行的; 这种攻击不适用于基于密钥的签名生成的令牌。

有趣的是,这是一种离线密码攻击技术,因此不会对目标的后端产生干扰。在身份验证或类似情况下,我们只需要后端提供的有效 JWT。

2. 使用算法签名一个新的令牌

这个测试很简单。我们将在不验证签名的情况下对 JWT 的值进行解码。并且我们将使用“none”算法生成一个新的令牌。

在此之后,我们将用新生成的令牌替换身份验证中的原始 JWT。如果这个 JWT 被接受,并且给出了原始令牌的相同响应,那么身份验证功能就可以任意接受“none”算法,在这个算法中,我们在后端显式地“请求” JWT 验证器不验证该令牌。

如果之后一切正常,那么也可以执行重放攻击。我指的是“重放攻击”术语,即向身份验证控制器重放有效令牌,而不关注获取令牌的源。在我们这里的示例中,我们将签名一个对另一个用户(或管理员)有效的新令牌。

3. 更改令牌的签名算法(用于模糊测试目的)

假设后端返回一个用 RSA256签名的 JSON Web 令牌。验证测试的目的是检查 JWT 验证器在这种情况下是否强制执行 RSA256。

我们将对原始 JWT 的值进行解码,然后使用我们的密钥生成一个新的签名令牌,例如使用 HS256。

在典型情况下,此测试可能不会完全破坏 JWT 身份验证系统。但是,对其进行测试并检查其响应是否具有模糊性,这可能是一种良好的实践。

4. 将非对称符号令牌签名为匹配的对称算法(当你拥有原始公钥时)

当一个令牌是非对称算法签名的(例如 RSA256) ,并且你获得了用于验证该签名的公钥时,可以应用的攻击技术是使用对称签名算法(例如 HS256)生成具有相同有效载荷的新令牌,同时使用公钥作为密码。

如果可行,那么这意味着验证器不会将 JWT 的签名算法列为白名单,我们可以生成任意的令牌,这些令牌将被 JWT 验证器接受。

公开的工具

有几个工具旨在评估 JWT 身份验证。用于进行 JWT 评估的测试工具面临不同的工程问题。

jwt_tool - (https://github.com/ticarpi/jwt_tool)

jwt_tool 可以对 JWT 做各种测试。但是,解析和生成 JWT 的自定义实现会导致错误和误报。 jwt_tool 使用自定义的 Base64解码和编码方法,而不是使用默认的 JWT 库。虽然 JWT 协议是公开的并且有文档记录,但是 Base64在不同的实现中是不同的。例如,多个 Base64编码的字符串可以表示相同的值。

注意: jwt_tool 发布了一个新的更新(截至201910) ,应该可以修复遇到的大多数问题

c-jwt-cracker - (https://github.com/brendan-rius/c-jwt-cracker)

C-jwt-cracker 是暴力破解 JWT 的私钥的工具。此外,它使用了 JWT 的实现,c-jwt-cracker 使用的 Base64库被证明是错误的,并且提供了无效的结果。

引用自 c-jwt-cracker Github 页面的部分内容:

“该工具使用的 Base64实现(来自苹果公司)有时会有些问题,因为不是每个 Base64实现都是相同的。所以有时候,你的 Base64令牌的解密只能部分可行,因此你可能会找到一个不正确的令牌的密钥。

· 来源: https://github.com/brendan-rius/c-jwt-cracker

jwt-cracker - https://github.com/lmammino/jwt-cracker

该工具仅限于单一的签名算法(HS256) ,如果提供了不同的签名算法,则无法进行操作。

附加问题

此外,实验中所讨论的所有工具都采用线性方法破解密码。

介绍 jwt-pwn

这些脚本采用各种测试和方法来破坏 JSON web 令牌,并系统地应用令牌。所有的脚本都使用了 Python 的主要 JWT 库“pyjwt”完成。 Pyjwt 在现实应用程序中得到了广泛的应用。这个库运行很稳定,并且经过测试和维护。

我发现使用现成的 Pyjwt 库而不是像许多人那样编写新的定制库对于稳定性来说要好得多。由于正确解析 JWT 令牌的失败,有一些已知的工具会给出错误的结果。 Pyjwt 生成的结果与后端解析器生成的结果在大多数情况下是相同。

第一个脚本: jwt-cracker.py

这个脚本通过加载字典文件对 JSON web 令牌进行暴力攻击。

我有两个针对暴力破解算法的方法。

第一种方法

1-加载字典文件中的所有密码

2-一旦有线程可用(有一个线程锁控制这个部分) ,就派生一个新线程。

经过分析,我发现这个并没有想象中的那么好用。原因是: 除了实际的暴力破解外,还存在的问题是:

1- 应该有一个线程不断地从队列中卸载

2- 需要有线程可用性检查器

3- Locker 的线程从被派生,直到有一个可用的线程才会执行

4- 线性的卸载队列

在这一部分涉及到许多因素,这些因素使得算法不是最有效的

第二种方法

我认为这个方法才是正确的方法。

1-将整个字典密码单词列表拆分成更小的队列

2-创建新线程,然后将每个队列提供给一个唯一的线程。

3-该线程被视为“worker” ,所有函数都与一个全局检查器同步,该检查器检查其他 worker 是否找到了密钥。

4-当找不到密钥时,所有线程测试指定队列中的值。

5-如果找到了密钥,则所有线程将被连接,并且应用程序将终止。

6-当测试了每个子队列中的所有值后,应用程序将终止。

问题

在 Python 中实现了这个设计之后,Python 中的 GIL (GIL)导致应用程序的执行速度比期望的要慢。

第二个脚本: jwt-cracker-go

该脚本是 jwt-cracker 的 Golang 的线性实现。与其他工具相比,它真的很快,尽管它使用的是线性方法,而且可靠,因为它使用的是 JWT 的官方 Golang 库来验证密码破解。这个库应该与开发人员在实际环境中使用的库相同。

我还写了另一个变种,使用了 goroutine,应该运行速度更快一些。多线程变体的代码可以在项目存储库中找到。

第三个脚本: jwt-decoder.py

这是一个解码 JSON web 令牌值的简单脚本。对于测试 JWT,这个脚本用起来很方便。

第四个脚本: jwt-mimicker.py

这个脚本从 JSON web 令牌创建一个无符号标记。此脚本应用前面讨论过的“空”算法攻击。

第五个脚本: jwt-key_based_token-to-hs256.py

这个脚本从基于密钥的 JWT 创建一个签名的 JWT。这适用于前面提到的攻击场景。

由于使用了强大的 pyjwt 库,该脚本适用于每个基于密钥的签名算法。

接下来怎么做?

渗透测试人员和安全研究人员

通过 JWT-pwn 测试你所在的组织的 JWT 实现,并报告所发现的任何漏洞或缺陷。

开发者和防御者

  • 确保你正在执行 JWT 验证器中使用的算法

  • 禁止使用未使用的算法(通过白名单方法)

  • 始终验证 JWT 头,并验证 JWT 头中的 JWT “alg”键

  • 永远不要使用“空”算法进行签名

  • 使用一个长且极难恢复的密钥。如果密钥被泄露或破解,整个身份验证将被破坏

  • 定期更改你的签名的键名称

  • 不要在 JWT 中公开重要的客户机数据; 可以对其进行解码。如果在有效载荷中共享了敏感数据,那么获得令牌的任何一方都能够看到它

  • 增加一个“有效期”的声明,以解决无状态协议中的没有有效期问题

Jwt-pwn 主页

https://github.com/mazen160/jwt-pwn

本文翻译自:https://mazinahmed.net/blog/breaking-jwt/如若转载,请注明原文地址:
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务