扫码领资料
获网安教程
来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会触发自动邮件:
占位符的激活与抑制
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 的区别,我们在测试实例中创建了两个工单,并通过工单的主题字段调用了一个占位符。
Tickets API 端点请求
当我们向 Tickets API 端点发送请求时,发现占位符会被调用并自动填充到主题字段的值中。同时,工单的 raw_subject
字段仍会保留原始字符串。在我们的测试案例中,{{ current_user.email }}
被自动填充为经过身份验证用户的电子邮件地址。
请求 API 端点请求
相比之下,当我们向 Requests API 端点发送请求时,主题字段中的用户输入会被正确地清理。占位符未被调用,且花括号也被移除,以防止后续的二次注入攻击。
在确认 Tickets API 端点可以访问和调用 Zendesk 中的占位符后,我们进一步研究了可以访问的具体占位符及其可能的影响。
Zendesk 中的占位符
Zendesk 的占位符可以访问三个对象:user(用户)、ticket(工单)和 organization(组织)。这些对象类似于类,可通过不同的变量引用。此外,每个对象包含的字段/子字段可存储与工单相关的信息。
用户对象 (User Object)
用户对象包含与通过占位符请求的 Zendesk 用户相关的信息。Zendesk 用户包括代理人(agents)和在门户中拥有账户的终端用户(end-users)。用户对象包含以下可访问字段:
工单对象 (Ticket Object)
访问占位符
{{ ticket.id }}
- 当前工单的工单 ID{{ ticket.ccs }}
- 工单中所有被抄送用户的列表{{ ticket.comments }}
- 工单中所有评论(包括内部和外部)的列表{{ current_user.custom_fields }}
- 当前用户在执行工单操作时的自定义字段编程调用占位符
利用占位符
/hc/en-*
。路径中包含 /hc/en-
的支持门户通常是常规的 Zendesk 门户,而非自定义支持门户。案例研究:GitHub 的自定义支持门户
*{{ ticket.requester.email }}*
的初始工单。如果存在漏洞,这将创建一个工单,其主题标题会显示请求用户的邮箱地址。请求用户是 GitHub 上的账户 rojan-rijal
。在创建工单后,我们确认主题中确实反映了与 rojan-rijal
账户关联的个人邮箱地址。{{ current_user }}
对象,以识别在 Zendesk 中创建工单的具体用户。在这种情况下,该用户是 mutwin+ticketbot[]github[.]com
。通过返回的角色信息,我们还确认了该用户是一个管理员用户。ticket.ccs
字段获取与这些用户相关的具体信息。漏洞利用场景如下:{{ ticket.ccs[0].custom_fields }}
。这将创建一个工单,其主题包含关于该用户的所有存储自定义字段信息。漏洞利用结论
缓解建议
/v2/requests.json
API 端点替代 Tickets API。结论
声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权!
如果你是一个网络安全爱好者,欢迎加入我的知识星球:zk安全知识星球,我们一起进步一起学习。星球不定期会分享一些前沿漏洞,每周安全面试经验、SRC实战纪实等文章分享,微信识别二维码,即可加入。