0x00 前言
漏洞名称:Grafana任意文件读取
漏洞编号:CVE-2021-43798
影响版本:8.0.0-Beta1-8.3.0
漏洞危害:任意文件读取
0x01 漏洞分析
根据 CVE 官网介绍,可知漏洞利用路径为 /public/plugins/:
Grafana 控制 api 的路径为 pkg/api/api.go,在该文件下找到 /public/plugins/:
发现此接口后面还需要跟上 “pluginId”,对应的方法是 hs.getPluginAssets,跟进该方法:
代码不长,可以一段一段来解析。
227-282:
这一段定义了 pluginID等于请求路径中的 “pluginID”。
hs.pluginStore.Plugin 实际调用:
若 pluginID 不存在则返回404。
284-285:
从请求路径中提取 path,并和 PluginDir 拼接成 pluginFilePath。
PlunginDir 可以从 init() 中找到:
跟进94行中的 corePluginPaths:
可以看到路径需要 m.cfg.StaticRootPath 与app路径拼接,全局搜索得到路径为public
跟进路径,可知初始 pluginID 有:
cloud-monitoring,cloudwatch,dashboard,elasticsearch,grafana,grafana-azure-monitor-datasource,graphite,influxdb,jaeger,loki,mixed,mssql,mysql,opentsdb,postgres,prometheus,tempo,testdata,zipkin,alertGroups,alertlist,annolist,barchart,bargauge,candlestick,canvas,dashlist,debug,gauge,geomap,gettingstarted,graph,heatmap,histogram,icon,live,logs,news,nodeGraph,piechart,pluginlist,stat,state-timeline,status-history,table,table-old,text,timeseries,welcome,xychart
295:
这里使用 os.open 打开pluginFilePath。
322:
这里会直接返回打开的文件内容。
因此使用存在的 pluginId,再利用目录穿越就可以实现任意文件读取。
则 payload 应为:
http://0.0.0.0/public/plugins/@pluginID/../../../../../../../../../etc/passwd
实际测试发现初始化 pluginID应该有47个:
cloudwatch,dashboard,elasticsearch,grafana,grafana-azure-monitor-datasource,graphite,influxdb,jaeger,loki,mixed,mssql,mysql,opentsdb,postgres,prometheus,tempo,testdata,zipkin,alertGroups,alertlist,annolist,barchart,bargauge,canvas,dashlist,debug,gauge,geomap,gettingstarted,graph,heatmap,histogram,live,logs,news,nodeGraph,piechart,pluginlist,stat,state-timeline,status-history,table,table-old,text,timeseries,welcome,xychart