jwt security issues of web penetration

foreword

JWT stands for JSON Web Token, which is a standardized format for sending cryptographically signed JSON data between systems. The original Token is just a uuid without any meaning.

JWT contains some business information, which reduces interactive operations such as Token verification and is more efficient

JWT composition

JWT consists of three parts, namely:

  • Header — head

  • Payload — payload

  • Signature — signature

They are separated by three . and encrypted by Base64. Let's take the following JWT as an example to illustrate

eyJraWQiOiI5MTM2ZGRiMy1jYjBhLTRhMTktYTA3ZS1lYWRmNWE0NGM4YjUiLCJhbGciOiJSUzI1NiJ9 . eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTY0ODAzNzE2NCwibmFtZSI6IkNhcmxvcyBNb250b3lhIiwic3ViIjoiY2FybG9zIiwicm8sZSI6ImJsb2dfYXV0aG9yIiwiZW1haWwiOiJ jYXJsb3NAY2FybG9zLW1vbnRveWEubmV0IiwiaWF0IjoxNTE2MjM5MDIyfQ . SYZBPIBg2CRjXAJ8vCER0LA_ENjII1JakvNQoP-Hw6GG1zfl4JyngsZReIfqRvIAEi5L4HV0q7_9qGhQZvy9ZdxEJbwTxRs_6Lb-fZTDpW6lKYNdMyjw45_alSCZ1fypsMWz_2mTpQzil0l Otps5Ei_z7mM7M8gCwe_AGpI53JxduQOaB5HkT5gVrv9cKu9CsW5MS6ZbqYXpGyOG5ehoxqm8DL5tFYaW3lB50ELxi0KsuTKEbD0t5BCl0aCR2MBJWAbN-xeLwEenaqBiwPVvKixYleeDQiBEIyl FdNNIMviKRgXiYuAvMziVPbwSgkZVHeEdF5MQP1Oe2Spac-6IfA

Header section

The Header part is like the logo of a truck, telling us what explosives or flammables are loaded on the truck.

In the JWT, the Header part stores the Token type and the encryption algorithm of the token

{
"alg": "HS256", // can also be HS512, RS256 etc.
"typ": "JWT"
​​}

Payload section

The word Payload in Chinese means load, that is, the goods on our big trucks. Payload contains specific business data such as user id and so on.

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

Signature section

The Signature part means signature. The goods have been delivered and need to be signed by the other party. This is the signature. Signature is the specific digital signature ciphertext information. This part of ciphertext information is manually set, and is generally set in the configuration file developed by Java. like this

JWT basic security issues

The security problems caused by JWT are caused by inappropriate design and logic.

Among them, if the server does not verify the signature, the data can be modified arbitrarily. If the verification is performed, it cannot be modified, and we need to use other means to assist the attack.

1. The signature is not verified

As we mentioned earlier, JWT requires developers to provide a Signature — a signature. If we do not verify the signature, there may be a risk of making arbitrary changes to the rest of the token.

Assume the option exists with a JWT as follows

{
"username": "carlos",
"isAdmin": false
}

If the server identifies the session username based on this, and the signature is not authenticated, modifying its value could allow an attacker to impersonate another logged-in user. Similarly, if the isAdmin value is used to control whether it is an administrator, modifying its value to true may lead to vertical overreach.

PortSwigger Range

This lab uses a jwt based mechanism to handle sessions. Due to an implementation flaw, the server does not verify the signature of any jwt it receives. Range requirements: modify session token to access /admin's admin panel, then delete user carlos.

First visit the shooting range: bypass-via-unverified-signature , click my account in the upper right corner, and log in wiener:peter with the account password provided

jwt authentication information is returned after successful login

Each subsequent request will carry authentication information

Above we introduced that the second part of payload in jwt stores specific business data such as user id, etc. We directly select the data in the second part of jwt in burp and then perform base64 decoding to view, or use online tools to decode: https: // jwt.io/ . It is found that the value of the sub key is of course the username wiener

So what happens if I change it to the administrator user? After modifying as follows, click apply changes, and then the cookie information will be modified

After replaying the modified data packet, it is found that the user has changed to an administrator at this time, and the vertical override is successful.

We can copy the modified jwt authentication information, and then use the "Cookie Quick Manager" plug-in to modify the cookie of the current user wiener to the cookie of the administrator, and finally click Save

然后刷新浏览器,页面显示为administrator,接着进入到管理员面板

最后删除carlos用户

2. 接受没有签名的令牌

其中,JWT头包含一个alg参数。这告诉服务器使用哪种算法对令牌进行签名,从而服务器也使用这种算法对签名进行验证。

{

"alg": "HS256",

"typ": "JWT"

}

jwt可以使用一系列不同的算法进行签名,但也可以不进行签名。通过设置 alg 为 none,绕过验证,从而实现攻击。

PortSwigger 靶场

地址:signature-verification

本实验室使用基于jwt的机制来处理会话。服务器被不安全地配置为接受无符号jwt。要解决这个问题,请修改会话令牌以访问/admin的管理面板,然后删除用户carlos。您可以使用以下凭证登录您自己的帐户:wiener:peter

首先像上一关一样尝试直接将sub值修改为administrator,发现无法认证成功

此时在将sub值修改为administrator的基础上,再将alg的值修改为none,并且删除jwt的第三部分但要保留引号,让其成为 JWT 的形式,因为 Signature 是通过 alg 算法生成的,修改了alg值 Signature也会变所以要将其删除。

此时已经是administrator用户了,然后去完成删除用户的操作

3. jwt秘钥爆破

一些签名算法,如HS256 (HMAC + SHA-256),使用简单的的字符串作为密钥,就很容易被暴力破解。

在jwt中的Signature部分,使用秘钥secret加密生成Signature,当通过暴力破解获取到了secret值,就能重新加密生成任意的用户的jwt

PortSwigger 靶场

地址:web-security-academy.net

登录后获取jwt,然后使用jwt_tool进行 Secret 爆破,字典:jwt.secrets.list

jwt_tool.py jwt -C -d 字典
#或者使用hashcat
hashcat -a 0 -m 16500 <jwt> <wordlist>

获取到了 Secret 为 "secret1",接着我们去到 jwt.io 下伪造administrator身份。如下填入,然后复制jwt替换原本的jwt

实现越权操作

4. jwt标头注入

根据JWS规范,只有alg标头参数是必需的。然而,在实践中,JWT报头(也称为何塞报头)通常包含几个其他参数。以下是攻击者特别感兴趣的。

  • jwk(JSON Web Key)——提供一个表示密钥的嵌入式JSON对象。

  • jku(JSON Web密钥集URL) -提供一个URL,服务器可以从该URL获取一组包含正确密钥的密钥。

  • kid(密钥ID) -提供一个ID,在有多个密钥可供选择的情况下,服务器可以使用该ID来识别正确的密钥。根据密钥的格式,这可能有匹配的kid参数。

正如您所看到的,这些用户可控制的参数都在告诉接收方服务器在验证签名时需使用哪个密钥。所以接下来将学习如何使用您自己的任意密钥去注入修改jwt签名而不是使用默认的服务器秘钥。

通过jwk头注入绕过JWT认证

jwk header中提供了一个可选的jwk参数,服务器可以使用该参数以JWK格式将其公钥直接嵌入令牌本身。JWK (JSON Web Key)是将键表示为JSON对象的标准化格式。

{
"kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG",
"typ": "JWT",
"alg": "RS256",
"jwk": {
"kty": "RSA",
"e": "AQAB",
"kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG",
"n": "yy1wpYmffgXBxhAUJzHHocCuJolwDqql75ZWuCQ_cb33K2vh9m"
}
}

理想情况下,服务器应该只使用指定的公钥来验证JWT签名。然而,错误配置的服务器有时会使用嵌入在jwk参数的公钥来验证,即允许任意公钥。所以通过使用自定义的RSA私钥对修改后的JWT进行签名,然后将匹配的公钥嵌入jwk标题,从而生成新的jwt,实现jwt认证绕过。

先安装 Burpsuite 的 JWT Editor Keys插件,burp商店中自带。靶场地址:bypass-via-jwk-header-injection

点击我们安装的 JWT Editor Keys插件中的 New RSA Key,生成 默认2048 长度的 JWK 私钥,点击ok保存。

回到repeatter模块中,将sub值改为administrator,然后点击Attack,点击“EMbedded JWK”,选择新生成的RSA秘钥,点击ok

在JWT的标题中,可以看到jwk已添加包含您的公钥的参数,发送请求,服务器会使用jwk中的公钥进行解密,从而绕过认证。成功变为administrator用户

还有其他的一些注入,后续补充

JWT 安全问题的防护

  • 使用最新的 JWT 库,虽然最新版本的稳定性有待商榷,但是安全性都是较高的。

  • 对 jku 标头进行严格的白名单设置。

  • 确保 kid 标头不容易受到通过 header 参数进行目录遍历或 SQL 注入的攻击。

参考:

Guess you like

Origin blog.csdn.net/qq_44159028/article/details/129683126