Grafana 任意文件读取漏洞 CVE-2021-43798

发表于 golang comment...
第一次在没有获取到漏洞细节,反推出漏洞存在点,感觉还是很有成就感的...

背景

payload如下:

public/plugins/grafana-clock-panel/../../../../../../etc/passwd

下载/安装

进入 pkg/api/api.go文件夹,寻找路由,跟进 getPluginAssets ,换 Goland 方便跟进函数,函数getPluginAssetsplugins.go 中,这里filepath.Join 直接获取了插件的名字plugin.PluginDir和路径requestedFile进行了拼接(但是在之前有判断插件是否存在,因此得是存在的插件),然后直接使用 os.Open 打开了插件,这时候导致了问题的存在:

  • filepath.Join 用于拼接URL路径 filepath.Join(“a”,“a”). => “a/a”
  • filepath.Clean 清理路径中的多余字符 , 也就是这里出现了问题,导致 ../ 进行了拼接

关于 filepath.Clean

在过滤时候, /../../../可以进行处理

但是 ../../../ 并不会被处理

使用 os.Open 打开文件,使用ServeContent

查看修复方式

在最新版本已经修复了,修复方式就是在数组前加上 /

// https://github.com/grafana/grafana/blob/main/pkg/api/plugins.go
requestedFile := filepath.Clean(filepath.Join("/", web.Params(c.Req)["*"]))
rel, err := filepath.Rel("/", requestedFile)

其他 TIPS

可以通过在前面加上//../,让nginx不处理后的锚点

/public/plugins/alertlist/#/../..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f/etc/hosts
  • 本文作者: shangzeng
  • 版权声明: 本博客所有文章除特别声明外,均采用「 知识共享署名4.0 」创作共享协议,转载请注明作者及原网址。