Grafana 任意文件读取

今天早上在赛博群里看到关于 Grafana 的漏洞通告,但是twitter上没有发出细节,陈师傅和p神等大哥们一挖就挖出来了只能说太强了,由于这玩意儿使用的非常多,之前在实习的时候内网中遇到好多次,所以就来尝试不参考文章自己来挖一波,这篇文章主要是记录一下我挖掘的思路

Grafana 源码:https://github.com/grafana/grafana

之前没怎么看过go框架的代码,由于是任意文件读取所以去搜索了一下 go 中文件读取会用到的一些函数

这里搜到了 os.Open()

我这里直接全局搜索(因为猜测漏洞肯定会用到这个函数

image-20211208000338037

接下来我就尝试一个个进行查看

第一个很显然参数不可控,直接放弃

image-20211208000507792

依次往下粗略的看过去,说来也是运气好第二个其实就是我们的漏洞点,仔细来看一下

首先 pluginFilePath 作为参数传递给了 os.Open ,往上查看参数是否可控

首先会通过 join 来进行一个路径拼接这个不去管他,我们直接从最前面开始看

可以看到这里最上面的注释中 api 的路径为 /public/plugins/{pluginId}/*

首先会获取 pluginId 的参数,然后根据 id 来获取对应的插件,如果不存在的话就会返回 404 Plugin not found

然后 requestedFile 会获取 * 处的内容,并进行路径拼接传递给 os.Open ,那么理论上就可以造成任意文件读取

所以在这里两个点都是可控的

image-20211208000719106

大致思路有了接下来就是搭建环境进行测试了,直接docker开一个环境

先随意测试一下看一下这个接口是否会有权限校验,发现返回的是 Plugin not found 而不是返回到登陆页面,所以首先可以确认这个接口是不需要权限校验的,剩下来一个问题就是如何获取 pluginId

image-20211208001252833

既然不知道 pluginId 那么我们就去找就行了

进入 grafana 页面根据如下进入配置页面可以看到已安装的 plugin(要选择已安装的不然会报 404)

image-20211208001439846

Burp 抓个包看一下,这里已经可以从返回包里看到 id ,但是此时的我还不确定这就是 pluginId

image-20211208002901303

在源码中进行寻找,目的是寻找插件的结构体,我们传入的 pluginId 会传入 GetPlugin,返回的肯定是用插件结构体来接受,所以先去看 PluginManager 的结构体

image-20211208002344157

看到 GetPlugin 返回的是 *plugins.PluginBase 跟进看一下

image-20211208002635247

找到插件的结构体了,和返回包比对了一下对上了

image-20211208002323514

然后就很简单了 构造一个任意文件读取就行了

由于政策原因不能发poc (虽然很多公众号都发了,所以随便找一下就行了

image-20211208100917681

具体后续利用可以看忍者师傅星球和少宇师傅的 Github

评论

  1. 123
    7月前
    2021-12-13 5:22:06

    文章加密码是什么操作?😂

    • KpLi0rn 博主
      7月前
      2021-12-13 10:23:22

      师傅加我wx

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇