记录黑客技术中优秀的内容,传播黑客文化,分享黑客技术精华

JSON Web Token 攻击和漏洞

2021-07-07 07:22

JSON Web Token 攻击和漏洞

JSON Web Token (JWT) 提供了一种使用 JSON 对象安全交换数据的方法。它们通常用于授权,因为它们可以被签名、验证并因此受到信任——但前提是正确实施。本文是对 JSON Web Token 攻击和漏洞的技术深入探讨。

JWT 格式

一个 JSON Web Token 由 base64url 编码的 header、payload 和签名组成,用点分隔,如下所示:

HEADER.PAYLOAD.SIGNATURE

让我们拆开以下真实Token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJuYW1lIjoiSm9obiBEb2UiLCJ1c2VyX25hbWUiOiJqb2huLmRvZSIsImlzX2FkbWluIjpmYWxzZX0.
fSppjHFaqlNcpK1Q8VudRD84YIuhqFfA67XkLam0_aY

头部包含有关令牌的元数据,例如用于签名的算法和令牌的类型(简称 JWT)。对于此示例,编码前的头部为:

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

payload包含有关将由应用程序验证的实体(用户)的信息(声明)。我们的示例令牌包括以下声明:

{
  "name": "John Doe",
  "user_name": "john.doe",
  "is_admin": false
}

最后,要生成签名,我们必须对头部、点和payload应用 base64url 编码,然后根据算法使用密钥(用于对称加密)或私钥(用于非对称加密)对整个事物进行签名在头部中指定。我们已经放入HS256了头部,这是一种对称算法,因此编码和签名操作将是:

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

这为我们提供了以下签名,然后将其附加(在一个点之后)到 base64url 编码的头部和payload:

fSppjHFaqlNcpK1Q8VudRD84YIuhqFfA67XkLam0_aY

常见的 JWT 漏洞

JSON Web Tokens 被设计为灵活且面向未来,为适应各种用例和要求留下了很大的空间——但在实现和使用中也有很大的错误空间。以下是使用 JWT 时可能引入的一些典型漏洞。

无法验证签名

许多 JWT 库提供一种方法来解码令牌,另一种方法来验证它:

decode(): 只从 base64url 编码解码令牌,而不验证签名。

verify():解码令牌并验证签名。

有时,开发人员可能会混淆这些方法。在这种情况下,签名永远不会被验证,应用程序将接受任何令牌(以有效格式)。开发人员也可能禁用签名验证以进行测试,然后忘记重新启用它。此类错误可能导致任意帐户访问或权限升级。

例如,假设我们有以下从未实际验证过的有效令牌:

{

  "alg": "HS256",

  "typ": "JWT"

}.

{

  "name": "John Doe",

  "user_name": "john.doe",

  "is_admin": false

}

攻击者可以发送带有任意签名的以下令牌以获得升级的权限:

{

  "alg": "HS256",

  "typ": "JWT"

}.

{

  "name": "John Doe",

  "user_name": "john.doe",

  "is_admin": true

}

允许None算法

JWT 标准接受许多不同类型的算法来生成签名:

RSA

HMAC

椭圆曲线 

None

None算法指定令牌未签名。如果允许使用此算法,我们可以通过将现有算法更改为None并剥离签名来绕过签名检查。让我们从我们预期的令牌开始:

{

  "alg": "HS256",

  "typ": "JWT"

}.

{

  "name": "John Doe",

  "user_name": "john.doe",

  "is_admin": false

}.SIGNATURE

编码和签名,令牌将如下所示(粗体签名):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.

eyJuYW1lIjoiSm9obiBEb2UiLCJ1c2VyX25hbWUiOiJqb2huLmRvZSIsImlzX2FkbWluIjpmYWxzZX0.

fSppjHFaqlNcpK1Q8VudRD84YIuhqFfA67XkLam0_aY

如果None允许作为算法值,攻击者可以简单地使用它来替换有效算法,然后去掉签名:

{

  "alg": "None",

  "typ": "JWT"

}.

{

  "name": "John Doe",

  "user_name": "john.doe",

  "is_admin": true

}.

虽然现在未签名,但修改后的令牌将被应用程序接受:

eyJhbGciOiJOb25lIiwidHlwIjoiSldUIn0.

eyJuYW1lIjoiSm9obiBEb2UiLCJ1c2VyX25hbWUiOiJqb2huLmRvZSIsImlzX2FkbWluIjp0cnVlfQ.

这就是为什么不接受令牌中的NonenoneNONEnOnE是很重要,或其他任何情况下,在变化alg头。

算法混乱

JWT 接受对称和非对称加密算法。根据加密类型,您需要使用共享密钥或公私密钥对:


算法

用于签名的密钥

用于验证的密钥

非对称 (RSA)

私钥

公钥

对称 (HMAC)

共享密钥

共享密钥


当应用程序使用非对称加密时,它可以公开发布其公钥并保持私钥保密。这允许应用程序使用其私钥签署令牌,任何人都可以使用其公钥验证此令牌。当应用程序不检查接收到的令牌的算法是否与预期的算法匹配时,就会出现算法混淆漏洞。

在很多 JWT 库中,验证签名的方法是:

verify(token, secret) – 如果令牌是用 HMAC 签名的

verify(token, publicKey) – 如果令牌是用 RSA 或类似方法签名的

不幸的是,在某些库中,此方法本身不会检查收到的令牌是否使用应用程序的预期算法进行签名。这就是为什么在 HMAC 的情况下,此方法将第二个参数视为共享密钥,而在 RSA 的情况下,则将其视为公钥。

如果在应用程序中可以访问公钥,攻击者可以通过以下方式伪造恶意令牌:

1.将令牌的算法更改为 HMAC

2.篡改payload以获得所需的结果

3.使用在应用程序中找到的公钥对恶意令牌进行签名

4.将 JWT 发送回应用程序

该应用程序需要 RSA 加密,因此当攻击者提供 HMAC 时, verify()方法会将公钥视为 HMAC 共享密钥并使用对称加密而不是非对称加密。这意味着令牌将使用应用程序的非密钥公钥进行签名,然后使用相同的公钥进行验证。

为避免此漏洞,应用程序必须在将令牌传递给verify()方法之前检查接收到的令牌的算法是否是预期的算法。

使用琐碎的密钥

对于对称加密,加密签名的强度取决于所使用的密钥。如果应用程序使用弱密钥,攻击者可以简单地通过尝试不同的密钥值来暴力破解它,直到原始签名与伪造的签名相匹配。发现密钥后,攻击者可以使用它为恶意令牌生成有效签名。为避免此漏洞,对称加密必须始终使用强密钥。

针对 JSON Web 令牌的攻击

kid 参数注入

JWT 头部可以包含 Key Id 参数kid。它通常用于从数据库或文件系统中检索密钥。应用程序使用通过kid参数获得的密钥来验证签名。如果参数是可注入的,它可以打开绕过签名甚至攻击的方式,例如RCESQLiLFI

要查看此操作,让我们从以下有效令牌开始:

{

  "alg": "HS256",

  "typ": "JWT",

  "kid": "key1"

}.

{

  "name": "John Doe",

  "user_name": "john.doe",

  "is_admin": false

}

如果kid参数容易受到命令注入,以下修改可能会导致远程代码执行:

{

  "alg": "HS256",

  "typ": "JWT",

  "kid": "key1|/usr/bin/uname"

}.

{

  "name": "John Doe",

  "user_name": "john.doe",

  "is_admin": false

}

kid 参数注入 + 目录遍历 = 签名绕过

如果应用程序使用该kid参数从文件系统中检索密钥,则它可能容易受到目录遍历的影响。然后攻击者可以强制应用程序使用攻击者可以预测其值的文件作为验证密钥。这可以使用应用程序中的任何静态文件来完成。知道密钥文件值后,攻击者可以制作恶意令牌并使用已知密钥对其进行签名。

继续前面的 JWT 示例,攻击者可能会尝试插入/dev/null作为密钥源以强制应用程序使用空密钥:

{

  "alg": "HS256",

  "typ": "JWT",

  "kid": "../../../../../../dev/null"

}.

{

  "name": "John Doe",

  "user_name": "john.doe",

  "is_admin": true

}

如果目录遍历/dev/null成功,攻击者将能够使用空字符串对恶意令牌进行签名。相同的技术可以用于已知的静态文件,例如 CSS 文件。

kid 参数注入 + SQL 注入 = 签名绕过

如果应用程序使用该kid参数从数据库中检索密钥,则它可能容易受到SQL 注入攻击。如果成功,攻击者可以控制kid从 SQL 查询返回到参数的值,并使用它来签署恶意令牌。

再次使用相同的示例令牌,假设应用程序使用以下易受攻击的 SQL 查询通过kid参数获取其 JWT 密钥:

SELECT key FROM keys WHERE key='key1'

然后攻击者可以UNION SELECTkid参数中注入一条语句来控制键值:

{

  "alg": "HS256",

  "typ": "JWT",

  "kid": "xxxx' UNION SELECT 'aaa"

}.

{

  "name": "John Doe",

  "user_name": "john.doe",

  "is_admin": true

}

如果 SQL 注入成功,应用程序将使用以下查询来检索签名密钥:

SELECT key FROM keys WHERE key='xxxx' UNION SELECT 'aaa'

复制

此查询返回aaakid参数中,允许攻击者简单地使用 对恶意令牌进行签名aaa。 

为避免这些和其他注入攻击,应用程序应始终kid在使用前清理参数的值。

使用jku头部进行攻击

在 JWT 头部中,开发人员还可以使用jku参数指定JSON Web Key Set URL。此参数指示应用程序可以在何处找到用于验证签名的JSON Web Key (JWK) – 基本上是 JSON 格式的公钥。

为了说明,让我们以以下使用jku参数指定公钥的JWT 为例:

{

  "alg": "RS256",

  "typ": "JWT",

  "jku":"https://example.com/key.json"

}.

{

  "name": "John Doe",

  "user_name": "john.doe",

  "is_admin": false

}

指定的key.json文件可能类似于:

{

  "kty": "RSA",

  "n": "-4KIwb83vQMH0YrzE44HppWvyNYmyuznuZPKWFt3e0xmdi-WcgiQZ1TC...RMxYC9lr4ZDp-M0",

  "e": "AQAB"

}

应用程序使用基于jku头部值检索到的 JSON Web Key 来验证签名:

现在进行攻击。攻击者可以更改jku参数值以指向他们自己的 JWK 而不是有效的 JWK。如果被接受,这将允许攻击者使用他们自己的私钥签署恶意令牌。发送恶意令牌后,应用程序将获取攻击者的 JWK 并使用它来验证签名:

为防止此类攻击,应用程序通常使用 URL 过滤。不幸的是,攻击者有多种方法可以绕过这种过滤,包括:

使用https://trusted(例如https://trusted@attacker.com/key.json),如果应用程序检查以trusted

使用带有#字符的URL 片段

使用 DNS 命名层次结构

使用开放式重定向链接

与头部注入链接

与 SSRF 链接

出于这个原因,应用程序将允许的主机列入白名单并进行正确的 URL 过滤非常重要。除此之外,应用程序不得存在攻击者可能会链接以绕过 URL 过滤的其他漏洞。

总结

JSON Web 令牌正在成为现代 Web 应用程序开发中身份验证过程的重要组成部分,尤其是在实现单点登录 (SSO) 时。为了防止 JWT 漏洞,开发人员应该遵循最佳实践并使用受信任的 JWT 库,而不是滚动他们自己的实现。为了最大限度地降低攻击者将 JWT 攻击与其他漏洞链接在一起的风险,您还应该使用高质量的漏洞扫描解决方案来发现漏洞,以免被网络犯罪分子利用。像 Netsparker 这样的现代 DAST 工具可以识别 JWT 漏洞以及数千个其他问题,使其成为任何应用程序安全工具箱的重要组成部分。


知识来源: https://mp.weixin.qq.com/s?__biz=MzU1Mjk3MDY1OA==&mid=2247492692&idx=1&sn=28a6c0e6efc53c54a05b6f0ded538297&chksm=fbfb5499cc8cdd8f1b7a12a4329222a0c217faf4f4de779b08f53db8569f53c0871dca2a6b70&scene=27&k

阅读:65042 | 评论:0 | 标签:漏洞 攻击

想收藏或者和大家分享这篇好文章→复制链接地址

“JSON Web Token 攻击和漏洞”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

永久免费持续更新精选优质黑客技术文章Hackdig,帮你成为掌握黑客技术的英雄

求赞助求支持💖

标签云