哈希、存储、关联:基于ES|QL LOOKUP JOIN的现代日志去重解决方案
数据保真度的高成本:当更多数据并非更好时
在网络安全和可观测性领域,领导层面临一个持续困境:对完全可见性的非协商要求与有限预算的严峻现实之间的冲突。这种冲突在PowerShell日志记录中表现得最为明显。
对于任何拥有大量Windows环境现代企业而言,PowerShell是管理和自动化的引擎。然而,其强大功能和普遍性使其成为攻击者的主要目标,他们利用它进行无文件恶意软件执行、横向移动和凭据盗窃。
为了应对这种威胁,安全框架要求进行全面日志记录,特别是PowerShell脚本块日志记录(事件ID 4104)。这些日志对于威胁狩猎至关重要,因为它们捕获了攻击者运行的确切去混淆代码。然而,这种安全要求可能造成数据管理危机。启用完整脚本块日志记录会生成大量事件,可能产生TB级数据,导致显著的存储和索引成本。
潜力:大幅降低存储
让我们量化潜在收益。考虑一个现实企业场景:标准的9KB PowerShell健康检查脚本在10,000台服务器上每10分钟运行一次。这每天生成1,440,000个事件。该技术对存储消耗的影响是变革性的。
| 指标 | 优化前 | 优化后 | 影响 |
|---|---|---|---|
| 脚本文本存储/天 | 12.96GB | 9KB | 减少99.99% |
| 记录的总事件数 | 144万 | 144万(精简)+ 1(完整) | 事件元数据无损失 |
| 分析能力 | 完整脚本文本可用 | 按需提供完整脚本文本 | 保真度零损失 |
| 安全规则覆盖 | 完整 | 完整(通过查找索引扫描进行调查) | 零盲点创建 |
策略:哈希、存储一次、按需查找
该解决方案的核心原则是智能数据去重。在任何大型企业中,同一组用于健康检查、应用程序监控和管理任务的PowerShell脚本每天执行数百万次。传统方法在每次执行时捕获这些脚本的完整多KB文本,导致大量数据冗余。
考虑您的日常通勤。您不需要每次旅行都有新的详细地图;只需要一个说明:走了通常路线。我们的日志记录策略应用相同的逻辑。我们不每次都存储完整的"地图"(脚本文本),而是存储一次,然后简单地为每次执行记录一个轻量级引用——哈希。
该架构建立在三个支柱上:
事件克隆(Logstash):作为多功能服务器端数据处理管道,Logstash适用于复杂路由。我们将使用其克隆过滤器为每个PowerShell脚本块日志事件创建飞行中副本。
通过哈希去重(摄取管道):Elasticsearch摄取管道将处理原始事件和克隆事件。它生成脚本文本的唯一哈希,作为去重键。管道从原始事件中剥离庞大的脚本文本,将克隆转换为最小化的"查找"文档,仅包含脚本文本、相关元数据和安全检测规则及其哈希。"查找"文档存储在单分片查找索引中,重复项会自动覆盖。
按需丰富(ES|QL):ES|QL是支持原生联接的强大管道查询引擎。在查询时,分析师可以使用LOOKUP JOIN命令无缝地将精简事件元数据(如时间戳、主机和用户)与查找索引中的完整脚本文本重新结合,按需提供完整上下文。
实施展示
先决条件
开始前,确保环境满足以下要求:
- Elastic Stack版本8.18/9.0及更新版本
- 启用PowerShell日志记录
- Elastic Windows集成
- Logstash部署
- 了解数据特征
步骤1:设置查找索引
首先为查找索引创建模板,包括具有最小映射的组件模板和将index.mode设置为lookup的索引模板。
PUT _component_template/logs-windows.powershell_operational_lookup@package
{
"template": {
"settings": {
"index": {
"lifecycle": {
"name": "logs-powershell_script_block"
},
"default_pipeline": "logs-windows.powershell_operational-3.0.0",
"mapping": {
"total_fields": {
"limit": "1000"
}
}
}
},
"mappings": {
"properties": {
"@timestamp": {
"ignore_malformed": false,
"type": "date"
},
"powershell": {
"type": "object",
"properties": {
"file": {
"type": "object",
"properties": {
"script_block_text": {
"analyzer": "powershell_script_analyzer",
"type": "text"
},
"script_block_hash": {
"ignore_above": 1024,
"type": "keyword"
}
}
}
}
}
}
}
}
}
步骤2:Logstash中的事件处理
在Logstash管道中拦截PowerShell脚本块日志(事件ID 4104),并使用克隆过滤器创建副本。
filter {
if ([event][module] == "powershell" or [event][provider] == "Microsoft-Windows-PowerShell") and [event][code] == "4104" and [winlog][event_data][MessageTotal] == "1" {
clone {
clones => ["powershell_scriptblock_reduction"]
ecs_compatibility => v8
}
if !("powershell_scriptblock_reduction" in [tags]) {
mutate {
update => { "[data_stream][namespace]" => "default_reduced" }
add_field => {
"[fields][duplicated]" => true
}
}
}
}
}
步骤3:路由到不同目的地
使用Logstash输出配置将事件路由到不同目的地。
output {
if "powershell_scriptblock_reduction" in [tags]{
elasticsearch {
cloud_id => "..."
index => "logs-windows.powershell_operational_lookup-default"
action => "index"
api_key => "${ES_API}"
ssl_enabled => true
}
}
else {
elasticsearch {
cloud_id => "..."
data_stream => "true"
api_key => "${ES_API}"
ssl_enabled => true
}
}
}
步骤4:使用摄取管道处理
基于Elastic集成的摄取处理流程,两个事件都由自定义摄取管道处理,该管道使用条件逻辑根据在Logstash中添加的标志应用不同的处理器。
{
"processors": [
{
"remove": {
"ignore_missing": true,
"field": "message",
"if": "ctx.powershell?.file?.script_block_hash!= null && ctx.fields?.duplicated!= null && (ctx.fields?.duplicated == true || ctx.fields?.duplicated == 'true')"
}
},
{
"script": {
"if": "ctx.tags!= null && ctx.tags.contains('powershell_scriptblock_reduction') && ctx.powershell?.file?.script_block_hash!= null",
"source": "ctx._id = ctx.powershell.file.script_block_hash"
}
}
]
}
步骤5:使用ES|QL重建上下文
实施后,主数据流包含精简事件,查找索引保存唯一的非分段PowerShell脚本集。最后一步是在分析期间将这些上下文结合在一起。
FROM logs-windows.powershell_operational-default_reduced*
| WHERE powershell.file.script_block_hash IS NOT NULL
| RENAME @timestamp AS original_timestamp, user.id AS original_user.id
| LOOKUP JOIN logs-windows.powershell_operational_lookup-default-2025.06.26-000004 ON powershell.file.script_block_hash
| RENAME original_timestamp AS @timestamp, original_user.id AS user.id
更智能日志记录的一瞥
这种"哈希、存储、关联"模式展示了一种打破安全可见性和数据成本之间僵局的强大方法。它应被视为任何具有庞大或重复数据的高容量日志源(如API有效负载或应用程序堆栈跟踪)的可重用蓝图。
对于希望将数据优化提升到新水平的团队,该技术可以与其他功能分层使用。在使用此方法移除高容量、重复内容后,可以在主数据流上启用logsdb索引模式(在9.0及更高版本的集群上默认启用)。
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)或者 我的个人博客 https://blog.qife122.com/
公众号二维码

292

被折叠的 条评论
为什么被折叠?



