当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 从用户聊天构建 Teams 外部访问允许列表

作者:精品下载站 日期:2024-12-14 04:11:28 浏览:13 分类:玩电脑

从用户聊天构建 Teams 外部访问允许列表


安全团队外部访问意味着限制与已知域的通信

2022 年 9 月,一名安全研究人员演示了 Teams 聊天中的外部参与者如何发送包含感染收件人 PC 的恶意软件的修改后的 GIF。默认情况下,Teams 允许用户与任何其他 Microsoft 365 租户中的任何人聊天。针对 GIFShell 漏洞的解决方案是将 Teams 的外部访问限制为已知租户的允许列表(白名单)。

那么问题就变成了如何填充允许列表。当时,我建议组织可以首先建立访客帐户来自的域列表。使用 PowerShell 查找所有来宾帐户、提取其域并使用该信息构建允许列表并不困难,该列表足以容纳大约 4,000 个域。

工作完成了,至少我是这么想的。然而,其他人认为使用来宾域作为允许列表的基础还不够好。无法保证从来宾帐户派生的域集将覆盖外部聊天参与者可能来自的每个可能的域。因此,需要进行一些安排以允许人们请求将域添加到允许列表中。这降低了跨组织基于聊天的协作的自发性,但这可能是安全通信所需的代价。

然后有人认为可以检查组织中的所有外部聊天,以发现外部聊天参与者所属的域集。听起来不错,但是如何查找并处理用户聊天中的信息呢?这就是我在本文中解释的内容。

访问聊天参与者是 Teams 外部访问的关键

在另一篇文章中,我解释了使用 Microsoft Graph PowerShell SDK 查找和处理 Teams 聊天和聊天消息的基础知识。该文章中剖析的 PowerShell 脚本允许管理员从群聊中删除可能令人反感或包含敏感信息的消息。这里需要的脚本也必须找到聊天,但是是一对一聊天而不是群聊。使用 Get-MgUser cmdlet 查找用户帐户列表后,我们可以使用不同的过滤器与 Get-MgBetaUserChat cmdlet 来查找一对一聊天每个用户。

每个聊天都有一个参与者列表,可以使用 Get-MgChatMember cmdlet 获取该列表。其中一个参与者是租户帐户,另一个可能是外部参与者。要构建外部域列表,脚本需要检查每个聊天的参与者并查找涉及外部参与者的参与者。利用该数据,脚本可以构建域列表。至少,理论上是这样。

定义解决方案

解决方案的轮廓很清楚。然而,细节决定成败,这里有一些重要的细节需要考虑。

首先,脚本必须使用应用程序权限来访问用户聊天。这对于之前的脚本来说不是问题,因为我使用了带有托管标识的 Azure 自动化 Runbook 进行身份验证。必要的图形权限已分配给 Azure 自动化帐户。

在这种情况下,我想使用 Microsoft Teams 模块中的 Get-CsTenantFederationConfiguration cmdlet 来获取有关租户外部访问配置的详细信息。 Teams 从 Skype for Business Online 继承的策略管理 cmdlet 不支持托管标识(其他 Teams cmdlet 则支持,因为它们是基于图形的)。通过利用 Azure Key Vault 存储帐户凭据并使用这些凭据连接到 Teams,我可以解决该问题并仍然使用 Azure 自动化。最后,我决定采用不同的方法并使用基于证书的身份验证,因为所有 cmdlet 都支持这种方法。

由于该脚本使用基于证书的身份验证,因此它需要注册的 Entra ID 应用程序来存储证书并持有访问脚本所需数据所需的 Graph 权限:

  • CrossTenantInformation.ReadBasic.All:读取租户标识符并返回租户显示名称。
  • User.Read.All:读取用户帐户信息。
  • Chat.Read.All:读取用户聊天记录。
  • Directory.Read.All:从目录中读取主租户信息。
  • Mail.Send:发送包含结果的电子邮件。

此外,由于脚本运行 Teams 策略管理 cmdlet,因此应用程序必须拥有 Teams 管理员角色。这并不困难,因为使用 Entra ID 管理中心可以轻松完成角色分配,但它是使一切正常运行所需的详细信息的示例。

本文概述的步骤描述了如何创建自签名证书(足以用于测试)并将其上传到已注册的应用程序(图 1)。

[玩转系统] 从用户聊天构建 Teams 外部访问允许列表

本文还介绍了如何使用 PowerShell 将 Entra ID 管理角色分配给应用程序,代码如下:

$TeamsAppSp = (Get-MgServicePrincipal -Filter "DisplayName eq ‘PowerShellGraph'").Id
$TeamsRoleId = (Get-MgDirectoryRole | Where-Object {$_.DisplayName -eq "Teams Administrator"}).Id
$NewAssignee = @{
  "@odata.id" = ("https://graph.microsoft.com/v1.0/directoryObjects/{0}" -f $TeamsAppSp)
  }
New-MgDirectoryRoleMemberByRef -DirectoryRoleId $TeamsRoleId -BodyParameter $NewAssignee

为应用程序分配必要的权限和角色以及适当的证书后,我们可以编写一些代码。

编写解决方案脚本

脚本中的步骤是:

  • 使用基于证书的身份验证连接到 Microsoft Graph 终结点。您需要注册应用程序的客户端标识符、租户标识符和证书指纹才能连接。
  • 使用基于证书的身份验证连接到 Teams 终结点。 Get-CsTenantFederationConfiguration 是 Teams 模块中使用的唯一 cmdlet。所有其他 cmdlet 来自 Microsoft Graph PowerShell SDK。
  • 查找租户的注册域集。此信息用于确定一对一聊天是否与租户内部或外部的人员进行。
  • 获取租户中的许可用户帐户集。这可以包括具有许可证的共享邮箱,但这是查找使用 Teams 的帐户集的最简单、最快的方法。
  • 对于每个用户,找到他们的一对一聊天集。每个用户之间会施加短暂的延迟,以避免 Microsoft 365 限制。
  • 对于每个聊天,检索参与者列表并从列表中删除正在处理的用户。由于这些是一对一的聊天,因此只能留下一名其他参与者。
  • 查找其他参与者的域名,以确定聊天是内部聊天还是外部聊天。
  • 如果是外部的,请使用租户标识符解析租户域。
  • 如果聊天由家庭租户主持,则检索聊天中的消息数。您无法检索外部租户托管的聊天的此信息。
  • 记录发现的内容并返回处理下一次聊天。
  • 处理所有用户的聊天后,检查 Teams 外部访问配置,并将其允许列表中的域与用于外部聊天的域进行比较。报告用于外部聊天但不在允许列表中的任何域。
  • 将结果通过电子邮件发送给预定收件人。结果是外部聊天的详细信息和有关外部域的信息。
  • 宣告成功。

图 2 显示了脚本发送的电子邮件的示例。每条记录的属性集在脚本中定义,但不包括报告中捕获的所有属性。不进行数据过滤。例如,您可能决定专注于过去两年内发起的与外部参与者的聊天,而忽略较早的聊天。

[玩转系统] 从用户聊天构建 Teams 外部访问允许列表

运行脚本

您可以从 GitHub 下载该脚本。请记住,此脚本可以工作,但其目的只是演示使用 Graph SDK 获取和处理有关 Teams 聊天及其参与者的信息的原理。它并不是一个现成的解决方案,而且我还没有以真正的规模运行它。鉴于需要获取处理的每个用户的所有一对一聊天,该脚本的速度并不快。您可能希望首先为一组有限的用户运行它。如果是这样,请将过滤器应用于从 Entra ID 获取的用户集。例如,要将集合限制为来自特定部门的用户,您可以将 Get-MgUser 调用修改为如下所示:

[array]$Users = Get-MgUser -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member' and department eq 'IT'" -ConsistencyLevel eventual -CountVariable Records -All | Sort-Object displayName

在尝试运行脚本之前,请确保满足所有先决条件,并且使用分配了必要的 Teams 管理员角色和图形权限的注册应用程序。

根据数据做出决策

此练习很好地说明了当需要从 Microsoft 365 中提取信息时 Microsoft Graph PowerShell SDK 的有用性。如果无法访问用户聊天,就不可能知道人们正在与租户之外的谁进行交谈。 Graph SDK 公开了他们的秘密,并帮助管理员根据数据而不是直觉做出更好的决策,这总是一件好事。

Microsoft 平台迁移规划和整合

简化迁移规划,克服迁移挑战,更快地完成项目,同时最大限度地降低成本、风险和对用户的干扰。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯