滥用工单系统中的动态占位符泄露用户数据

文化   2024-12-17 12:01   韩国  

扫码领资料

获网安教程


Track安全社区投稿~  

赢千元稿费!还有保底奖励~(https://bbs.zkaq.cn)

概要

我们发现,许多公司在通用支持系统(如Zendesk)上构建了定制支持门户。在此过程中,这些公司错误配置了API集成,使我们能够滥用占位符这一常见功能来提取敏感用户信息。滥用这一漏洞,攻击者可以通过占位符提取诸如账单信息、购买元数据、内部备注、明文密码(如果可能)等敏感信息。

注意:这些滥用/利用案例并非由于Zendesk的漏洞。受影响的组织通过切换到正确的API端点并进一步清理用户输入,自行修复了这一漏洞。


定制支持门户与公司

企业构建定制客户支持门户是一种常见做法。定制门户允许企业实施自己的身份验证方式(如OAuth),以获取用户的相关信息。例如,用户通过公司的主应用程序身份验证进入支持门户后,可共享其账户信息,从而让客户支持人员更轻松地与之交互。然而,从零开始设计客户支持门户非常困难,因此Zendesk、Freshdesk等公司提供了相应的解决方案。

在调查中,我们注意到大多数定制支持门户通过API集成使用了现成产品(如Zendesk)。因此,尽管定制门户有自己的身份验证和授权机制,创建的案例仍会发送到公司的内部Zendesk门户。

这种方式有效地实现了:1)提供企业特定的身份验证, 2)将用户案例存储在多个地方,而非单一存储。

但创建定制应用程序也会引入常见的OWASP安全风险和业务逻辑漏洞,而这些问题在Zendesk等产品中已有内置缓解措施。不仅是OWASP漏洞,使用API集成作为“后端”来存储、提取和处理用户输入,还可能因API误用、文档不足等原因引入漏洞。例如,我们的研究发现,许多使用Zendesk作为案例存储的定制支持门户存在API集成错误配置。这使我们能够专门滥用Zendesk的一个功能——占位符,来提取其他用户的信息。


什么是占位符?

占位符是泛指的术语或词语,稍后会被替换为实际信息。支持系统的占位符类似于此。例如,用户请求的信息会根据请求返回相关工单数据。因此,占位符可以请求信息,例如案例创建者的信息、处理该案例的代理、案例状态,以及与案例相关联的(次要)用户信息。

占位符的设计方式多种多样,具体取决于产品本身。本篇博客将探讨Zendesk的占位符设计及其一个利用案例研究。


Zendesk与占位符

Zendesk提供了内置的占位符支持,允许代理和自动邮件系统在响应案例时自动填充用户信息。一个典型的例子是,当创建一个案例时,Zendesk会触发自动邮件:

img

占位符的激活与抑制

Zendesk 内置了占位符的抑制与激活规则,用于配置何时可以使用占位符。当占位符抑制规则生效时,占位符会被视为普通字符串;而当抑制规则失效时,占位符则会返回相应的值。在 Zendesk 中,占位符会在以下三种特定场景中激活:

代理响应 当代理通过门户回复时,可以调用占位符以自动填充所需信息。

管理员 API 端点 Zendesk 内置了自动化和邮件触发器(如上述提到的触发器),这些触发器会调用占位符。这在需要获取当前用户或工单信息以响应工单时显得非常合理。

自动化与邮件触发器/处理程序 通过管理员 API 进行的特定 API 调用可以触发占位符,以自动填充所需的用户信息。这与代理响应类似,因为管理员 API 端点通常被代理、内部机器人或管理员用于对工单执行操作。


Zendesk API 端点

Zendesk 提供了两种不同的 API 端点:Requests API 和 Tickets API。我们的研究发现,大多数定制门户使用的是 Tickets API,而非 Requests API。这引起了我们的担忧,因为 Tickets API 端点(/v2/tickets.json)是管理员 API 端点,必须使用代理或管理员会话密钥进行身份验证。如前所述,管理员 API 端点可以调用占位符。

为了验证管理员 API 和 Requests API 的区别,我们在测试实例中创建了两个工单,并通过工单的主题字段调用了一个占位符。

img

Tickets API 端点请求

当我们向 Tickets API 端点发送请求时,发现占位符会被调用并自动填充到主题字段的值中。同时,工单的 raw_subject 字段仍会保留原始字符串。在我们的测试案例中,{{ current_user.email }} 被自动填充为经过身份验证用户的电子邮件地址。

img

请求 API 端点请求

相比之下,当我们向 Requests API 端点发送请求时,主题字段中的用户输入会被正确地清理。占位符未被调用,且花括号也被移除,以防止后续的二次注入攻击。

在确认 Tickets API 端点可以访问和调用 Zendesk 中的占位符后,我们进一步研究了可以访问的具体占位符及其可能的影响。


Zendesk 中的占位符

Zendesk 的占位符可以访问三个对象:user(用户)、ticket(工单)和 organization(组织)。这些对象类似于类,可通过不同的变量引用。此外,每个对象包含的字段/子字段可存储与工单相关的信息。


用户对象 (User Object)

用户对象包含与通过占位符请求的 Zendesk 用户相关的信息。Zendesk 用户包括代理人(agents)和在门户中拥有账户的终端用户(end-users)。用户对象包含以下可访问字段:

    名(First Name)
    姓(Last Name)
    电子邮件(Email)
    电话(Phone)
    备注(Notes)
    自定义字段(Custom Fields)
在所有可访问字段中,有两个字段对我们尤为重要:custom_fields(自定义字段)和 notes(备注)。
自定义字段 是根据具体组织定义的字段,存储帮助客户支持代理的信息。例如:
一个电商应用可能会在自定义字段中存储用户最近的订单 ID、账单地址和账户编号。
一个电信公司可能会存储用户的账户编号、账户中电话号码的数量以及最近的账单日期。
备注 是一个字符串数组,其中包含有关用户账户的备注。这些备注通常由支持代理添加,用于未来参考或更好地解释客户的状态。例如,某公司 A 的企业客户可能会有特定的备注,记录在支持门户中,以便代理在将来帮助他们解决问题时参考。

工单对象 (Ticket Object)

工单对象包含通过占位符请求的 Zendesk 工单相关的信息。工单对象包含以下可访问字段:
    工单 ID (Ticket ID)
    抄送名称 (CC Names)
    抄送列表 (CCs)
    评论 (Comments)
    请求者 (Requester)
在所有可访问字段中,ccs 字段对我们尤为重要。
ccs 字段 类似于 cc_names 字段,因为它们都存储与工单上添加的次要用户(secondary users)相关的信息。在 Zendesk 中,终端用户可以将其他用户抄送到工单中。这允许被抄送的用户查看并回复该工单。
cc_names 字段 是一个字符串数组,包含被抄送用户的名字和姓氏。如果被抄送用户未注册,则会包含抄送到工单的电子邮件地址。
ccs 字段 是一个用户对象数组,包含被抄送到工单的用户信息。例如,如果一个电子邮件地址被抄送到工单,并且该地址关联到一个有效用户,则该用户信息会通过ccs字段链接。
由于 ccs 字段中的每个值都链接到一个用户对象,这使得调用特定用户字段(如 custom_fields和 notes)成为可能。

访问占位符

Zendesk 使用 Shopify 的 Liquid 模板语言来实现占位符功能。这使得在某些情况下,能够更轻松地编程调用占位符以访问特定信息。以下是一些调用占位符的示例:
{{ ticket.id }} - 当前工单的工单 ID
{{ ticket.ccs }} - 工单中所有被抄送用户的列表
{{ ticket.comments }} - 工单中所有评论(包括内部和外部)的列表
{{ current_user.custom_fields }} - 当前用户在执行工单操作时的自定义字段

编程调用占位符

由于某些占位符包含数组和对象,可以使用 Liquid 的 for 循环来清理返回的信息。例如,如果需要获取 ticket.ccs 占位符中第一个用户的信息,可以使用一个简单的 for 循环来实现。

利用占位符

在对 Zendesk 占位符有了较高层次的理解后,我们开始测试那些使用 Zendesk 作为后端的自定义门户中可能存在的漏洞。为了识别这类系统,我们通过内部资产跟踪工具寻找特定模式:
客户支持门户路径中没有 /hc/en-*。路径中包含 /hc/en- 的支持门户通常是常规的 Zendesk 门户,而非自定义支持门户。
在成功创建工单后,我们会收到带有 Zendesk 线程令牌(thread-token)格式的确认电子邮件。Zendesk 的线程令牌允许将电子邮件回复链接到特定的工单。
第一个存在漏洞的系统案例,即我们的“零号病人”,是 GitHub 的自定义支持门户。

案例研究:GitHub 的自定义支持门户

GitHub 最近从使用原生 Zendesk 门户迁移到了其自定义支持门户,地址为 https://support.github.com。该自定义门户允许用户为其所属组织创建支持工单,同时也支持为其个人账户创建工单。
img
为了识别 GitHub 在后端的具体实现,我们下载了 GitHub Enterprise Server (GHES)。GHES 与 github.com 共享大部分代码库,除了那些尚未公开测试的 beta 功能。通过审查代码库,我们注意到 GitHub 调用了 Tickets API 端点,而不是 Requests API 端点。
随后,我们进行了系列测试,以验证并利用这一漏洞。
img
为了确认漏洞,我们创建了一个包含 *{{ ticket.requester.email }}* 的初始工单。如果存在漏洞,这将创建一个工单,其主题标题会显示请求用户的邮箱地址。请求用户是 GitHub 上的账户 rojan-rijal。在创建工单后,我们确认主题中确实反映了与 rojan-rijal 账户关联的个人邮箱地址。
随后,我们提取了 {{ current_user }} 对象,以识别在 Zendesk 中创建工单的具体用户。在这种情况下,该用户是 mutwin+ticketbot[]github[.]com。通过返回的角色信息,我们还确认了该用户是一个管理员用户。
img
在测试过程中,我们注意到 GitHub 的支持门户允许添加次级用户。通过将其他用户加入工单的 CC 列表,我们可以通过 ticket.ccs 字段获取与这些用户相关的具体信息。漏洞利用场景如下:
将目标用户添加为工单的 CC 用户。
在工单主题中使用 {{ ticket.ccs[0].custom_fields }}。这将创建一个工单,其主题包含关于该用户的所有存储自定义字段信息。

漏洞利用结论

在测试结束时,我们发现多家公司存在这种注入漏洞。这种漏洞允许提取以下信息:
其他用户的账单信息,包括但不限于地址、邮箱和电话号码。
支持代理在用户账户中的内部备注,以及硬编码在代理内部备注中的明文密码。
支持代理的工作状态和分配的工作地点(城市和国家)。

缓解建议

为缓解类似漏洞,可以采取以下措施:
在可能的情况下,使用 /v2/requests.json API 端点替代 Tickets API。
如果必须使用 Tickets API,应对用户输入进行过滤,防止在支持工单中使用类似占位符的字符串。

结论

Zendesk 并不是唯一被公司用作后台的支持系统。我们还注意到像 Salesforce 的 Service Cloud 系统的使用量有所增加。该系统也存在某些需要警惕的可利用条件。

声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权

如果你是一个网络安全爱好者,欢迎加入我的知识星球:zk安全知识星球,我们一起进步一起学习。星球不定期会分享一些前沿漏洞,每周安全面试经验、SRC实战纪实等文章分享,微信识别二维码,即可加入。

白帽子左一
零基础也能学渗透!关注我,跟我一启开启渗透测试工程师成长计划.专注分享网络安全知识技能.
 最新文章