Grafana 任意文件读取漏洞 CVE-2021-43798 漏洞分析
从朋友那边找到的漏洞 Payload 中发现这是一个未授权的漏洞,打开 Github 上找到最新版本开始分析。
https://github.com/grafana/grafana/releases/tag/v8.3.0
先定位到路由函数

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

继续跟踪 web 包

意思应该是调用 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 如下

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