NickHoward1/Incident-Response-in-Sentinel-NIST-800-61-

GitHub: NickHoward1/Incident-Response-in-Sentinel-NIST-800-61-

一个基于 Microsoft Sentinel 和 NIST 800-61 标准的事件响应实战项目,提供 KQL 查询和完整 IR 流程来检测与处置暴力破解、恶意 PowerShell、不可能旅行等安全威胁。

Stars: 0 | Forks: 0

Sentinel 中的事件响应 - NIST 800-61

目标

深入理解 Microsoft Sentinel 并掌握如何高效使用该平台,通过 KQL 查询调查与暴力破解攻击、恶意 PowerShell 活动、不可能旅行事件以及过量 Azure 资源创建或删除相关的可疑行为。本实验旨在了解日志来源、识别可疑活动的关键指标,并在 SOC 环境中获得调查和警报分流的实践经验。

环境

  • Microsoft Azure、Sentinel 和 Defender

完成的任务

  • 暴力破解:在 Sentinel 中使用 KQL 查询创建警报,搜索失败登录尝试次数大于或等于 10 次的情况,在 SIEM 中触发事件。随后分析攻击并按照 NIST 标准执行 IR 生命周期。
  • PowerShell 可疑 Web 请求:在 Sentinel 中使用 KQL 查询创建警报,搜索恶意命令 Invoke-WebRequest 以识别日志和受影响的主机,并检查该命令是否被执行。随后按照 NIST 标准执行 IR 生命周期。

截图

虚拟机暴力破解检测

创建 KQL 查询

`DeviceLogonEvents | where TimeGenerated >= ago(5h) | where ActionType == "LogonFailed" | summarize NumberOfFailures = count() by RemoteIP, ActionType, DeviceName | where NumberOfFailures >= 10`

创建警报规则

流程: `Microsoft Sentinel - 配置 - 分析 - 创建(计划查询规则)- 启用规则 - 根据查询设置 Mitre ATT&CK 框架类别 - 每 4 小时运行一次查询 - 查询最近 5 小时的数据(可在查询中定义)- 生成警报后停止运行查询 == 是 - 为 RemoteIP 和 DeviceName 配置实体映射 - 规则触发时自动创建事件 - 每 24 小时将所有警报归为单个事件 - 生成警报后停止运行查询(24 小时)- 审核并创建`

           

截图1:展示我使用在 Sentinel 日志中测试过的 KQL 查询创建警报。
截图2:展示警报已在威胁管理下作为事件触发。
截图3:展示调查地图,详细列出所有尝试暴力破解攻击的公共 IP 地址以及被攻击的主机。要获取此地图,我将警报分配给自己并将状态更改为活动状态。*重要:记下 IP 和被攻击的主机地址。

Microsoft Defender for Endpoint

在真实场景中,如果登录成功,我会立即隔离受受影响的主机或设备,以帮助防止横向移动,并阻止任何可能已执行的恶意软件或勒索软件在整个环境中进一步传播。我还会启动防病毒或端点扫描作为遏制流程的一部分。我会在资产/设备部分导航到受影响的设备,并在将事件上报给高级 SOC 分析师进行进一步调查和修复活动之前,应用设备隔离和遏制操作。 要查看暴力破解尝试是否成功,请使用下面的 KQL 查询,如果没有结果显示,则说明尝试未成功。 在某些情况下,我需要在 Azure 中创建网络安全组规则以应对暴力破解攻击。攻击者会扫描开放的 RDP,以便在端口 3389 上重复进行 RDP 尝试或在端口 22 上进行 SSH 暴力破解。创建规则的流程如下... 流程: `Azure - 网络安全组 - 创建端口规则。` 在事件响应的最后一步,您需要声明您的发现,操作如下 - 流程: `Sentinel - 事件 - 搜索事件 - 选择事件 - 查看完整详情 - 选择活动日志 - 发布评论`

调查暴力破解攻击和 KQL 查询

构建事件序列以确定是否为误报或真实告警:失败登录、成功登录、PowerShell 执行、外部连接、文件下载 失败登录次数:是单次失败登录?还是数百/数千次? `DeviceLogonEvents | where ActionType == "LogonFailed" | summarize FailedAttempts = count() by RemoteIP, AccountName | order by FailedAttempts desc` 登录成功:LogonSuccess `DeviceLogonEvents | where RemoteIP in ("185.156.73.169") | where ActionType != "LogonFailed"` RDP 登录:暴力破解攻击通常针对:RDP (3389) SSH (22) `DeviceLogonEvents | where LogonType == "RemoteInteractive"` (是否尝试或实现了远程访问) 地理位置异常 检查:国家、ASN、VPN/代理指标
问题:登录是否来自可疑国家?对组织来说是否异常?是否为不可能旅行? 多个用户名被攻击:多个用户名,同一来源 IP `DeviceLogonEvents | summarize Attempts=count() by RemoteIP, AccountName` PowerShell 已执行 如果登录成功:攻击者通常会立即执行 PowerShell
检查:DeviceProcessEvents、可疑脚本、编码命令、Invoke-WebRequest 检查横向移动:被攻陷的主机是否连接到了其他系统?是否访问了管理共享?是否创建了新的登录? 检查:DeviceNetworkEvents、其他主机、SMB/RDP 流量 调查持久性 攻击者可能:创建账户、安装服务、计划任务
查找:新用户、计划任务、注册表更改

PowerShell 可疑 Web 请求

创建 KQL 查询

`let TargetHostname = "nicks-vm"; DeviceProcessEvents | where DeviceName == TargetHostname | where FileName == "powershell.exe" | where InitiatingProcessCommandLine contains "Invoke-WebRequest" | order by TimeGenerated`

创建警报规则

流程: `Microsoft Sentinel - 配置 - 分析 - 创建(计划查询规则)- 填写:名称:- 描述:- 启用规则 - 使用 ChatGPT 根据查询设置 Mitre ATT&CK 框架类别 - 每 4 小时运行一次查询 - 查询最近 24 小时的数据(可在查询中定义)- 生成警报后停止运行查询 == 是 - 配置实体映射:账户:标识符:名称,值:AccountName,主机:标识符:HostName,值:DeviceName,进程:标识符:CommandLine,值:ProcessCommandLine - 规则触发时自动创建事件 - 每 24 小时将所有警报归为单个事件 - 生成警报后停止运行查询(24 小时)`

           

截图1:展示我创建 KQL 查询以查找包含 "Invoke-WebRequests" 的 PowerShell 脚本。
截图2:展示我创建检测规则,使事件出现在 Sentinel 的事件列表中。
截图3:展示我收集信息并将其整理成笔记,然后发送给高级 SOC 分析师。流程: `Sentinel - 威胁管理 - 事件 - 目标主机 - 分配所有者(我)- 更改状态:活动 - 查看完整详情 - 调查 - 将发现的命令复制并粘贴到笔记中(见下文)` 检测与分析部分:这是您记录发现的地方。 布局:在下方展示调查内容... 标题:检测与分析 正文:在调查触发的事件时....(事件数量或主机名称)写下您的发现 脚本:复制并粘贴脚本 命令:例如 (portscan.ps1),然后将该脚本的 URL 复制并粘贴到 Web 搜索中以检索原始命令,并粘贴到笔记中。 已执行:参见下面的 KQL 查询,如果有结果,说明命令已执行,这意味着需要将此写入笔记并传递给 SOC2。在笔记中也要复制并粘贴所使用的查询。 遏制、根除和恢复: 已隔离:写明该机器已在 MDE 中隔离并进行了防病毒扫描。流程: `MDE - 资产 - 设备 - 搜索设备 - 右上角隔离并运行恶意软件扫描` 关闭事件:复制并粘贴笔记,使用 chatGPT 进行精简。完成后,返回 Sentinel 在活动日志中记录笔记并关闭事件。流程: `Sentinel - 威胁管理 - 事件 - 搜索事件 - 查看完整详情 - 活动日志 - 发布笔记 - 更改状态:已关闭` `let TargetHostname = "windows-target-1"; // 替换为目标主机在日志中显示的名称 let ScriptNames = dynamic(["eicar.ps1", "portscan.ps1", "pwncrypt.ps1"]); // 添加已下载脚本的名称 DeviceProcessEvents | where DeviceName == TargetHostname // 注释掉此行以获取更多结果 | where FileName == "powershell.exe" | where ProcessCommandLine contains "-File" and ProcessCommandLine has_any (ScriptNames) | order by TimeGenerated | project TimeGenerated, AccountName, DeviceName, FileName, ProcessCommandLine`      

潜在的不可能旅行

创建 KQL 查询

`let TimePeriodThreshold = timespan(7d); let NumberOfDifferentLocationsAllowed = 2; SigninLogs | where TimeGenerated > ago(TimePeriodThreshold) | summarize Count = count() by UserPrincipalName, UserId, City = tostring(parse_json(LocationDetails).city), State = tostring(parse_json(LocationDetails).state), Country = tostring(parse_json(LocationDetails).countryOrRegion) | project UserPrincipalName, UserId, City, State, Country | summarize PotentialImpossibleTravelInstances = count() by UserPrincipalName, UserId | where PotentialImpossibleTravelInstances > NumberOfDifferentLocationsAllowed`

创建警报

流程: `Microsoft Sentinel - 配置 - 分析 - 创建(计划查询规则)- 填写:名称:- 描述:- 启用规则 - 根据查询设置 Mitre ATT&CK 框架类别 - 每 4 小时运行一次查询 - 查询最近 7 天的数据(可在查询中定义)- 生成警报后停止运行查询 == 是 - 配置实体映射:账户:标识符:AadUserId,值:UserId,标识符:DisplayName,值:UserPrincipalName - 规则触发时自动创建事件 - 每 24 小时将所有警报归为单个事件 - 生成警报后停止运行查询(24 小时)`

           

截图1:展示。
截图2:展示。
截图3:展示。

检测与分析部分:

准备:记录角色、职责和流程。确保工具、系统和培训到位。 使用 KQL 查询调查每个账户,查看他们具体从哪些位置登录,并自行判断是误报还是真实告警。例如,如果用户在合理时间内登录了两个相邻城市,这将是误报。但如果有人在 12 小时内分别登录了泰国、西雅图、泰国,这就值得怀疑。 // 调查潜在的不可能旅行事件 `let TargetUserPrincipalName = "Nickhoward605@gmail.com"; // 更改为目标用户(UserPrincipalName) let TimePeriodThreshold = timespan(7d); // 更改为您想要回溯的时间范围 SigninLogs | where TimeGenerated > ago(TimePeriodThreshold) | where UserPrincipalName == TargetUserPrincipalName | project TimeGenerated, UserPrincipalName, City = tostring(parse_json(LocationDetails).city), State = tostring(parse_json(LocationDetails).state), Country = tostring(parse_json(LocationDetails).countryOrRegion) | order by TimeGenerated desc` 观察不同用户(UserPrincipalName)的登录模式并做记录。
示例:Nickhoward605@ 在 Z 时间段内从 x 和 y 登录:可疑
示例:arisa_lognpacific@lognpacific.com 在 C 时间段内从 a 和 b 登录:正常

遏制、根除和恢复

隔离受影响的系统以防止进一步损害。 根据公司政策和证据,您可能需要在 Entra ID(Azure Active Directory)中立即禁用该账户,并联系用户或用户的经理进行调查。
  • 示例:经确定该警报为真实告警。用户 ___ 在 ___ 天的时间段内登录了 ___ 和 ___,这应该是不可能的。
  • 用户的账户已被禁用,并已通知管理层。
消除威胁并将系统恢复正常。
  • 如果登录行为异常,可能存在账户被攻陷的风险。
  • 转向查看用户还进行了哪些其他活动。例如,您可以查看 AzureActivity 日志:
`AzureActivity | where tostring(parse_json(Claims)["http://schemas.microsoft.com/identity/claims/objectidentifier"]) == ""`

事后活动

  • 更新策略和工具以防止再次发生:在 Azure 中设置地理围栏策略,防止在特定区域之外登录。在我们的环境中无法做到这一点,但需要牢记。
  • 记录发现和总结经验教训:在事件中记录您的笔记。

关闭

  • 审查并确认事件解决:审查/查看您的事件笔记。
  • 完成报告并结案:在 Sentinel 中将事件关闭为"良性误报"(或根据您的情况选择适当分类)。

过量资源创建/删除

成果

标签:ATT&CK框架, Azure资源创建删除, Invoke-WebRequest, KQL, KQL查询, Microsoft Azure, Microsoft Defender, Microsoft Sentinel, NIST 800-61, OpenCanary, 不可能旅行事件, 云服务安全, 免杀技术, 安全运营中心(SOC), 恶意PowerShell, 暴力破解检测, 检测规则, 突发事件管理, 红队行动, 网络资产发现