osquery YARA 扫描实战指南:yara_events、yara_file 与 yara_process 的配置、查询与底层原理

发布时间:2026/9/20 13:20:00
osquery YARA 扫描实战指南:yara_events、yara_file 与 yara_process 的配置、查询与底层原理 观测代理网络安全【免费下载链接】osquerySQL powered operating system instrumentation, monitoring, and analytics.项目地址https://gitcode.com/gh_mirrors/os/osquery点击查看免费下载osquery 将 YARA一种在文件中查找文本或二进制模式的规则匹配引擎能力封装为三张用途迥异的 SQL 表事件驱动的yara_events、按需文件扫描的yara_file与进程内存扫描的yara_process。本文以 docs/wiki/deployment/yara.md 为主线结合仓库内 yara 表实现 与 表结构定义完整讲解 YARA 配置格式、签名组管理、运行时远程拉取规则、三类扫描的查询写法、内联规则及常见排错帮助你在 osquery 上落地基于 YARA 的恶意软件检测与文件/进程取证。三张 YARA 相关表概览osquery 中的 YARA 能力由三张表承担它们服务于完全不同的场景yara_events基于 osquery 事件框架Events framework的表用于持续监控文件系统变化。当配置中指定的路径发生文件变更事件时自动对变更文件执行 YARA 扫描。其事件订阅逻辑在 yara_events.cpp 中实现表结构定义于 specs/yara_events.table。yara_file别名yara按需on-demand扫描表可对文件系统上任意可读文件使用任意签名文件或签名组执行一次性 YARA 扫描。yara_process按需扫描运行中进程的内存用于发现加壳packed、注入injected或无文件fileless型内存载荷。为便于表述本文后续将“签名文件”signature file与“YARA 规则文件”视为同义——即通常以.yar或.yara为扩展名的纯文本规则文件实际允许任意扩展名。YARA 规则的具体编写语法属于 YARA 项目本身的范畴本文聚焦 osquery 侧的使用与实现。YARA 配置osquery 的 YARA 配置非常简单核心是顶层 JSON 中的yara键。配置解析由YARAConfigParserPlugin完成该插件在 yara_utils.cpp 中通过REGISTER(YARAConfigParserPlugin, config_parser, yara)注册keys()声明其只关心配置中的yara顶级键见 yara_utils.h。下面是一个分组管理本地 YARA 规则文件的示例配置{ // Description of the YARA feature. yara: { signatures: { // Each key is an arbitrary group name to give the signatures listed sig_group_1: [/Users/wxs/sigs/foo.yar, /Users/wxs/sigs/bar.yar], sig_group_2: [/Users/wxs/sigs/baz.yar] }, file_paths: { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table system_binaries: [sig_group_1], tmp: [sig_group_1, sig_group_2] } }, // Paths to watch for filesystem events file_paths: { system_binaries: [/usr/bin/%, /usr/sbin/%], tmp: [/Users/%/tmp/%%, /tmp/%] } }file_paths监控路径与通配符语法配置中最先要注意的是全局file_paths段它描述需要监控哪些路径的变化。每个键是任意分类名值是路径列表。其路径语法即 osquery 的 FIM文件完整性监控通配符规则详见 file-integrity-monitoring.md要点如下%匹配一层的所有文件与文件夹%%递归匹配所有文件与文件夹%abc/abc%匹配某一层内以abc结尾 / 开头的所有条目不支持在路径中间递归例如/Users/%%/Configuration.conf不是合法的通配符~/%这类 home 简写同样不会被解析。路径展开后由 osquery 监控变化并由file_events表处理记录该表输出目标路径、分类、时间、动作、哈希等字段。从源码角度看YARAEventSubscriber::configure()yara_events.cpp会读取 yara 配置中的file_paths将其分类映射到全局file_paths的对应路径集合并为每个路径创建事件订阅上下文sc-recursive 0并设置FILE_CHANGE_MASK在 Linux 上底层由INotifyEventPublisher提供事件掩码含IN_CREATE | IN_CLOSE_WRITE | IN_MODIFY | IN_MOVED_TO在 macOS 上则由FSEventsEventPublisher提供。yara 段signatures 与 file_pathsyara段包含两个键signatures一组任意命名的“签名组”signature groups。每个组的 value 是要编译并存储在 osquery 内的签名文件路径列表。签名文件路径必须是绝对路径相对路径不被接受。配置更新时YARAConfigParserPlugin::update()会对每个组调用handleRuleFiles()yara_utils.cpp完成编译编译产物以std::mapstd::string, YaraRulesHandle形式缓存在插件内见 yara_utils.h。file_paths把全局file_paths中的事件分类名映射到扫描时要使用的签名组列表。例如当/usr/bin/与/usr/sbin/下的文件发生变化时会使用sig_group_1即foo.yar与bar.yar扫描当/Users/%/tmp/递归下的文件发生变化时会同时使用sig_group_1与sig_group_2即全部三个签名文件。运行时从远程获取 YARA 规则signature_urlsyara表的默认行为是使用 osquery 主机本地文件中的 YARA 规则。但如果希望在单一位置集中管理规则、让yara表运行时自动拉取而不必在每个 osquery 主机上单独维护并做版本管理规则文件可以使用signature_urls配置。有些组织还会将 YARA 规则视为安全敏感数据不希望把规则文件分发到每台主机的文件系统上。要允许运行时拉取规则需要在yara配置中增加signature_urls段。它是一个数组元素既可以是完整 URL指向单条 YARA 规则也可以是部分 URL——其中路径部分可以是正则表达式用于匹配多个 URL 与规则。每个条目对应查询中sigurl约束提供的单个或多个 URL。注意URL 字符串中域名之后的部分路径部分始终按正则表达式解析因此如果要用它指定完整的 URL必须转义正则特殊字符如.要写成\.。配置示例yara: { signature_urls: [ https://raw.githubusercontent.com/Yara-Rules/rules/master/cve_rules/CVE-2010-0805\\.yar, https://raw.githubusercontent.com/Yara-Rules/rules/master/crypto/crypto_signatures\\.yar, https://raw.githubusercontent.com/Yara-Rules/rules/master/malware/APT_APT3102\\.yar, https://raw.githubusercontent.com/Yara-Rules/rules/devel/CVE_Rules/CVE-.* ] }对应的查询示例# This is valid SELECT * FROM yara_file WHERE path/usr/bin/ls AND sigurlhttps://raw.githubusercontent.com/Yara-Rules/rules/master/cve_rules/CVE-2010-0805.yar; # This too SELECT * FROM yara_file WHERE path/usr/bin/ls AND sigurlhttps://raw.githubusercontent.com/Yara-Rules/rules/devel/CVE_Rules/CVE-2010-0805.yar; # Process scan example SELECT * FROM yara_process WHERE pid1234 AND sigurlhttps://raw.githubusercontent.com/Yara-Rules/rules/devel/CVE_Rules/CVE-2010-0805.yar # This is not allowed (not defined in yara config) SELECT * FROM yara_file WHERE path/usr/bin/ls AND sigurlhttps://raw.githubusercontent.com/Yara-Rules/rules/devel/malware/APT_APT3102.yar;对于上述最后一条未在配置中定义的 URLosquery 会拒绝并给出类似如下错误YARA signature url https://raw.githubusercontent.com/Yara-Rules/rules/devel/malware/APT_APT3102.yar not allowed Failed to get YARA rule url: https://raw.githubusercontent.com/Yara-Rules/rules/devel/malware/APT_APT3102.yar Query must specify sig_group, sigfile, or sigrule for scanURL 是否被允许的判断在 yara.cpp 的isRuleUrlAllowed中实现它要求查询 URL 与配置条目具有相同的 scheme 与 host大小写敏感然后用配置条目的路径部分作为正则对查询 URL 的路径做regex_match匹配配置更新时所有signature_urls条目会被解析为Uri存入url_allow_set_yara_utils.cpp。实际拉取规则由 getRuleFromURL 完成通过http::Client发起请求仅在响应状态码为 200 时把响应体作为规则内容随后经compileFromString编译并缓存yara.cpp。默认情况下YARA 规则字符串不会出现在查询输出中以防止结果与日志泄露规则内容。若需要在sigrule列中返回 YARA 规则本身需将隐藏 flagenable_yara_string设为true默认false声明见 yara.cpp。请求认证可以启用--yara_sigurl_authenticateflag 开启请求认证。启用后osquery 不再发送GET请求而是发送POST请求请求体为包含 node key 的 JSON。接收端服务器可先用 node key 完成认证再返回 YARA 规则。其余行为不变。对应实现见 yara.cpp认证开启时构造{node_key: ...}的 JSON bodynode key 通过getNodeKey(tls)获取并以application/json类型 POST否则使用普通 GET。注意事项拉取到的 YARA 规则只会被获取一次随后缓存直到服务器响应头Last-Modified表明缓存已过期才会重新拉取。osquery agent 始终校验提供 YARA 签名的服务器的 HTTPS 证书但当前不支持客户端认证client authentication。YARA 规则文件必须无需认证即可访问。使用 yara_events 持续监控以上面的配置为例在 osquery 运行期间在另一个终端执行touch /Users/wxs/tmp/foo即可看到实际效果。相关查询及结果如下osquery SELECT * FROM file_events; ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | target_path | category | time | action | transaction_id | md5 | sha1 | sha256 | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | /Users/wxs/tmp/foo | tmp | 1430078285 | CREATED | 33859499 | d41d8cd98f00b204e9800998ecf8427e | da39a3ee5e6b4b0d3255bfef95601890afd80709 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- osquery SELECT * FROM yara_events; --------------------------------------------------------------------------------------- | target_path | category | time | action | transaction_id | matches | count | --------------------------------------------------------------------------------------- | /Users/wxs/tmp/foo | tmp | 1430078285 | CREATED | 33859499 | always_true | 1 | --------------------------------------------------------------------------------------- osqueryfile_events表记录了/Users/wxs/tmp/foo被创建以及对应的时间戳与哈希值yara_events表记录创建该文件时命中了 1 条规则always_true。该示例中每个文件都至少命中一次是因为使用的规则恒为真。若将always_true规则从签名文件中移除再在监控目录下创建同名文件结果如下osquery SELECT * FROM yara_events; --------------------------------------------------------------------------------------- | target_path | category | time | action | transaction_id | matches | count | --------------------------------------------------------------------------------------- | /Users/wxs/tmp/foo | tmp | 1430078285 | CREATED | 33859499 | always_true | 1 | | /Users/wxs/tmp/foo | tmp | 1430078524 | CREATED | 33860795 | | 0 | ---------------------------------------------------------------------------------------可以看到即使没有任何规则命中事件表中仍会生成并保留一行记录matches为空、count为 0。从实现角度看YARAEventSubscriber::Callbackyara_events.cpp会基于事件上下文填充action、target_path、category、transaction_id等列然后以事件的category为键在 yara 配置的file_paths中查找要执行的签名组列表对每个签名组调用yr_rules_scan_file以SCAN_FLAGS_FAST_MODE快速模式扫描命中信息由YARACallbackyara_utils.cpp汇总为逗号分隔的规则名、字符串含十六进制偏移、标签并累计count。yara_events表结构含eid隐藏列、macOS 扩展的transaction_id列定义于 specs/yara_events.table。按需扫描文件yara_file 表yara_file表别名yara用于按需扫描。通过它你可以使用配置中的任意签名文件或签名组对文件系统上任意可用文件执行 YARA 扫描。要进行扫描表必须同时收到“扫哪里”和“用什么扫”两类约束。扫哪里wherepath约束必须是单个文件的完整路径或者带通配符的path LIKE模式。该约束不做展开与递归——注意想使用通配符就必须用LIKE。用什么扫what通过sigfile或sig_group约束指定。sigfile必须是文件系统上签名文件的绝对路径不接受相对路径该签名文件只会在本次查询执行期间编译、用后即删sig_group则必须是配置文件中定义的命名签名组。yara_file表在行动中的几个示例osquery SELECT * FROM yara_file WHERE path/bin/ls AND sig_groupsig_group_1; --------------------------------------------------------------------- | path | matches | count | sig_group | sigfile | strings | tags | --------------------------------------------------------------------- | /bin/ls | always_true | 1 | sig_group_1 | | | | --------------------------------------------------------------------- osquery SELECT * FROM yara_file WHERE path/bin/ls AND sig_groupsig_group_2; ----------------------------------------------------------------- | path | matches | count | sig_group | sigfile | strings | tags | ----------------------------------------------------------------- | /bin/ls | | 0 | sig_group_2 | | | | -----------------------------------------------------------------如上所示同一个文件用两个不同签名组扫描会得到不同结果。osquery SELECT * FROM yara_file WHERE path LIKE /bin/%sh AND sig_groupsig_group_1; ------------------------------------------------------------------------- | path | matches | count | sig_group | sigfile | strings | tags | ------------------------------------------------------------------------- | /bin/bash | always_true | 1 | sig_group_1 | | | | | /bin/csh | always_true | 1 | sig_group_1 | | | | | /bin/ksh | always_true | 1 | sig_group_1 | | | | | /bin/sh | always_true | 1 | sig_group_1 | | | | | /bin/tcsh | always_true | 1 | sig_group_1 | | | | | /bin/zsh | always_true | 1 | sig_group_1 | | | | -------------------------------------------------------------------------上面的例子演示了用path LIKE约束配合签名组扫描/bin/%sh。LIKE约束的展开由genYaraFileScanImpl中的context.expandConstraints完成使用resolveFilePattern解析通配符GLOB_FILES | GLOB_NO_CANON逐一stat校验、isReadable检查并通过yaraShouldSkipFileyara_utils.cpp跳过非普通文件如/dev/x、/proc/x、FIFO 命名管道等避免扫描导致挂起。osquery select * from yara_file where path LIKE C:\tmp\% and sigfile C:\tmp\test.yar.txt; --------------------------------------------------------------------------------------------------------- | path | matches | count | sig_group | sigfile | strings | tags | --------------------------------------------------------------------------------------------------------- | C:\tmp\New Text Document.txt | TextExample | 1 | | C:\tmp\test.yar.txt | $text_string:0 | | | C:\tmp\test.yar.txt | TextExample | 1 | | C:\tmp\test.yar.txt | $text_string:35 | | ---------------------------------------------------------------------------------------------------------上例是sigfile绝对路径与path LIKE组合使用的示例。因为签名文件本身包含其规则所搜索的字符串所以它把自身也作为结果返回了。技巧在查询中追加AND count 0可以只返回 YARA 阳性命中结果。yara_file表的结构定义在 specs/yara_file.tablepath为必填索引列sig_group、sigfile为 additional 约束列sigrule与sigurl为隐藏列Linux 上还扩展了隐藏的pid_with_namespace列。注意yara_file有一个别名yara即yara_file与yara指向同一张表。扫描进程内存yara_process 表yara_process表扫描运行中进程的内存而非磁盘文件适用于检测内存驻留痕迹——例如加壳、注入或无文件型载荷这类内容不会出现在基于文件的扫描中。pid约束是必填的且必须是单个进程 ID。与yara_file的path不同pid不支持LIKE或通配符匹配要扫描多个进程请对processes表使用子查询让 osquery 计算pid IN (...)集合。命中/计数等列与yara_file一致matches、count、sig_group、sigfile、strings、tags另有隐藏的sigrule、sigurl列见 specs/yara_process.table。使用命名签名组扫描单个进程osquery SELECT * FROM yara_process WHERE pid 1234 AND sig_group sig_group_1; --------------------------------------------------------------- | pid | matches | count | sig_group | sigfile | strings | tags | --------------------------------------------------------------- | 1234 | always_true | 1 | sig_group_1 | | | | ---------------------------------------------------------------使用磁盘上的签名文件扫描所有运行中的进程并只返回阳性结果osquery SELECT yp.pid, p.name, yp.matches, yp.count ... FROM yara_process yp ... JOIN processes p USING (pid) ... WHERE yp.pid IN (SELECT pid FROM processes) ... AND yp.sigfile /etc/osquery/yara/suspicious.yar ... AND yp.count 0;使用内联规则扫描单个进程osquery SELECT * FROM yara_process WHERE pid 1234 ... AND sigrule rule has_mz { strings: $mz MZ condition: $mz };使用配置的signature_urls条目拉取的签名扫描进程osquery SELECT * FROM yara_process WHERE pid 1234 ... AND sigurl https://raw.githubusercontent.com/Yara-Rules/rules/master/cve_rules/CVE-2010-0805.yar;在 Linux 上隐藏列pid_with_namespace置为1可用于让宿主机级 osqueryd 扫描位于 PID 命名空间内例如容器中的进程osquery SELECT * FROM yara_process WHERE pid 4321 AND pid_with_namespace 1 AND sig_group sig_group_1;进程扫描注意事项读取其他进程的内存需要足够权限Linux/macOS 上通常为 rootWindows 上为启用了SeDebugPrivilege的提升会话。对受保护进程或内核邻近进程的扫描可能失败或返回空数据。Windows 实现中会使用SeDebugPrivilegeGuard在扫描期间启用调试令牌权限并在结束后复位见 yara.cpp。进程内存扫描比文件扫描昂贵得多——避免在生产主机上以高频率调度针对SELECT pid FROM processes的扫描。进程内存是不断变化的一次命中反映的是扫描时刻观测到的内存状态稍后可能无法复现。使用 sigrule 内联 YARA 规则除了本地文件与远程拉取的签名YARA 规则还可以随查询以内联方式提供即使用隐藏列sigrule作为约束。规则形式为rule rulename { condition: [whatever] }遵循标准 YARA 规则语法。例如osquery select * from yara_file where path /etc/passwd and sigrule rule always_true { condition: true };YARA 规则没有行终止符。要输入多行 YARA 规则直接使用换行即可——这在osqueryi中同样有效osquery select * from yara_file where path LIKE C:\tmp\% and sigrule rule hello_world { ... strings: ... $a Hello world ... condition: $a ... }; ------------------------------------------------------------------------------------- | path | matches | count | sig_group | sigfile | strings | tags | ------------------------------------------------------------------------------------- | C:\tmp\New Text Document.txt | hello_world | 1 | | | | | -------------------------------------------------------------------------------------注意内联输入sigrule时要小心避免先给规则加双引号、又给规则内的字符串变量加双引号——第二个会提前终止规则并导致syntax error。上面的例子中sigrule字符串用单引号包裹因此内部的变量Hello world可以安全使用双引号。由于允许任意 YARA 规则也就意味着可能通过strings列检索任意文件数据作为防护strings列默认返回空除非同时将隐藏 flagenable_yara_string设为true默认false。在 yara_utils.cpp 的compileFromString中可以看到若该 flag 未开启内联编译的所有规则字符串都会被标记为STRING_FLAGS_PRIVATE私有从而阻止经strings列回显。此外内联sigrule与远程sigurl的规则内容会以 SHA-256 哈希作为键缓存并在本次查询结束YaraState析构时从缓存中清理yara.cpp避免分布式查询反复执行造成缓存膨胀或哈希碰撞。测试用例佐证仓库的 yara_tests.cpp 提供了针对上述机制的单元测试例如定义always_true、always_false与非法规则invalid三种规则内容验证compileSingleFile的编译路径与错误路径进程扫描测试则在测试进程内存中放置十六进制哨兵字节序列DE AD BE EF CA FE BA BE配合process_scan_true/process_scan_false规则验证yara_process的扫描行为。这些测试由 tests/CMakeLists.txt 组织注册为osquery_tables_yara_tests-test并通过 osquery/tables/yara/CMakeLists.txt 在开启OSQUERY_BUILD_TESTS时构建。如需为 osquery 补充 YARA 规则或验证规则行为可参考该测试文件的写法。排错TroubleshootingYARA 编译错误YARA compile errorYARA 扫描前YARA 引擎会先编译规则。此处出现错误通常意味着规则本身有问题但首先要检查的是能否用 YARA 命令行工具运行同一条规则例如yara64.exe myYaraRule.yar fileToScan.foo。命令行工具会给出更有帮助的编译错误信息。如果命令行下规则能正常工作那可能确实遇到了 osquery 的 bug可以联系 osquery 团队反馈。在 osquery 侧编译错误信息由YARACompilerCallbackyara_utils.cpp以 verbose 日志输出会区分“来自规则文件的编译错误”与“来自规则字符串的编译错误”并带上文件名/行号与错误或警告级别。Error loading YARA rules: 8目前 osquery 只支持加载纯文本YARA 规则/签名并在运行时自行编译。如果这些规则已经被编译成二进制形式例如用yaracCLI 工具编译osquery 在加载规则时会报错。这与源码行为一致compileSingleFile会先尝试yr_rules_load加载预编译规则文件只有在其返回ERROR_INVALID_FILE即不是二进制规则文件时才回退到纯文本编译路径yara_utils.cpp。小结osquery 通过yara_events事件驱动持续监控、yara_file/yara按需文件扫描与yara_process进程内存扫描三张表将 YARA 规则引擎完整暴露为 SQL 接口。合理组织signatures签名组、file_paths监控路径与signature_urls远程规则配合enable_yara_string、yara_sigurl_authenticate、yara_delay每次文件扫描后休眠 50ms 以平滑内存尖峰见 yara.cpp等 flag即可在文件完整性与进程监控之上叠加一套可查询、可调度、可审计的恶意内容检测能力。更多表级细节可继续查阅 specs/yara_file.table、specs/yara_process.table、specs/yara_events.table 及 osquery/tables/yara 目录下的实现与测试。赞分享观测代理网络安全【免费下载链接】osquerySQL powered operating system instrumentation, monitoring, and analytics.项目地址https://gitcode.com/gh_mirrors/os/osquery点击查看免费下载相关推荐Apache Airflow 集成 Apache Drill 指南连接配置、SQLExecuteQueryOperator 查询与 DrillHook 底层原理Apache Airflow 集成 Apache Drill 指南连接配置、SQLExecuteQueryOperator 查询与 DrillHook 底层原后端任务调度工作流自动化数据编排批处理数据工程流程编排Metabase 连接 Amazon Redshift 完整指南连接配置、同步扫描与底层驱动原理Metabase 连接 Amazon Redshift 完整指南连接配置、同步扫描与底层驱动原理 Amazon Redshift 是 AWS 提供的托管型 P数据分析数据可视化后端数据库客户端企业应用TimescaleDB 查询优化SkipScan 与 Gapfill 自定义扫描节点原理与实战TimescaleDB 查询优化SkipScan 与 Gapfill 自定义扫描节点原理与实战 TimescaleDB 作为以 PostgreSQL 扩展形式时序数据库数据库关系型数据库上一篇Proxmark3 的 HiTag2 Attack 5 GPU 版ht2crack5gpu 的 OpenCL 位切片破解原理与实操下一篇终极Windows系统管理工具Chris Titus Tech WinUtil完整使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考