Scary Tickets:第三方服务系统存在的安全风险(下)

 

一、利用Zendesk配置

根据前面对Zendesk的了解,我们想挖掘如何利用这种处理过程来攻击正常客户。为了避免重复造轮子,我决定再次阅读Inti的研究报告,看他是否忽视过其他攻击方法。在Inti的研究报告中,他提到了利用类似系统来访问Slack以及Yammer。我觉得还有其他利用场景能够造成更严重的后果,比如在Google上获得有效的@domain.com邮箱,然后利用该邮箱获得访问权限。在下文中,我将与大家分享我在漏洞报告中使用的几个案例。

攻击Zendesk

1、获得Google账户

每次渗透测试我们都可以先从定位公司的支持邮箱开始。为了完成该任务,我使用hunter.io来寻找可能存在的支持邮箱列表。找到目标邮箱后,我使用自己的账户往该邮箱发送了一封简单邮件,请求提供帮助。如前文所述,如果目标服务使用的是Zendesk,那么通常就会自动回复邮件表示已确认收到我们发送的邮件。收到回复邮件后,我们就可以从中提取出哈希值。

然后,我访问accounts.google.com开始注册账户。Google有一个注册功能,可以让我们绑定域名。这个功能非常有用,我们可以在Google上注册自己公司的域名,然后使用日历、群组等功能,无需创建GSuite账户或者注册GSuite服务。还有一点比较有趣,Google上大多数“Sign in with Google”使用的是Google的OpenID,当用户注册或者登录时只会检查邮箱的域名。因此这就会让这种攻击技术变得更加危险。

为了获得有效的support+1@domain.com邮箱,首先我回复自动回复邮件,将no-reply@google.com添加为ticket的CC,完成该操作后再访问Google注册账户。注册账户时,我在名字(First Name)和姓氏(Last Name)字段填入的时ticket的哈希值。之所以这么做,是因为在发送验证码时,Google会向support+1@domain.com邮箱发送一封邮件,邮件正文中包含Hi {firstname} {lastname}。成功完成测试后,我已经得到了经过验证的@domain.com邮箱,并且可以在“Sign in with Google”的大多数页面上使用。

2、利用已验证的邮箱

<1> 登录内部域名:

在Google上获得已验证的邮箱后,我想测试能否在目标公司(Gitlab)内部或者敏感的环境中使用这个邮箱。其中有个网址为https://prometheus.gitlab.com/,该站点需要@gitlab.com域名才能登陆。

然而需要注意的是,这里可能存在两种不同的Oauth:在某些站点中,Oauth使用的是简单的登录策略,会检查用来登录的域名是否与公司域名(gitlab.com)相匹配,并检查用户账户是否存在于目标系统中(Prometheus)。在类似Prometheus的某些服务中,用户账户采用自动配置(auto-provisioned)策略,这意味着只要用户使用@gitlab.com域名,即使该用户在目标系统中不存在,也能成功登录,使用有限的访问权限。在某些情况下,有些公司会使用基于GSuite的Oauth。在这种情况下,虽然我们能看到同样的Google登录页面,但后台的登录过程有所不同。登录函数会检查该组织的GSuite用户列表中是否存在该邮箱地址。通过Zendesk漏洞验证的任何邮箱并不存在于GSuite中,因为我们只能在Google中验证不存在的邮箱。如果目标企业使用的是GSuite SSO,那么我们就无法利用这个登录过程。

回到Gitlab,我尝试使用已获得账户登录Prometheus。(对我而言)幸运的是,Gitlab使用的是常规的Oauth,这样我就能成功登录Prometheus(出于安全保护考虑这里不展示截图)。

<2> 登录Atlassian实例:

在某些情况下,我无法找到能够登录的任何内部域。我测试的某个公司最近已经将所有Oauth迁移到GSuite SSO,因此我登录内部域的所有尝试都以失败告终。然而在某些情况下,我发现有些公司会通过Atlassian的云功能来运行公司的JIRA实例。除了将JIRA安装在本地服务器以外,我们还能在Atlassian自己的域中(atlassian.net)运行JIRA,这是一种开箱即用的服务方式。对于这类实例,大多数都允许带有公司域名的任何人登录并查看JIRA ticket。对于这个公司,虽然所有的实例都已迁移到GSuite SSO上,但他们忘了将JIRA登录口迁移到GSuite SSO上,因此我可以登录并查看系统中的JIRA ticket。

使用内部域名的Google和Atlassian登录口并不是这个漏洞的唯一攻击点。我们可以在其他第三方服务(如Zoom和Asana)上利用这个漏洞,获得目标公司的受限访问资源,包括视频(Zoom)以及内部项目管理信息(Asana)。接下来我们将分析Help Scout利用方法以及这种攻击方法的局限性。

攻击Help Scout

在针对支持系统的测试报告中,Inti最令人激动的一个发现就是成功进入了目标公司的Slack实例。Inti在测试Zendesk时发现,如果攻击者可以使用no-reply@slack.com注册公司的Zendesk实例,那么就可以加入目标Slack实例,因为Slack会通过这个no-reply邮箱发送邀请链接。发现这个问题后,Slack决定在no-reply后面加一串随机的字母数字(比如no-reply-940819dh9uhfy87sgf@slack.com)来保护客户,导致攻击者无法准确猜出正确的邮箱。对于Help Scout,当我们利用Slack实例时事情变得更加有趣起来。

在进入Slack利用环节之前,我们需要重点关注Slack的某些功能,这样攻击起来更加方便。与其他服务一样,Slack也为企业提供了不同选购方案。免费版最为简单,没有集成类似SSO之类的企业工具。Slack实例还支持域限制,使企业能限制可以自动加入Slack的用户。此外,Slack还支持查找用户加入、受邀以及所属的所有工作区(workspace),如果我们加入太多的workspace,以至于无法跟踪特定的实例,那么这个功能就非常有用。在本次研究中,我们会利用到这些功能,配合Help Scout来获得目标企业内部Slack实例的访问权限。需要强调的是,我们并没有刻意去加入某些Slack实例,只加入了其中一个实例,并且整个过程都已获得目标企业授权,处于目标企业监控下,确保我们没有执行任何恶意操作。

在此次利用过程中,“目标企业(company)”表示该目标存在Help Scout攻击漏洞。当我向support@company.com发送邮件时,就可以获得自动回复,发现目标企业使用的是Help Scout。了解这一点后,我提取了哈希token,开始利用研究。

<1> 创建自己的Slack实例

利用过程的第一阶段就是创建我们自己的Slack实例。在创建Slack实例时,workspace名我设置的是目标企业的哈希token。完成该操作后,我使用Slack的邀请功能,邀请support@邮件到我的Slack实例,现在我的Slack实例已经加入邀请该邮箱的实例清单中。

<2> 查找实例

Slack有个非常优秀的功能(https://slack.com/signin/find),可以获取我们所属的、被邀请的、提供邮箱即可注册的所有Slack实例。一旦我们提交邮件,Slack会通过一封邮件告诉我们所有相关信息。在第一阶段,我们的实例已被当成受邀请的Slack组。当Slack发送我们可以访问的实例列表邮件时,会按照名称和URI列出待加入的实例,其中就包含超链接信息。由于我们的Slack实例位于清单中,因此也会被添加到该邮件列表中。注意到我们的实例名中包含ticket的哈希token,这意味着Slack发送给support@company.com的完整邮件现在已经被加入我的服务单(support ticket)中。

<3> 获取邮件

现在我们已经收到到Slack列表,我们还需要获取详细内容。目前这些信息已作为public comment嵌入ticket中,但与Zendesk不同的是,Help Scout并不会自动将内容发送到我的邮箱(攻击者邮箱)。此外,前面我在Help Scout概览中也提到过,Slack的邮件现在会被当成“原始”发送方,因为与该ticket对应的最近一封邮件来自于Slack的邮箱。因此为了确保为了能接收该ticket后续的邮件、看到之前的邮件内容,我需要确保我使用的攻击邮箱是“原始的”发送方。为了满足该条件,我回复目标系统发送的第一封邮件,随便写了些内容,然后继续等待。

<4> 利用漏洞

为了理解如何利用这个了流程,我们来看一下Slack邮件的一些概念。邮件清单可能如下所示:

在上图中有一个特殊的超链接:“Join”。这个超链接可以获取带有token的一个简单超链接,可以让我们直接注册。使用“Join”链接后,我们可以直接访问私有Slack,无需太多复杂的处理。

Slack在这类邮件中还包含一个“Launch”超链接。这是一次性魔术链接,可以让我们直接登录用户账户。只有当support@邮箱是Slack实例的注册用户时,才会出现这个超链接。与此同时,这个魔术链接还有一些限制条件:“Launch”链接只在24小时内有效。因此,如果目标agent没有在24小时内回复ticket,那么我们就无法利用这个魔术链接。某些公司允许任何用户使用@company邮箱来注册,因此我可以使用support+1@company.com邮箱,在面对某些Slack实例时绕过这种问题。

大家可以参考该视频了解利用Help Scout的完整操作过程。

 

二、经验总结

误解及合作

在研究支持系统时,我们经常可以看到大多数公司会使用这些系统,但却不是特别了解其中某些功能,也不知道攻击者会如何利用这些功能。在本文中我们使用的所有功能(Zendesk以及Help Scout中的ticket哈希)正是这些公司容易忽视的一些环节。在某些情况下,目标企业会询问我们是否利用了Zendesk中的0-day漏洞,因为我们竟然可以获取该系统上的许多敏感材料。在这种情况下,我们必须向这些企业解释这并非Zendesk的问题,并且需要给出官方资料来源,解释该系统为何采用这种工作方式。同样,由于有些人非常困惑且有所担忧,因此某些公司也联系了Zendesk,询问背后具体工作流程。为了确保所有人都能及时收到消息,我们还向Zendesk反馈了具体解释(通过HackerOne的支持团队),以便Zendesk了解我们的攻击方法。

从这个过程中,我发现我们需要耐心与目标公司配合,一起修复这个漏洞,这对我来说是非常特殊的一次体验,因为通常情况下我发现的是RCE、SSRF、IDOR等漏洞,并且我已经好久没有专门对第三方系统做过深入全面研究(上一次我研究的是Sendgrid以及Google的GSuite),感谢合作过程中保持耐心态度的这些企业。由于这对我们而言是一种新的攻击方式,我们也找到了利用该漏洞的多种方法,并且与目标企业保持联系,不断更新关于利用该漏洞访问关键内部资源的最新信息。在大多数情况下,所有公司都非常赞赏我们的工作,对我们给出的研究成果表示满意。有家公司还在报告发布后1小时内推出了补丁,并且专门召开安全团队参与的会议,进一步讨论这方面内容。我们还与另一家公司的工程师电话联系,讨论潜在的修复方式,以及这些方式存在的优缺点。

情况统计

我们测试了25家企业,发现20家存在该漏洞。在所有测试案例中,我们成功获得了某些内部资源访问权限,包括如下应用(已获得目标公司授权):

  • Slack
  • Asana
  • 内部域
  • Zoom
  • 通过Atlassian.net访问的JIRA & Confluence
  • 利用已注册的@company.com账户实现权限提升。
  • Zendesk内部支持页面,该页面只对内部员工开放,其中JIRA ticket包含某些API问题。
  • Dropbox

 

三、Zendesk修复措施

在目标企业通过邮件向Zendesk发送我们发现的漏洞报告后,Zendesk决定阻止no-reply@邮箱,直接将这些邮箱发送到垃圾邮件中,增加了这种技术的利用难度。但这并不意味着所有公司已得到安全保护,还有一些第三方服务会使用除no-reply@之外的邮箱来发送确认邮件,因此这些邮件还是会被添加到收件箱中。大家可以根据该线索寻找能够攻击的新系统。

 

四、Scout修复措施

Scout并没有专门为该问题发布大型补丁,因为这需要修改整个平台结构。目前我们建议大家添加一个邮件过滤器,阻止no-reply@邮件以及其他自动回复邮件(如验证邮件、忘记密码邮件等)。此外,运维人员也需要确保目标系统不回复可能有害(或者有趣)的邮箱,这也是可以采取的一种安全措施。

 

五、漏洞报告

大家可以访问此处阅读我们提交的一份漏洞报告。

(完)