Tag: SIEM

红队技术:对 Sysmon 的可靠对抗技巧-第二部分

在第一部分中,我们介绍了在 Windows 系统中对 Sysmon 的对抗技巧,接下来我们将操作系统更改为 Linux,观察 Sysmon 又有何表现。

部署 SysmonForLinux

本文所使用的 Linux 系统发行版本为 openKylin 1.0(开放麒麟),我们将在该国产系统中进行 Sysmon 部署与测试。

下载 SysinternalsEBPFSysmonForLinux 的 dpkg 软件包,分别进行部署。

部署完毕后,输入 sysmon 命令打印帮助,命令行参数与 Windows 版本没有太大区别。

使用 sysmon -i 命令安装 Sysmon 驱动与服务。

安装完成后,需要准备 SysmonForLinux 配置文件,该配置将监控并记录 Sysmon 在 Linux 系统上支持的所有行为事件,配置内容如下:

<Sysmon schemaversion="4.70">
  <EventFiltering>
    <!-- Event ID 1 == ProcessCreate. Log all newly created processes -->
    <RuleGroup name="" groupRelation="or">
      <ProcessCreate onmatch="exclude"/>
    </RuleGroup>
    <!-- Event ID 3 == NetworkConnect Detected. Log all network connections -->
    <RuleGroup name="" groupRelation="or">
      <NetworkConnect onmatch="exclude"/>
    </RuleGroup>
    <!-- Event ID 5 == ProcessTerminate. Log all processes terminated -->
    <RuleGroup name="" groupRelation="or">
      <ProcessTerminate onmatch="exclude"/>
    </RuleGroup>
    <!-- Event ID 9 == RawAccessRead. Log all raw access read -->
    <RuleGroup name="" groupRelation="or">
      <RawAccessRead onmatch="exclude"/>
    </RuleGroup>
    <!-- Event ID 10 == ProcessAccess. Log all open process operations -->
    <RuleGroup name="" groupRelation="or">
      <ProcessAccess onmatch="exclude"/>
    </RuleGroup>
    <!-- Event ID 11 == FileCreate. Log every file creation -->
    <RuleGroup name="" groupRelation="or">
      <FileCreate onmatch="exclude"/>
    </RuleGroup>
    <!--Event ID 23 == FileDelete. Log all files being deleted -->
    <RuleGroup name="" groupRelation="or">
      <FileDelete onmatch="exclude"/>
    </RuleGroup>
  </EventFiltering>
</Sysmon>

使用 sysmon -c 命令导入配置文件。

现在,SysmonForLinux 开始正常工作,它稳定的记录着一切来自红队的操作痕迹......

配置存储位置

Windows 中的 Sysmon 将导入的配置内容以二进制形式保存在注册表中,但 Linux 系统并没有注册表,它的配置存储位置在哪里?

通过浏览 SysmonForLinux 服务程序源代码,从 这里 开始,Sysmon 将响应 -c 参数输出正在应用的配置。

我们继续审计 DumpConfiguration 函数,发现配置文件位置由 SYSMON_RULES_FILE 宏进行定义。

  • 默认安装路径:/opt/sysmon
  • 配置路径:/opt/sysmon/config.xml
  • 规则路径:/opt/sysmon/rules.bin

在查看 config.xml 的时候,我们惊讶的发现,它的内容居然与我们指定的配置文件一致,而非默认的空配置,再结合前面截图中的正在运行的 sysmon 进程命令行参数......思考。

难道说,SysmonForLinux 不能离开明文配置独立工作?我们尝试重命名 config.xml,重启,观察 Sysmon 的运行状态。

重启后,Sysmon 服务程序已停止工作......

syslog 中也没有继续出现 Sysmon 的日志记录,内核中收集行为日志的机制完全失效。

我们只需要有权限可以访问到 SysmonForLinux 的配置文件,即可了解当前系统中的行为监控情况,不再需要二进制解析过程。

脆弱的 eBPF

SysmonForLinux 没有独立的内核模式程序(驱动程序),它通过 Linux 内核提供的 eBPF 框架实现用户层系统调用跟踪,类似的开源项目还有 traceeHades

实际上,从 此处 审计可发现,在执行 sysmon -i 命令时,SysmonForLinux 只是将所需的配置文件与编译后的 eBPF 对象文件释放,而后通过前面提到的 SysinternalsEBPF 将 eBPF 程序注入进内核 eBPF 框架中,进而实现系统行为监控。

在注入前,SysmonForLinux 会读取 config.xml,将其中的规则保存为二进制的 rules.bin 文件,注入后,二进制会通过 linkTPprogs 修改 eBPF 跟踪点,这使得 eBPF 框架可以依照配置文件对特定系统调用进行跟踪。

但是,这些注入的 eBPF 程序并不能独立运行,它们类似于安插在系统调用中的回调函数,当指定的系统调用发生时,eBPF 会向处于用户态的将 eBPF 代码注入进内核的程序传达这些系统调用的详细信息,而且,这些 eBPF 程序依赖用户态进程,一旦用户态进程未能正常工作,则整个监控记录机制完全无效。

而且,被植入的 eBPF 程序由于 eBPF 框架的安全检查和功能需要,很难被混淆后再进行注入,即使是没有开源的编译后 eBPF 跟踪程序,也可通过 llvm-objdump 进行反编译。参考 此处

总结

Sysmon 作为免费且公开的系统工具,实现了很多细致且开箱即用的系统行为记录功能,是蓝队手中的强大武器,可能出于对工具滥用的担忧,开发者并未设计它的自我保护和数据保护功能,但这并不妨碍它日常的行为记录功能。

在它灵活的监控规则下,红队不太可能在操作时隐藏自身,唯有充分了解 Sysmon 的弱点,在 SIEM 和 SOC 广泛流行的现在,才可以与使用 Sysmon 蓝队继续对抗下去。

红队技术:对 Sysmon 的可靠对抗技巧-第一部分

Sysmon 是什么

Sysmon 是一款可以全面记录系统行为日志的工具,全称为 System Monitor(系统监视),最初由美国 Winternals 软件有限公司的 Mark Russinovich 编写而成,作为 Sysinternals 实用工具套件的一部分,现在的所有者为微软。

截止至本文发布时间,Sysmon 已经更新至 15.0 版本,且已经支持了 Linux 系统,在大多数国产操作系统中也可以正常工作。

在第一部分中,我们只讨论 Sysmon 的 Windows 版本。

保持敬畏

很多从事红队或渗透测试工作的朋友,在进程列表中遭遇 Sysmon 的第一反应可能是:

  • A:它没有任何自身保护功能,Kill 掉它就万事大吉了;
  • B:它又不会阻拦我继续进行渗透测试,是无关紧要的;
  • C:拜托,很弱的啦。

可事实并非如此,在绝大多数已经部署 Sysmon 的企业或机构网络中,Sysmon 往往不是独立存在的。

Sysmon 可以收集的系统行为日志如下:

  • 进程创建
  • 进程退出
  • 文件的创建时间被修改
  • 网络连接
  • Sysmon 服务状态更改
  • Sysmon 配置更改
  • 驱动加载
  • 模块加载
  • DNS 查询
    ...

篇幅有限,详细的事件记录请查阅 官方文档

将各类行为日志提取后,后续的安全日志分析工具就开始发挥作用了,例如全球最流行的开源 SIEM 项目 Wazuh 和全球最大的日志分析商业平台 Splunk,它们采集到 Sysmon 的行为日志后,会通过内置的安全策略对行为日志进行筛选,找出可能对安全存在威胁的系统行为。

这种 日志收集 ->日志筛选 ->安全响应 模式,在安全运维机制良好的网络环境中是长期存在的,入侵者在系统中产生的行为数量,在广泛的行为日志中如沧海一粟。

所以,红队从一开始就处于完全监视之下,对上述模式采取不管不顾甚至是轻视的做法,最终会招致渗透测试完全失败的恶果,这是必然事件。

我们认为,以下做法是完全错误且十分不专业的,且可能会迅速吸引蓝队的注意:

  • 尝试破坏 Sysmon(这是最危险的行为)
  • 无视 Sysmon

从红队角度看,对行为事件采集源头的 Sysmon 保持敬畏之心,是十分有必要的。

定位 Sysmon

在准备应对 Sysmon 之前,红队必须确定当前系统中是否存在它,我们提供了一些方案用于定位 Sysmon。

Sysmon 由以下部分组成:

  • Sysmon 服务程序
  • Sysmon 驱动程序

使用 -i 参数可以将 Sysmon 以默认配置部署至系统中,如下图所示:

我们可以在系统服务和进程列表中观察到 Sysmon64,如下图所示:

该服务进程程序的路径默认为:

  • C:\Windows\Sysmon64.exe

驱动程序为:

  • C:\Windows\SysmonDrv.sys

注册表项路径:

  • 服务:HKLM\SYSTEM\ControlSet001\Services\Sysmon64
  • 驱动:HKLM\SYSTEM\ControlSet001\Services\SysmonDrv

过滤器实例信息:

  • 过滤器名:SysmonDrv
  • 实例名:Sysmon Instance
  • 过滤器高度:385201

想了解更多有关文件系统微型过滤器的知识,请参考微软 官方文档

通过查找以上信息,红队可以发现默认配置下的 Sysmon 部署情况,然而,不知出于有意或无意,Sysmon 允许用户通过改变安装参数和信息,避开上述所有的默认特征。

例如,使用如下安装操作,改变服务与进程名:

效果如下:

更多操作可以参考文章:Sysmon hide and seek

红队怎样才能定位到被彻底隐藏的 Sysmon?Sysmon 行为日志收集功能的核心是它的驱动程序,通过向系统注册上面提到的过滤器实例,Sysmon 才得以正常工作,我们可以先尝试枚举出所有的过滤器,然后找到它们对应的驱动程序路径:

Function Select-Column {
  [cmdletbinding(PositionalBinding = $False)]
  param(
    [Parameter(ValueFromPipeline, Mandatory)]
    $InputObject,

    [Parameter(Mandatory, Position = 0)]
    [int[]] $Index,

    [Parameter(Position = 1)]
    [int] $RequiredCount,

    [Parameter(Position = 2)]
    [string] $OutFieldSeparator = "`t"
  )

  process {
    if (($fields = -split $InputObject) -and ($RequiredCount -eq 0 -or $RequiredCount -eq $fields.Count)) {
      $fields[$Index] -join $OutFieldSeparator
    }
  }
}

$filterList = & "fltMC.exe" filters
$serviceList = Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\*'

$filterList | Select-Column -Index 0 -RequiredCount 4 | Select-Object -Skip 1 | ForEach-Object {
  $__ = $_
  $serviceList | ForEach-Object {if($_.ImagePath -like "*$__.sys") { $_.ImagePath }}
}

遍历得到的驱动程序,获取它们的附加信息,并检索其中是否包含 Sysmon 关键字,随后,我们成功找到被隐藏起来的 Sysmon 驱动程序,如下图所示:

使用以上过程确定原版 Sysmon 是否部署,是非常准确的,因为,如果蓝队尝试修改掉 Sysmon 驱动程序的附加信息,就会使驱动程序二进制签名校验失败;如果蓝队重新对驱动程序进行签名,那就是另一个痛苦的故事了 🙂

* 如果你一定想破坏掉 Sysmon,较安全的办法已经在前面提到了,请仔细阅读并理解所有内容。

规则提取

以上步骤只是确定 Sysmon 是否部署,我们不建议红队对 Sysmon 功能进行任何形式的更改。

Sysmon 提取的特定行为类型,全部由配置文件定义,配置文件可以在 Sysmon 部署时指定并导入,也可以后续导入或更新,以下内容是一个简单的 Sysmon 配置,它允许 Sysmon 记录 cmd.exe 进程创建事件:

<Sysmon schemaversion="4.1">
    <HashAlgorithms>*</HashAlgorithms>
    <CheckRevocation/>
    <EventFiltering>
        <ProcessCreate onmatch="include">
            <Image condition="image">cmd.exe</Image>
        </ProcessCreate>
    </EventFiltering>
</Sysmon>

蓝队通常情况下,会在导入配置文件后,将配置文件删除,这不会影响 Sysmon 的正常工作。Sysmon 配置文件的内容以二进制形式保存在以下注册表值项中:

  • HKLM\SYSTEM\CurrentControlSet\Services\sysmonDrv\Parameters\Rules

正常情况下,蓝队或者管理员通过 -c 参数运行 Sysmon,可以将该二进制形式的配置转换为可读格式并打印,如下图所示:

但从红队角度出发,这是一个不太安全的操作,因为蓝队很可能提前准备了针对该命令执行的检测方案。

红队可以尝试使用注册表相关的 WIN32 API 对配置值项二进制进行转储,例如 RegQueryValueExW,然后将转储后的值项写入红队本地的对应注册表值项中,并通过在本地运行 Sysmon 的 -c 参数得到可读配置内容。

在 2018 年的 Black Hat(黑帽大会)中,Matt Graeber 和 Lee Christensen 分享了针对 Sysmon 的议题,并开源了他们的工作成果,链接如下:

其中我们认为非常有意思的部分,是对 Sysmon 二进制配置内容进行逆向的工作,你可以在 PSSysmonTools 项目中找到它,但是它已经停止维护了,对新版本的 Sysmon 配置无效,感兴趣的朋友可以自行学习。

小结

在本文中,我们简单的介绍了 Sysmon,描述了它在实际场景中的应用和十分有效的防御策略,并从红队角度出发,描述了准确的在 Windows 系统中找到 Sysmon 并获取可读配置内容的方法。

在第二部分中,我们还将会介绍 Sysmon 在 Linux 系统中使用的先进技术和优秀表现,并提出在 Linux 下的可靠对抗技巧,敬请期待。