跳到正文
Databricks Blog·· 2 小时前AI 评分29

Databricks 如何检测凭据驱动的攻击

Detecting credential-driven attacks on Databricks

AI 导读

Databricks 发布博客,说明如何利用 verbose audit logs 与 Genie 检测凭据驱动攻击中身份行为的偏移。攻击者用泄露的 session cookie、PAT 或 service-principal 凭据登录后,活动可归为六个阶段,事件按 service_name.action_name 记录,如 secrets.getSecret。

正文 · AI 翻译

在 Databricks,我们知道数据是您最宝贵的资产。Databricks 已与数千家客户合作,安全部署 Databricks Data + AI Platform,并配备适当的功能以满足其安全、隐私和监管要求。

现代网络攻击并不总是始于被攻破的边界;它始于一次合法的登录。一旦攻击者获取了泄露的会话 cookie、个人访问令牌(PAT)或服务主体凭据,初始入侵就已经完成。从那一刻起,他们的全部目标就是融入环境,并以被攻陷的用户或服务的身份进行操作。

但拥有钥匙并不意味着你熟悉这栋大楼。想象一名入侵者刷卡进入一间安全办公室。他们可能已经通过了旋转门,但仍需应对保安、猜测自己可以进入哪些楼层,并找出金库的位置。由于攻击者缺乏对您实际员工的深入、本地化了解,他们的行为最终会暴露自己。发现这些异常正是抓住他们的方法。

在本文中,我们将介绍凭据驱动的攻击在 Databricks 平台上如何展开、如何使用 Databricks 详细审计日志和 Genie 检测身份行为的转变、在确认入侵后如何响应,以及哪些控制措施能从源头上限制被盗凭据所能做的事情。

跟踪凭据驱动攻击的模型

与安全从业者一样,攻击者在通过合法凭据建立访问时也明白,一旦其行为过于偏离该身份的预期行为,其访问权限随时可能被撤销。攻击者依赖非线性的攻击顺序,例如先验证一组凭据以摸清您的环境,再获取另一组凭据,通过一个没有侦察活动关联的新身份或工作区返回。此外,攻击者可能在未建立持久化的情况下收集信息,或在完成目标之前先建立返回 Databricks 平台的途径。

实际中的表现

设想一名数据工程师的个人访问令牌从配置错误的持续集成与交付(CI/CD)日志中被复制。几分钟内,该令牌便从一个新 IP 被用于列出整个工作区中的密钥范围、目录和仓库,而这名工程师从未做过这些事。一个存放服务主体凭据的密钥被读取。一小时后,是该服务主体而非这名工程师创建了一个函数、将自己加入管理员组,并导出了少量 init 脚本。这些事件中的每一个都可能被视为常规的平台使用,但综合起来,它们显示了一次入侵正在沿攻击链推进。

在 Databricks,我们预期凭据驱动攻击会呈现非线性的事件顺序,并使用这一模型将单个事件关联为一次调查,而不是将它们视为互不相关的事件。

image4.png

凭据驱动攻击的六个阶段

当攻击者利用在平台即服务(PaaS)环境(例如 Databricks)中泄露的凭据时,他们的活动可以分为六个阶段,尽管他们很少按直线顺序推进。以下每个阶段描述了攻击者试图做什么,以及在 Databricks 审计日志表中应关注什么。请将此指南作为起点,并根据你环境中的正常自动化进行调整。

注意:事件写作 service_name.action_name,例如 secrets.getSecret。

1. 攻击者使用有效凭据获得访问权限

登录本身很少显得异常。由于凭据是真实的,身份验证会像合法所有者一样成功。然而,该身份在登录后几分钟内的行为往往与其正常活动大不相同,而这种变化正是响应人员可以检测到的。在数据工程师示例中,被盗令牌成功通过身份验证,登录时唯一的区别是工程师从未使用过的源 IP。随后的活动才是引人注目的。

攻击者目标:使用有效凭据访问工作区,无论是被盗的浏览器会话、重放的 PAT 还是服务主体凭据,并融入控制措施旨在允许的活动之中。

应关注什么:

  • 将身份验证事件作为时间线的起点。仅凭登录很少足以触发告警,但其 user_identity、source_ip_address, user_agent、sessionId、request_id 和 workspace_id 可让你追踪该凭据接下来的行为。
  • 标记在短时间内从陌生客户端突发到达、随后同一令牌从不同源 IP 被使用的 accounts.tokenLogin 事件。此模式可能表明有人正在测试被盗令牌,而 requestParams.tokenId 可让你将这些事件关联到同一令牌。
  • 标记从预期网络铸造但用户代理异常的服务主体 OAuth 令牌,尤其是当一分钟内出现来自新源 IP 的活动时。

2. 攻击者绘制环境地图

接下来,攻击者需要在访问权限被撤销之前了解该凭据可以触及什么。因此,被入侵的身份可能在几秒钟内从日常活动转向列出数据、机密、代码和网络控制。这种侦察通常同时跨越多个服务,并且比人工在 UI 中导航更快。在我们的场景中,此阶段是在令牌被使用后几分钟内爆发式调用列出机密范围、目录和仓库,这是该工程师从未执行过的活动。

攻击者目标:绘制可访问的数据、凭据、存储库和防护措施的地图,以便在访问权限被撤销之前规划深入环境的路径。

应关注什么:

  • 寻找单个身份在工作区平面和账户平面上进行快速列表调用,例如 secrets.listScopes / listSecrets、unityCatalog.listMetastores / listCatalogs / listSchemas / listExternalLocations / listStorageCredentials、repos.listRepos,以及账户级 accountsManager.listWorkspaceConfigurations / listNetworkConfigurations / listStorageConfigurations。例如,一分钟内调用五个或更多不同的发现 API 不太可能是人工在导航平台。
  • 将活动与该身份的基线进行比较。一个已建立的身份首次进行密钥枚举,或一个 SQL 会话从业务查询转向针对访问控制和配置架构的 SHOW TABLES,比大量调用更有意义。启用详细审计日志记录后,commandSubmit 会将查询保留在 commandText 中。
  • 在搜索中包含失败的请求。调查某个身份的首次 IpAccessDenied,尤其是当它紧随 accounts.oidcTokenAuthorization 之后或在多个工作区中重复出现时。在这种情况下,授权已成功,但请求来自被阻止的网络,这通常是从不受信任位置重放凭据的最早记录。

3. 攻击者获取更多凭据

获取凭据通常需要几个步骤。攻击者列出密钥范围,列出其中的密钥,然后读取看起来有用的那些。他们检索到的值使他们能够以另一个通常权限更高的身份返回。因此,可疑身份读取的每个密钥都值得跟进。在数据工程师示例中,攻击者读取了一个包含服务主体凭据的密钥。从那时起,调查必须跟踪两个身份:工程师和服务主体。

攻击者目标: 检索令牌、API 密钥或服务主体密钥,将初始立足点升级为在新身份下对整个环境的访问。

需要查找的内容:

  • 对调用的进展发出警报。secrets.listScopes 本身很常见并会产生噪声。然而,listScopes 后跟 listSecrets,然后是 getSecret,在多个范围中快速连续重复出现,表明正在收集。listSecrets 记录范围,getSecret 同时记录范围和密钥。
  • 将拒绝的读取与后来的成功读取关联起来。在严格控制的范围上被拒绝的 getSecret,随后在限制较少范围中成功读取相同或相关密钥,表明该身份正在寻找它可以访问的副本。
  • 除密钥 API 外,还要监控计算侧访问。启用详细审计日志记录后,笔记本 submitCommand 和 Databricks SQL commandSubmit 事件可以显示调用密钥实用程序或针对包含凭据的路径运行 read_files() 的代码。请记住,提交的文本显示运行了什么,但并不能确认返回了值。
  • 将每次密钥读取与接下来发生的事情联系起来,例如新的 accounts.tokenLogin、首次出现的服务主体活动、更改的 IP 或用户代理,或 generateTemporaryTableCredential / generateTemporaryVolumeCredential 调用。在响应期间,轮换该身份可能访问过的每个凭据,并检查每个凭据的使用位置以及存储位置。

4. 攻击者找到可行的执行路径

一旦建立访问权限,攻击者就会寻找运行自己代码的方法。在 Databricks 上,这通常通过用户定义函数(UDF)和作业来实现。函数可以将载荷包装在看似普通的代码中,从而可以被反复调用;而作业可以按计划在不同的计算资源上运行该代码。因此,检测的关键问题在于某个身份是否开始执行其此前从未执行过的操作。回到数据工程师的案例,在读取密钥一小时后,该服务主体创建了一个函数。由于执行此操作的是服务主体而非该工程师,仅针对该工程师活动范围的搜索会漏掉它。

攻击者目标:建立一种可靠、可复用的载荷执行方式,并在某条计算路径被阻断时拥有备用方案。

需要关注:

  • 优先关注来自没有创建函数历史的身份、IP 或目录的 createFunction 事件,尤其是短时间内出现多个此类事件时。在可获取函数定义的情况下,标记那些执行进程、动态求值代码、访问实例元数据、打开出站网络连接或写入云存储的代码。同时追踪函数之间的引用关系,因为看似无害的包装函数可能调用风险更高的 UDF。请注意,function_info 中的 system.access.audit 除账户管理员和 databricks_pii_access 外均被遮蔽,因此需将审计数据与函数清单配合使用。
  • 按身份、IP 以及作业或运行 ID 追踪 Jobs 路径。典型序列是 importNotebook,然后是 changeJobAcl、Jobs create、runNow 和 getRunOutput。这些事件很少保留 notebook 正文,因此需同时保留 notebook 版本和作业配置。来自同一来源的重复导入并运行活动,比单独任一操作都是更强的信号。
  • 寻找在失败后切换计算资源的身份。例如,集群创建失败或 submitRun 失败后不久出现 startWarehouse,或在不同计算资源上出现新作业,可能表明攻击者正在绕过被阻断的路径。响应代码和事件之间的短暂间隔,正是将这一序列与常规错误区分开来的关键。Serverless 计算是常见的备用方案。

5. 攻击者建立持久化

有了运行代码的方式后,攻击者接下来会设法确保在原始凭据被吊销后仍能返回。常见的持久化方法包括访问授权、新建令牌、组和工作区成员关系变更以及控制平面编辑。最有用的信号是由不熟悉的身份或执行上下文做出的敏感变更。例如,从作业内部发起的权限变更,比管理员在控制台中做出的相同变更更值得审查。在接下来的场景中,该服务主体将自己添加到管理员组。即使工程师的令牌被吊销,该组成员关系仍能维持攻击者的访问权限。

攻击者目标:创建持久、独立的访问路径,使其在受损凭据被吊销后仍能存活。

需要关注:

  • 对来自意外上下文的权限和身份授予发出告警,例如对密钥范围的 putAcl、updatePermissionAssignment、addPrincipalToGroup 或 setAdmin。尤其要注意服务主体向另一身份授予访问权限,或短时间内发生多次分配的情况。
  • 将试图更改安全控制的行为视为高严重性,即使这些尝试失败了。这包括 setSetting / deleteSetting、IP 访问列表编辑以及 createPrivateAccessSettings。在断定某个控制是否确实被绕过之前,请审查所请求的更改、响应以及来源。同时审查来自预期 IdP 之外的 SCIM 组更改。
  • 标记来自不熟悉来源或在作业运行期间发生的 generateDbToken 调用。每个生成的令牌都是单独的凭据,需要被撤销。
  • 留意会自行继续运行的工作负载。将控制平面事件与 run_by、run_as 以及预期的运行窗口相关联。如果某个作业在攻击者的交互活动停止后仍继续修改组、权限或设置,它可能正在自行维持访问。在终止该作业之前,保留作业定义和工件。

6. 攻击者收集数据并清理访问痕迹

数据收集可能只是少量有针对性的导出,而清理可能不仅仅是删除文件。留意有针对性的导出、临时凭据请求、短生命周期工具的移除,以及使活动更难被还原的混淆命令。其中任何单个事件都可能看起来是常规操作,因此它们前后的序列比单个导出或删除更重要。最后,我们场景中的服务主体导出了少量 init 脚本。单看这是一次小规模导出。然而,由于它发生在同一服务主体的机密读取和新函数创建之后,应将其作为同一次入侵的一部分进行调查。

攻击者目标: 获取重要数据并抹除最明显的工具痕迹,同时保留更隐蔽的访问途径。

需要关注的内容:

  • 关注每次导出的上下文,而不是导出的数量。workspaceExport 记录了路径、格式以及是否为直接下载。优先关注由不熟悉身份发起的、导出到异常路径或使用异常格式的、来自此前未见网络的,或发生在机密访问或新执行之后的导出。少量有针对性的 init 脚本导出可能泄露的信息比一次批量 SOURCE 转储更多。
  • 保留短生命周期对象的记录。在同一会话中对同一函数先 createFunction 后 deleteFunction,或反复进行创建、删除和重新创建的循环,可能表明试图清除证据。在还原任何内容之前,保留定义和时间信息。存活下来的对象通常比被删除的对象被赋予更合理的名称。
  • 将临时凭据和数据读取的突发活动(generateTemporaryTableCredential、generateTemporaryVolumeCredential、Delta Sharing、云存储读取)与先前的侦察活动关联起来。编码或脚本化命令本身过于常见,不足以单独触发告警,因此应将其与不熟悉的用户代理、类似自动化的时间模式、机密访问或新函数相关联。

使用 Genie 调查凭据驱动的攻击

以凭据驱动的攻击链为指引,你可以让 Genie 逐步推进攻击阶段,而无需从头编写每个查询。本文中的每个检测都运行在你已有的遥测数据上。Databricks 将控制平面活动写入 system.access.audit 系统表。

要开始使用,请安装 Detection App,它为 Databricks 的审计日志添加了一个 Genie agent。你可以通过两种方式在 Genie One 中使用它:

  • 用你自己的话提问,比如“user@example.com 昨天导出了哪些 notebook?”Genie 会为你编写并运行 SQL。
  • 使用内置检测。Detection App Genie agent 包含 30 多种检测,涵盖从 token 滥用到管理员授权。问“上周谁创建了个人访问令牌?”,Genie 会运行匹配的检测,而不是编写新的 SQL。给它一个目标,比如“过去 90 天我们是否被入侵?”,它会逐一执行这些检测。

请记住两个限制。第一,空结果并不意味着什么都没发生。事件可能在你设定的时间窗口之外,或者详细审计日志可能已被禁用。第二,审计日志记录了什么发生了变化以及是谁更改的,但通常不记录旧值或新值。

从检测到响应

一旦狩猎发现某个身份不符合其正常模式,焦点就转向攻击者仍然拥有哪些访问权限。由于凭据驱动的攻击是非线性的,你发现的第一个访问权限很少是唯一的访问权限。在数据工程师示例中,撤销该工程师的 token 会留下服务主体的凭据、其管理员组成员身份以及它创建的函数。完整的响应会移除原始凭据以及攻击者之后创建的每一条路径,包括授权、token、函数以及在用户被禁用后仍在运行的作业。

对于疑似工作区入侵,响应人员应:

  1. 禁用该身份。在账户级别停用该用户,这会阻止所有工作区。没有 API 可以结束用户的浏览器会话,但停用会阻止它们。对于服务主体,删除其 OAuth 密钥并通过账户 SCIM API停用它。服务主体已持有的 OAuth token 最长可保持有效一小时。
  2. 撤销其个人访问令牌。停用用户不会删除其 token,如果用户被重新激活,这些 token 会再次生效。使用Token Management API 或账户控制台中的 token 报告。
  3. 保存你需要的内容,然后停止计算。首先导出作业定义和 notebook 版本。然后取消作业运行、终止集群并停止 SQL 仓库。在无服务器环境中,取消运行或语句。停用用户不会停止已在运行的计算。
  4. 轮换该行为者读取过的每一个密钥。在源头更改它,然后更新存储的值。同时轮换攻击者用于进入的凭据。
  5. 撤销行为者创建的持久化机制。移除密钥范围 ACL、工作区分配和组成员身份。删除函数并撤销授权。从你自己的记录中恢复基于上下文的入口策略(以及 IP 访问列表,如果你仍在使用)。
  6. 检查该身份可以在 Databricks 之外更改的代码,例如云存储中的 init 脚本和 ETL 代码。
  7. 确认它已停止。对该行为者的活动运行搜索。如果详细审计日志已关闭,请将其打开。命令文本仅在开启时才会被记录。

防范凭据驱动的攻击

回到办公楼这个比喻:基于上下文的入口控制决定谁能通过旋转门,而最小权限决定他们的工牌能打开哪些楼层。早期检测能争取响应时间,但预防性控制能限制被盗凭证能做什么。下面的控制措施按它们从对手那里夺走的东西分组,大致按照它们打断攻击链的顺序排列。

image3.png

把被盗凭证挡在门外

针对凭证复用最强的预防性控制是基于上下文的入口控制。它评估是谁在发起请求、请求来自哪里、请求的目的是什么,而不是依赖单一的网络边界。随着越来越多的组织不再使用 VPN,这一点尤其有用。即使没有可依托的企业网络,你也可以把被盗令牌限制在其所有者实际使用的上下文中。例如,你可以将特权服务主体限制为仅接受来自受信网络的 API 请求,同时对人类用户应用不同的策略。

  • 对工作区和账户请求都应用策略。工作区策略不覆盖账户控制台或账户级 API。
  • 从试运行模式开始。在system.access.inbound_network中查看拒绝和试运行违规记录,优先保护特权服务主体,并在考虑了合法的自动化和合作伙伴集成之后再强制执行。
  • 在广泛强制执行之前测试无服务器和私有连接工作流,因为它们遵循单独的策略规则。记录任何例外并监控其使用情况。
  • 将 IP 访问列表视为额外的一层。在两者都适用的情况下,请求必须同时通过两者。如果你仍在使用工作区和账户控制台列表,请配置它们。

让窃取到的凭证价值更低

  • 为服务主体凭证、集成凭证和个人访问令牌设置过期和轮换要求,并停用不再使用的凭证。休眠凭证对对手尤其有吸引力,因为一旦被攻破,可能数月都无人察觉。
  • 在密钥范围上强制执行最小权限。避免在具有不同 ACL 的范围中存储高权限凭证的副本,并审查谁可以列出范围内容以及谁可以检索值。

限制凭证可以运行或更改的内容

  • 限制高影响操作。将 UDF 创建、密钥范围 ACL 更改、工作区权限更改、作业管理和入口策略更改限制为经批准的身份和受控自动化。
  • 将管理路径与计算路径分离。普通作业运行时不应能够修改账户和网络控制,任何此类尝试都应生成警报。
  • 保护云执行环境。在适用的情况下使用强化的元数据服务配置,并限制计算资源的出站流量,使工作负载无法自由访问凭证端点或未经批准的目的地。
  • 限制哪些身份可以管理账户身份、分配工作区访问权限和创建作业。

保留证据

  • 为潜在的安全入侵保留可供调查的遥测数据。
  • 保留审计日志、笔记本和作业版本历史、UDF 定义和依赖项、权限更改历史、云存储写入事件以及基于上下文的入口拒绝日志,保留时间足以重建一次攻击活动。

请记住,被盗凭证的爆炸半径取决于分配给它的权限。通过采取以下步骤来减少这种暴露,并能够猎捕异常活动:

来源:Databricks Blog · databricks.com