安基网 首页 安全 漏洞挖掘 查看内容

分享一个有趣且牛逼的漏洞

2020-8-5 01:13| 投稿: xiaotiger |来自: 互联网


免责声明:本站系公益性非盈利IT技术普及网,本文由投稿者转载自互联网的公开文章,文末均已注明出处,其内容和图片版权归原网站或作者所有,文中所述不代表本站观点,若有无意侵权或转载不当之处请从网站右下角联系我们处理,谢谢合作!

摘要: 和往常一样,我今天早早到了公司, 也就提前了两个小时吧(现在你们知道我为什么有时间写文章了吧)想着既然离上班还早,于是我逛起了推特,看看今天是哪位幸运的大佬被我膜拜,不一会,我就发现很多人都转了一条推特,这条推特是关 ...

如果文中图片加载不出来,请到我的公众号【一个安全研究员】查看原文

和往常一样,我今天早早到了公司, 也就提前了两个小时吧(现在你们知道我为什么有时间写文章了吧)

想着既然离上班还早,于是我逛起了推特,看看今天是哪位幸运的大佬被我膜拜,不一会,我就发现很多人都转了一条推特,这条推特是关于CVE-2020-13379这个漏洞的

看到这么多人都在转,那一定是很牛逼的漏洞,于是我点了进去...

这是一个Grafana的未授权ssrf漏洞,涉及3.0.1-7.0.1版本。下面是漏洞详情


CVE-2020-13379

漏洞的入口点是/avatar/:hash接口,在Grafana api.go 文件中我们可以看到如下的路由

r.Get("/avatar/:hash", avatarCacheServer.Handler)

这个路由会获取到接口/avatar/:hash中的hash值,并把它路由到secure.grafana.com,代码实现大体如下:

const (
 gravatarSource = "https://secure.gravatar.com/avatar/"
)
...
case err = <-thunder.GoFetch(gravatarSource+this.hash+"?"+this.reqParams, this):

代码中的gravatarSource的值就是secure.grafana.com,this.hash的值就是经过URL解码过后的/avatar/:hash中的:hash的值,因为:hash的值可控,所以我们可以注入参数到url中。

而这个secure.gravartar.com有一个特点,如下:

secure.gravartar.com这个网站是国外的一个著名的提供头像等图片的站点,而它还实现了从其它主机加载图片的功能,只要用参数d=指定你要加载的图片地址就行,例如你要加载的图片地址是http://axin.com/1.png,你就可以这么写https://www.gravatar.com/avatar/test?d=http%3a%2f%2faxin.com%2f1.png,注意,冒号斜杠等特殊等字符需要url编码

而这个功能是怎么实现的呢?

其实就是一个重定向,当我们请求https://www.gravatar.com/avatar/test?d=http%3a%2f%2faxin.com%2f1.png

会被重定向到

http://i0.wp.com/axin.com/1.png

我们可以用curl做个试验,如下

那你可能会疑惑了,我指定的地址不是http://axin.com/1.png吗,怎么给我跳到了i0.wp.com这个主机上呀

而且,这个主机怎么拿到我指定地址的图片的?

没错,你可能已经猜到了,这里又有一次重定向

当我们请求i0.wp.com/imageDomain/pathofImage时,会被重定向到imageDoamin/pathofImage这个地址,但是这里的imageDoamin可不是随便什么域名都可以,而是要*.bp.blogspot.com子域下的域名

这是一个白名单的配置,而我们需要做的就是绕过这个白名单,只要绕过了这个白名单,我们就大功告成了

我又探索了一番,发现了如下绕过手法

http://i0.wp.com/axin.com%3f/1.bp.blogspot.com/

通过如上技巧就可以轻松绕过白名单限制,把请求重定向到axin.com,至此就完成了整个ssrf,由于我在复现的过程中发现i0.wp.com已经修复了这种绕过方式,所以我贴一张原作者的图

从图中可以看到,确实是重定向到了我们指定的域名,但是修复过后,发送上述请求不会再重定向,而是返回400

这真是一个悲伤的故事

最后的payload类似这样: https://grafanaHost/avatar/test%3fd%3daxin.com%25253f%253b%252fbp.blogspot.com

再来梳理一下整个流程:

Grafana把字符串test%3fd%3daxin.com%25253f%253b%252fbp.blogspot.com当做:hash,此时,目标服务器会请求到

https://secure.gravatar.com/avatar/anything?d=axin.com%253f%3b/1.bp.blogspot.com/

然后,因为我们使用了d=参数,请求又被重定向到了

http://i0.wp.com/google.com%3f%;/1.bp.blogspot.com/

最后,由于白名单的正则缺陷,我们重定向到我们指定的主机地址axin.com

http://axin.com?;/1.bp.blogspot.com

最后,目标服务器会请求上述地址,然后给我们返回一个Content-Type为image/jpeg的响应,相关代码如下:

...
if avatar.Expired() {
 // The cache item is either expired or newly created, update it from the server
 if err := avatar.Update(); err != nil {
  log.Trace("avatar update error: %v", err)
  avatar = this.notFound
 }
}

if avatar.notFound {
 avatar = this.notFound
} else if !exists {
 if err := this.cache.Add(hash, avatar, gocache.DefaultExpiration); err != nil {
  log.Trace("Error adding avatar to cache: %s", err)
 }
}

ctx.Resp.Header().Add("Content-Type", "image/jpeg")

if !setting.EnableGzip {
 ctx.Resp.Header().Add("Content-Length", strconv.Itoa(len(avatar.data.Bytes())))
}

ctx.Resp.Header().Add("Cache-Control", "private, max-age=3600")

if err := avatar.Encode(ctx.Resp); err != nil {
 log.Warn("avatar encode error: %v", err)
 ctx.WriteHeader(500)
}

最后,漏洞作者给出了他自己的一个payload:

https://grafanaHost/avatar/test%3fd%3dredirect.rhynorater.com%25253f%253b%252fbp.blogspot.com%252fYOURHOSTHERE

但是,由于i0.wp.com修复了正则缺陷,这个payload好像也就失效了...

其他

原文地址: https://rhynorater.github.io/CVE-2020-13379-Write-Up

PPT: https://docs.google.com/presentation/d/1He_zFFXCuft3LsZTXbHKoDxQHNoSveZg2c2uF1HKuaw/edit#slide=id.g8dc2d55207_8_578

原文很精彩,我只挑了最最最最基础的漏洞原理讲了讲,漏洞作者可是用这个漏洞横扫了bugbounty呢!

ok,文章写完了,我也该下班了!我们周末见~



小编推荐:欲学习电脑技术、系统维护、网络管理、编程开发和安全攻防等高端IT技术,请 点击这里 注册账号,公开课频道价值万元IT培训教程免费学,让您少走弯路、事半功倍,好工作升职加薪!

本文出自:https://www.toutiao.com/a6856910277556994564/

免责声明:本站系公益性非盈利IT技术普及网,本文由投稿者转载自互联网的公开文章,文末均已注明出处,其内容和图片版权归原网站或作者所有,文中所述不代表本站观点,若有无意侵权或转载不当之处请从网站右下角联系我们处理,谢谢合作!


鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

 最新
返回顶部