#yara #string-matching #scan #execution-time #replace

boreal

一个用于评估 YARA 规则的库,用于扫描字节数据中的文本和二进制模式

9 个版本 (重大变更)

0.8.0 2024年6月9日
0.6.0 2024年4月14日
0.5.0 2024年2月16日
0.3.1 2023年11月12日
0.1.0 2022年12月4日

#94 in 文本处理

Download history 166/week @ 2024-04-26 393/week @ 2024-05-03 198/week @ 2024-05-10 72/week @ 2024-05-17 47/week @ 2024-05-24 179/week @ 2024-05-31 345/week @ 2024-06-07 191/week @ 2024-06-14 97/week @ 2024-06-21 85/week @ 2024-06-28 25/week @ 2024-07-05 44/week @ 2024-07-12 45/week @ 2024-07-19 3/week @ 2024-07-26 80/week @ 2024-08-09

每月154次下载
用于 boreal-cli

MIT/Apache

1.5MB
29K SLoC

boreal

Build status Crates.io Documentation Coverage

北极熊是 YARA 规则的评估器,用于扫描字节数据中的文本和二进制模式,主要用于恶意软件检测。

描述

北极熊旨在作为 YARA 的直接替代品,同时增加改进。该项目的主要目标是

  • 与 YARA 规则的完全兼容性
  • 只为你使用的部分付费
  • 提高性能和可靠性

特性

  • 与 YARA 4.5 和所有 官方模块 完全兼容。任何现有规则都可以直接使用。
  • 在不需要时避免扫描字符串,大大减少精心设计的规则上的执行时间。请参阅 无扫描优化
  • 针对任何不受信任的输入提供保护,无论是规则还是扫描的字节数据。设计不当的规则或输入不应导致崩溃或性能下降。
  • 大多数情况下性能都有所提高,特别是在使用几百个规则时。请参阅基准测试以获取详细信息。
  • 支持在 Windows、Linux 和 macOS 上进行扫描,并提供不同的扫描模式。请参阅 FragmentedScanMode 文档
  • 纯 Rust 实现,不依赖任何 C 库,如 OpenSSL,使其在任何目标上构建和使用都变得非常容易。唯一的例外是 magic 模块,它需要 libmagic。

安装与使用

北极熊可以作为库和命令行工具使用。

命令行工具可以从源代码构建

> cargo install --locked boreal-cli

并使用与 yara 可执行文件相同的标志和语法

> ./boreal path/to/rules path/to/dir
rule_1 path/to/dir/suspicious_file

北极熊也可以用作库,请参阅 文档

如果你曾经使用过 YARA 或 Yara-Rust 作为库,API 应该会感觉熟悉

use boreal::Compiler;

let mut compiler = Compiler::new();
compiler.add_rules_str(r#"
rule example {
    meta:
        description = "This is an YARA rule example"
        date = "2022-11-11"
    strings:
        $s1 = { 78 6d 6c 68 74 74 70 2e 73 65 6e 64 28 29 }
        $s2 = "tmp.dat" fullword wide
    condition:
        any of them
}
"#)?;

let scanner = compiler.into_scanner();
let res = scanner.scan_mem(b"<\0t\0m\0p\0.\0d\0a\0t\0>\0");
assert!(res.matched_rules.iter().any(|rule| rule.name == "example"));

Yara 兼容性

北极熊保证所有由 YARA 执行的有效规则都将被接受,并表现出相同的行为。这通过执行 YARA 仓库中的测试以及添加许多其他测试来实现,所有测试都在 boreal 和 YARA 上运行,以确保完全相同的行为。

然而,也存在一些兼容性的例外

  • 评估错误。Boreal可能不会遇到其中的一些错误,或者可能已经修复了一些错误。

  • 溢出或下溢。这些错误在YARA中没有指定,事实上,有符号溢出本身就是未定义行为。在Boreal中,对溢出/下溢的评估行为不再是未定义行为,但目前没有指定。

  • 对抗性规则的自防御限制。Boreal设置限制以确保无法编写可能导致程序解析或评估此规则时出现问题的规则。尽管这些限制从技术上拒绝了YARA会接受的规则,但这些限制不应该影响正确的规则。

此外,目前YARA和Boreal之间有一个评估差异

  • 依赖自身的规则不再能编译。
rule my_rule {
    condition: my_rule
}

在YARA中这是有效的,并且始终评估为假。在Boreal中,这个规则不能编译。

没有计划修复这种行为,因为我看不到一个有效的用例,并且修复它是不免费的。如果有人可以提供一个有效的用例,这种差异可以得到解决。

模块

  • elf(具有对象特性)
  • hash(具有hash特性)
  • math
  • macho(具有对象特性)
  • pe(具有对象特性)
    • pe.imphash()位于hash特性之后
    • pe.signatures位于authenticode特性之后
    • pe.is_signed和签名verified的值位于authenticode-verify特性之后,默认禁用。有关详细信息,请参阅authenticode-verify部分。
  • dotnet(具有对象特性)
  • string
  • time
  • console
  • dex(具有对象特性)
  • magic(具有magic特性,默认禁用)
  • cuckoo(具有cuckoo特性,默认禁用)

按使用付费

YARA是一款出色的软件,但它主要设计用于优化最坏情况。这会导致很多无用的和不必要的工作,并使用户设计规则时感到非常沮丧,这些规则实际上应该很快就能评估。

没有扫描优化

假设你编写了这条规则

rule should_be_fast {
    strings:
        $a = { 10 2d EF CF 29 31 26 }
    condition:
        filesize < 50KB and $a
}

你预期扫描这条规则与一个大目录相比会相当快,因为所有大文件都会被跳过,无需扫描所有文件的全部内容。

然而,这正是YARA的行为。然而,在boreal中,所有大于50KB的文件将不会进行扫描,并且评估这条规则将非常快。

只要所有规则都可以评估而不需要扫描它们的字符串,这种优化就会生效。如果有一个规则需要扫描,那么所有规则的所有字符串都将进行扫描。

在这方面还有一些工作要做。例如,常见的"$a at X"规则尚未得到妥善处理,并且将需要扫描字符串。如果你认为你有条规则不需要扫描但确实需要,请报告它。

保存和加载编译后的规则

尚未实现YARA的唯一功能是保存和加载编译后的规则,因为我并不完全清楚这个功能的用例。如果您需要这个功能,请创建一个带有用例的问题。

crate功能标志

默认启用

  • object:启用elfmachopedotnetdex模块。
  • hash:启用 hash 模块,以及如果启用了 object 功能,则启用 pe.imphash() 函数。
  • authenticode:启用 pe 模块的 signatures 部分。
  • process:添加进程扫描 API。
  • memmap:添加使用内存映射扫描文件的 API。

默认禁用

  • profiling:在编译和评估期间添加统计计算的函数。
  • magic:启用 magic 模块。添加对 libmagic 的依赖。
  • cuckoo:启用 cuckoo 模块。
  • authenticode-verify:启用 pe.signedpe.signatures[*].verifiedpe.signatures[*].countersignatures[*].verifiedpe 模块部分。

authenticode-verify

YARA 4.3 引入了针对 pe.signatures 对象的新解析,特别是字段 pe.is_signedpe.signatures[*].verifiedpe.countersignatures[*].verified。然而,这些字段却引发了一些问题

  • 它们可能会令人困惑,因为它们并不表示 Windows 是否实际上会将文件视为已签名,因为没有信任锚验证。
  • 它们引入了对 OpenSSL 的依赖以进行签名验证,并且任何等效的实现都会引入大量依赖来处理签名中可能使用的所有不同算法。

我不确定这些字段的用例是什么,因此默认情况下没有实现。为了能够使用它们,有两种可能性

  • 可以启用 authenticode-verify 功能以重新获取它们,但实现是尽力而为的。它不依赖于 OpenSSL,而是使用 rust cryptos crate,因此并非所有算法都已实现,可能缺少一些检查。
  • 在 Windows 上,可以调用 WinVerifyTrust 并将结果作为外部符号提供。可以实现一个功能,使其作为 pe.is_signed 而不是外部符号提供,但在实现之前我想要了解对此的兴趣。这里的优势是,该值真正反映了文件是否被 Windows 视为已签名。

如果您需要使用这些字段并且这些解决方案不足以满足您的需求,请提交一个 issue。

依赖项

~5–16MB
~197K SLoC