中间件无忧·日更

入侵JSON Web令牌(JWT)

2019-10-30  本文已影响0人  开心人开发世界

攻击者如何伪造令牌并以其他人身份登录

JSON Web令牌是一种在商业应用程序中广泛使用的访问令牌。它们基于JSON格式,并包含令牌签名以确保令牌的完整性。

今天,我们将讨论使用JSON Web令牌(通常是基于签名的令牌)的安全隐患,以及攻击者如何利用它们绕过访问控制。

JSON Web令牌如何工作?

JSON Web令牌包含三个组件:标头,payload和签名。

标头

JSON Web令牌的标头部分标识用于生成签名的算法。它是JSON Blob的base64编码的字符串,如下所示:

{
 "alg" : "HS256",
 "typ" : "JWT"
}
base64 encoded string: eyBhbGcgOiBIUzI1NiwgdHlwIDogSldUIH0K

最常用的算法是HMAC和RSA算法。

payload

payload部分包含实际用于访问控制的信息。此部分在用于令牌之前也已进行base64编码。

{
 "user_name" : "admin",
}
base64 encoded string: eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg

签名

签名是用于验证令牌未被篡改的部分。它是通过将标头与payload串联在一起,然后使用标头中指定的算法进行签名来计算的。

signature = HMAC-SHA256(base64Encode(header) + '.' + base64Encode(payload), secret_key)
// Let's just say the value of secret_key is "key".
-> signature function returns 4Hb/6ibbViPOzq9SJflsNGPWSk6B8F6EqVrkNjpXh7M

对于此特定令牌,字符串“ eyBhbGcgOiBIUzI1NiwgdHlwIDogSldUIH0K.eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg”已用密钥“ key”的HS256算法签名。生成的字符串是4Hb / 6ibbViPOzq9SJflsNGPWSk6B8F6EqVrkNjpXh7M

完整的令牌

通过将每个部分(标头,有效负载和签名)与每个部分之间的“。”串联起来,可以获得完整的令牌。

eyBhbGcgOiBIUzI1NiwgdHlwIDogSldUIH0K.eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg.4Hb / 6ibbViPOzq9SJflsNGPWSk6B8F6EqVrkNjpXh7M

绕过JSON Web令牌控件的方法

如果正确实现,JSON Web令牌将提供一种安全的方式来标识用户,因为payload部分中包含的数据无法被篡改。(由于用户无权访问密钥,因此她不能自己对令牌进行签名。)

但是,如果实施不正确,攻击者可以通过多种方式绕过安全机制并伪造任意令牌。

更改算法类型

攻击者可以伪造自己的令牌,其中一种方法是篡改标头的alg字段。如果应用程序不限制JWT中使用的算法类型,则攻击者可以指定要使用的算法,这可能会损害令牌的安全性。

  1. 无算法

JWT支持“无”算法。如果将alg字段设置为“ None”,则如果其标记部分设置为空,则任何令牌都将被视为有效。例如,以下令牌将被视为有效:

eyAiYWxnIiA6ICJOb25lIiwgInR5cCIgOiAiSldUIiB9Cg.eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg。

它只是这两个Blob的base64编码版本,没有签名。

{
 "alg" : "None",
 "typ" : "JWT"
}
{
 "user" : "admin"
}

此功能最初用于调试目的。但是,如果没有在生产环境中将其关闭,则攻击者可以通过将alg字段设置为“ None” 来伪造他们想要的任何令牌。然后,他们可以使用伪造的令牌模拟网站上的任何人。

2. HMAC算法

用于JWT的两种最常见的算法类型是HMAC和RSA。使用HMAC,将使用密钥对令牌进行签名,然后使用相同的密钥进行验证。对于RSA,将首先使用私钥创建令牌,然后使用相应的公钥进行验证。

HMAC -> signed with a key, verified with the same key
RSA -> signed with a private key, verified with the corresponding public key

至关重要的是,将HMAC令牌的私钥和RSA令牌的私钥保密,因为它们用于签名令牌。

现在,我们假设有一个最初设计为使用RSA令牌的应用程序。令牌用私钥A签名,私钥A对公众保密。然后,使用任何人都可以使用的公钥B验证令牌。只要令牌始终被视为RSA令牌,就可以。

Token signed with key A -> Token verified with key B (RSA scenario)

现在,如果攻击者改变的ALG到HMAC,她可能通过与RSA公钥B.签署伪造的令牌能够创建有效令牌

这是因为最初使用RSA对令牌进行签名时,程序会使用RSA公钥B对其进行验证。当将签名算法切换为HMAC时,仍使用RSA公钥B来验证令牌,但是这次是使用令牌可以使用相同的公钥B签名(因为它使用的是HMAC)。

Token signed with key B -> Token verified with key B (HMAC scenario)

提供无效的签名

令牌的签名在到达应用程序后也可能永远不会被验证。这样,攻击者可以通过提供无效签名来简单地绕过安全机制。

暴力破解密钥

也有可能暴力破解用于签署JWT的密钥。

攻击者从一开始就有很多信息:她知道用于对令牌进行签名的算法,已签名的有效负载以及生成的签名。如果用于对令牌进行签名的密钥不够复杂,则她可能可以轻松地对其进行暴力破解。

泄漏密钥

如果攻击者无法蛮力破解密钥,则可以尝试泄漏秘密密钥。如果存在另一个允许攻击者读取存储密钥值的文件的漏洞(如目录遍历,XXE,SSRF),则攻击者可以窃取密钥并签署任意令牌。

KID操作

KID代表“Key ID”。它是JWT中的可选标头字段,它使开发人员可以指定用于验证令牌的密钥。KID参数的正确用法如下所示:

{
 "alg" : "HS256",
 "typ" : "JWT",
 "kid" : "1"       // use key number 1 to verify the token 
}

由于此字段是由用户控制的,因此攻击者可能会操纵它并导致危险的后果。

  1. 目录遍历

由于KID通常用于从文件系统中检索密钥文件,因此,如果在使用前未对其进行清理,则可能导致目录遍历攻击。在这种情况下,攻击者将能够在文件系统中指定任何文件作为用于验证令牌的密钥。

“kid”: “../../public/css/main.css” 
// use the publicly available file main.css to verify the token

例如,攻击者可以迫使应用程序使用公开可用的文件作为密钥,并使用该文件对HMAC令牌进行签名。

2. SQL注入

KID还可以用于从数据库检索密钥。在这种情况下,可能可以利用SQL注入来绕过JWT签名。

如果可以在KID参数上进行SQL注入,则攻击者可以使用该注入返回她想要的任何值。

“kid”: "aaaaaaa' UNION SELECT 'key';--"
// use the string "key" to verify the token

例如,上面的注入将使应用程序返回字符串“ key”(因为数据库中不存在名为“ aaaaaaa”的键)。然后将使用字符串“ key”作为密钥来验证令牌。

标头参数处理

除密钥ID外,JSON Web令牌标准还使开发人员能够通过URL指定密钥。

  1. JKU标头参数

JKU代表“ JWK设置URL”。它是一个可选的标头字段,用于指定指向一组用于验证令牌的密钥的URL。如果允许该字段,并且没有适当地限制该字段,则攻击者可以托管自己的密钥文件,并指定应用程序使用它来验证令牌。

jku URL -> file containing JWK set -> JWK used to verify the token

2. JWK标头参数

可选的JWK(JSON Web密钥)标头参数允许攻击者将用于验证令牌的密钥直接嵌入令牌中。

3. X5U,X5C URL操作

类似于jku和jwk标头,x5u和x5c标头参数允许攻击者指定用于验证令牌的公钥证书或证书链。x5u以URI形式指定信息,而x5c允许将证书值嵌入令牌中。

其他JWT安全问题

如果未正确实施,还会产生其他JWT问题。这些不是很常见,但是绝对值得关注:

信息泄漏

由于JSON Web令牌用于访问控制,因此它们通常包含有关用户的信息。

如果令牌未加密,则任何人都可以通过base64解码令牌并读取令牌的有效负载。因此,如果令牌包含敏感信息,则它可能成为信息泄漏的来源。JSON Web令牌的正确实现的签名部分可提供数据完整性,而不是机密性。

命令注入

有时,当KID参数直接传递到不安全的文件读取操作中时,可能会将命令注入代码流中。

可能允许这种类型的攻击的函数之一是Ruby open()函数。此功能使攻击者只需在KID文件名之后将命令添加到输入即可,即可执行系统命令:

“key_file” | whoami;

这只是一个例子。从理论上讲,每当应用程序将未经消毒的任何头文件参数传递给任何类似于system(),exec()等的函数时,就会发生此类漏洞。

最终,JSON Web令牌只是用户输入的另一种形式。他们应始终持怀疑态度并严格审查。


免责声明:这篇文章旨在引起人们对JSON Web令牌漏洞的关注,并帮助开发人员识别常见的陷阱。请不要使用此信息来攻击网站或冒充他人。

在没有测试权限的系统上尝试此操作是非法的。如果您发现了漏洞,请以负责任的方式向供应商披露。帮助使我们的互联网更安全。

翻译自:https://medium.com/swlh/hacking-json-web-tokens-jwts-9122efe91e4a

上一篇下一篇

猜你喜欢

热点阅读