使用PowerShell和SOF-ELK处理M365统一审计日志(第一部分)

本文详细介绍了如何利用PowerShell的Exchange Online管理模块和SOF-ELK平台来获取、解析和查询Microsoft 365的统一审计日志(UAL),以支持安全审计和事件调查工作。

使用PowerShell和SOF-ELK处理M365统一审计日志(第一部分)

在M365审计和调查中,“统一审计日志”(UAL)是你的得力助手。它可能有些难以驾驭、固执且功能有限,但仍然是你的朋友。遗憾的是,根据许可和保留策略,有时它可能是你唯一的朋友。无论你需要进行何种类型的审计或调查,UAL的挑战都集中在三个方面:获取数据、解析输出以及查询数据以回答审计和调查问题。在本文中,我们将逐步介绍一种方法,利用Exchange Online Management PowerShell模块和“安全操作与取证Elasticsearch、Logstash、Kibana”(SOF-ELK)来克服所有这三个挑战。

在处理之前,值得一问:“UAL是否包含你要查找的数据?”由于UAL结合了来自多个M365服务(即“工作负载”)的数据,直接访问服务日志可能更高效,而且在某些情况下,你需要的细节可能实际上不会填充到UAL中。你可以在这里查看每个服务捕获的UAL属性:详细属性在审计日志中 – Microsoft Purview(合规性)| Microsoft Learn

还值得注意的是,M365生态系统在不断变化,许可可能复杂、令人困惑,并直接影响UAL的保留和属性。这是一个独立的“处理”话题,但从战术上讲,基于对UAL可以且应该包含的内容的基本理解,我通常会采样租户的数据以查看可用的内容并确定保留情况,而不是纠结于E3与E5以及Azure P1与Entra Identity P2等。回顾起来,回到许可级别、属性可用性和保留问题作为“经验教训”机会可能是有价值的,特别是如果你无法基于当前M365租户配置回答审计/调查问题。

一旦我们确定在审计/调查场景中UAL确实是我们的朋友,就该卷起袖子、穿上靴子和必备的帽子,开始处理了!首先,我们需要获取UAL数据。有几种不同的方法可以实现这一点,即“合规门户”(又名Purview)、Office 365 API和Exchange Online PowerShell模块(EXO)。我更喜欢后者,因为它具有内联过滤功能、一些绕过最大返回记录限制的变通方法,以及灵活的输出格式,特别是当我们着眼于通过SOF-ELK进行解析和查询的下一步时。

在撰写本文时,EXO的当前版本是3.2.0,需要PowerShell 7。你可以选择自己的安装方式和位置,但我从一个全新的Windows 2022 Server Base AWS EC2实例(t2.medium)开始,下载PowerShell 7.x,并安装EXO模块:

1
2
3
4
5
#下载并安装PowerShell 7.x.x - msi
iex "& { $(irm https://aka.ms/install-powershell.ps1) } -UseMSI -Quiet"
#从PowerShell v7(pwsh)运行 - 安装exchangeonline管理和graph api...耐心等待...需要几分钟,由于使用pwsh - 没有进度指示器
& "C:\Program Files\PowerShell\7\pwsh.exe" -Command Install-Module -name exchangeonlinemanagement -repository psgallery -force
& "C:\Program Files\PowerShell\7\pwsh.exe" -Command Install-Module -name microsoft.graph -scope allusers -repository psgallery -force

安装PowerShell 7和EXO管理模块

如果一切顺利,你可以通过键入“pwsh”并按Enter从PowerShell 5启动PowerShell 7!你可能需要终止并重新启动PowerShell 5会话才能识别该命令。如果你执行“Get-InstalledModule -Name Exchange*”,你应该看到ExchangeOnlineManagement 3.2.0,如下所示:

1
Get-InstalledModule -Name Exchange*

启动PowerShell 7并确认EXO管理模块

由于UAL可能非常庞大,即使在小的M365租户中,明智的做法是在获取时保持谨慎。幸运的是,在审计/调查开始时,我们通常有一个或多个目标账户以及相关的日期范围,这就是我们的起点。

首先,我们将使用PowerShell 7中的“Connect-ExchangeOnline”命令进行连接。你应该会收到一个现代身份验证弹出浏览器窗口,在那里你将使用具有足够权限(查看此)和MFA的账户按常规方式向M365进行身份验证。你正在使用MFA,对吧?对吧!?当然你在使用,因为没有它处理是不安全的!

通过EXO连接和身份验证

连接后,我们将进行快速测试以验证一切正常。记住,选项卡完成是你的朋友!开始键入“Search-Un”并按Tab键。如果你没有获得“Search-UnifiedAuditLog”的自动完成,那么你可能缺少所需的权限(查看此)。为了采样数据访问/输出,让我们运行以下命令,“Search-UnifiedAuditLog -StartDate 7/15/2023 -EndDate 7/20/2023 -UserIds target-user@yourdomain.com -ResultSize 1”,适当地更改斜体部分。你应该看到类似于下面图像的输出。注意,有几个离散的命名字段和AuditData JSON blob:

1
Search-UnifiedAuditLog -StartDate 7/15/2023 -EndDate 7/20/2023 -UserIds target-user@yourdomain.com -ResultSize 1

单个UAL记录搜索

最终,我们希望为目标用户/用户组提取日期范围内的所有UAL数据,通常是全部可用数据(365天),但我们也可能希望进行一些搜索或过滤以指导或缩小我们的UAL导出范围。例如,我们可能希望搜索特定操作或提取AuditData的一些关键组件进行审查。在我们的初始测试搜索中,我们看到一个名为“PC”的高度可疑字符执行了“Remove delegated permission grant”操作,这可能会让我们想知道相关的所述权限授予的添加。如果我们运行“Search-UnifiedAuditLog -StartDate 1/1/2023 -EndDate 7/1/2023 -Operations “Add delegated permission grant” -ResultSize 1”,也许我们可以找到答案!注意结果大小限制为了简洁,并且我没有指定UserId。根据需要调整任一:

1
Search-UnifiedAuditLog -StartDate 1/1/2023 -EndDate 7/1/2023 -Operations Add delegated permission grant -ResultSize 1

UAL操作过滤

也许“PC”不应该有Microsoft Graph权限,你注意到AuditData中的用户代理看起来像Windows上的Edge,这似乎可疑/异常。在你的租户中是否有任何其他使用此用户代理的审计操作?让我们尝试运行“Search-UnifiedAuditLog -StartDate 1/1/2023 -EndDate 7/20/2023 -ResultSize 1 | Select-Object -ExpandProperty AuditData | ConvertFrom-Json | Where-Object ExtendedProperties -like “Mozilla” | Select-Object workload,userid,extendedproperties”:

1
Search-UnifiedAuditLog -StartDate 1/1/2023 -EndDate 7/20/2023 -ResultSize 1 | Select-Object -ExpandProperty AuditData | ConvertFrom-Json | Where-Object ExtendedProperties -like *Mozilla* | Select-Object workload,userid,extendedproperties

按用户代理“关键词”过滤UAL

好消息是它工作了!坏消息是它繁琐且不可扩展,这引出了UAL解析和查询的挑战。你可以导出到CSV,但AuditData转换为单个字段。你可以使用Excel并从JSON转换,这简单、快速且 moderately useful,但你仍然会得到截断的列表条目,并在大型数据集上遇到扩展限制。该怎么办?请鼓声…引入…SOF-ELK。(感谢Phil Hagen和团队!)

UAL解析和查询解决方案

从Windows EC2实例SSH到SOF-ELK

接下来,我们将返回到我们的PowerShell会话以提取数据供SOF-ELK使用。如果我们提取的数据量很小,少于5K结果,我们可以运行一个单一命令,如下所示:“Search-UnifiedAuditLog -StartDate 7/20/2022 -EndDate 7/20/2023 -UserIds target-user@yourcompany.com -ResultSize 5000 | Select-Object -ExpandProperty AuditData | Out-File -Encoding UTF8 ual-target-user-07202022-07202023.json”

1
Search-UnifiedAuditLog -StartDate 7/20/2022 -EndDate 7/20/2023 -UserIds target-user@yourcompany.com -ResultSize 5000 | Select-Object -ExpandProperty AuditData | Out-File -Encoding UTF8 ual-target-user-07202022-07202023.json

UAL导出到JSON为“PC”用户

我们如何知道基于我们的查询参数是否有少于5K UAL条目?我们不知道!你可以通过重新运行上述命令来检查,将输出到文件替换为measure:“Search-UnifiedAuditLog -StartDate 7/20/2022 -EndDate 7/20/2023 -UserIds pc@securecake.com -ResultSize 5000 | Select-Object -ExpandProperty AuditData | Measure”

或者,我们可以使用几种不同的方法来克服5K记录限制。查看下面的链接以获取Microsoft的观点。自然,我更喜欢我的脚本,主要是因为它简单且适用于我大约98%的用例。只需编辑文件输出路径、开始和结束日期,过滤特定UserIDs或保留$null以搜索所有。该脚本以一小时为增量查询UAL,以最小化每次查询达到5K最大结果的可能性,在屏幕上报告计数,并写入单个文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#更改路径到所需的输出位置,并更改名称以反映日期范围
$OutputFile = ".\ual-userid-pc-07012023-07202023.json"
#输入“UserID”在引号中或保留为$null以搜索所有用户
$userids = $null
#输入开始搜索日期,格式为mm-dd-yyyy
$StartSearchDate = get-date "7-1-2023”
#输入结束搜索日期,格式为mm-dd-yyyy
$EndSearchDate = get-date "7-20-2023"
$FormattedStartDate = Get-Date $EndSearchDate
$DaysToSearch = (new-timespan -start $StartSearchDate -End $EndSearchDate).days
For ($i=0; $i -le $DaysToSearch; $i++){
  For ($j=23; $j -ge 0; $j--){
    $StartDate = ($EndSearchDate.AddDays(-$i)).AddHours($j)
    $EndDate = ($EndSearchDate.AddDays(-$i)).AddHours($j + 1)
    $Audit = Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -userIDs $userids -ResultSize 5000
$ConvertAudit = $Audit | select-object -expandproperty AuditData | out-file -encoding UTF8 $OutputFile -Append
Write-Host $StartDate `t $Audit.Count
  }
}

UAL导出脚本

使用PowerShell脚本搜索审计日志 – Microsoft Purview(合规性)| Microsoft Learn

我的脚本假设你已经通过EXO连接到你的租户,并按相反顺序工作,从最新日期/时间到最旧,显示每个间隔的记录计数:

导出脚本输出

现在我们需要将我们的JSON数据复制到SOF-ELK,在摄取和解析发生时耐心等待,然后通过SOF-ELK web UI进行查询处理!从我当前目录,我将确认JSON文件/文件,然后将它们“scp”到适当的SOF-ELK目录:

复制UAL数据到SOF-ELK

从我们的SOF-ELK ssh会话,我们可以通过运行“sof-elk_clear.py -i list”来密切关注Elasticsearch进度,这将显示当前的索引。起初你可能看不到任何条目,但耐心点!在几分钟内,你应该看到一个“- microsoft365 (nn documents)”条目,这是一个很好的迹象,表明我们的数据正在被摄取/解析:

检查SOF-ELK索引

再次,需要一点耐心,但我们可以去web UI看看我们的结果是什么样子。启动浏览器并访问http://x.x.x.x:5601(将x替换为你的SOF-ELK IP地址)。这应该带你到默认仪表板。点击“汉堡”图标(左上角的三条线)并点击“Discover”。

SOF-ELK Discover

将你的数据视图从“logstash-”更改为“microsoft365-”:

Microsoft365数据视图

然后将你的日期范围更改为适用的值。我将使用“Quick Select”和“Last One Month”为我的“PC UAL”数据集:

设置日期/时间范围

你现在应该看到一些“命中”和几百个“可用字段”。如果没有,确保你选择了正确的数据视图(microsoft365-*)并仔细检查你的日期范围过滤器:

日期过滤的Microsoft365数据视图

得益于内置解析和一些字段规范化,我们现在可以通过查看、选择和搜索可用字段来轻松处理我们的数据。让我们侦查出“PC” user_name(如果你在特定UserID上过滤了你的UAL查询,这可能不是必要的),并可视化一些关键的UAL细节:workload、operation、ips和useragent。在搜索框中键入第一个字段名称,例如“user_”。点击字段名称以查看“top”值并确认它是你要查找的数据字段,然后点击弹出窗口顶部的“+”号以添加该字段作为列,或点击顶部值旁边的“+”号以过滤该值。对每个所需的数据字段重复此操作:

添加字段到当前视图

现在我们可以轻松地挑选和选择、过滤、搜索和查看提取的AuditData字段:

数据视图表

根据我们之前的内联过滤讨论,如果我们想基于“UserAgent”进行透视,并查看我们当前UAL中是否有其他人使用可疑条目,只需悬停在useragent列条目上并选择“+”号以“过滤此useragent”。如果你之前过滤了单个user_name,移除该过滤器(点击手动过滤器框下方过滤器条目右侧的“x”):

过滤选定的数据字段值

从而开始了迭代过程,查询你的数据以回答审计/调查问题,添加字段,过滤进/出字段值,排序和可视化。在某个时候,你可能希望导出到CSV,这可以通过“Share”菜单选项和“CSV Reports”以及“Generate CSV”来完成:

导出到CSV

希望这只是我们SOF-ELK和UAL处理冒险的开始,因为我们 barely scratched the surface of SOF-ELK的效用!我们将回过头来讨论如何在AWS EC2中启动这整个混乱,以及如何转换UAL CSV文件以供SOF-ELK摄取。敬请关注,感谢阅读!

PS:以防你想知道,“他在一篇博客文章中可以使用‘处理’这个词多少次?”只有十次。我知道看起来比那多,但不是。

阅读: [第二部分] [第三部分]

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计