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

从朋友那边找到的漏洞 Payload 中发现这是一个未授权的漏洞,打开 Github 上找到最新版本开始分析。

https://github.com/grafana/grafana/releases/tag/v8.3.0

先定位到路由函数

截屏2021-12-07 下午9.58.26

跟踪这个RouteRegister发现是github.com/grafana/grafana/pkg/api/routing这个包

截屏2021-12-07 下午10.08.48

继续跟踪 web 包

截屏2021-12-07 下午10.11.34

意思应该是调用 r.Get 或 r.Post 的时候,第一个参数是请求的地址,第二个以及后面的参数是相应的处理函数,这边判断如果只有第二个参数则无需鉴权。

那么找一下只有两个参数的 r.Get 调用

// expose plugin file system assets
r.Get("/public/plugins/:pluginId/*", hs.getPluginAssets)

跟踪getPluginAssets这个函数

// /public/plugins/:pluginId/*

进入这个路由会先查找插件是否存在,如果没有存在就会返回 Json 数据Plugin not found,如果存在这个插件名,则会匹配 * ,并且打开这个这个文件并输出。

那么利用方式就很明显了,访问/public/plugins/插件名/想要访问文件的相对路径即可得到想要访问的文件内容。

这边的插件名可以到grafana/grafana/public/app/plugins下找文件名,比如用welcome,想要访问/etc/passwd则可以构造/public/plugins/welcome/../../../../../../../../../etc/passwd这个 Payload 如下

截屏2021-12-07 下午10.50.39

Nginx 修复存在绕过

如果使用Nginx代理转发,可以在目标文件前加上/#/构造/public/plugins/:pluginId/#/../..%2f..%2f的方式来绕过 Nginx 的 normalize