From 6c17fd749396bc9a421dc2ff4282aa91263edcf4 Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Wed, 3 Dec 2025 12:49:13 +0100 Subject: [PATCH 1/2] Add WMI persistence event subscriptions query (T1546.003) Comprehensive osquery query detecting WMI-based persistence: - Bound subscriptions (active filter-consumer chains) - Orphaned consumers (residual malware indicators) - Orphaned filters (incomplete cleanup detection) - Hash and authenticode enrichment for executables - Supports CommandLineEventConsumer and ActiveScriptEventConsumer Uses relative_path JOINs per osquery schema for accurate binding correlation. ECS mappings included for Elastic Security integration. --- ...-40033716-3580-48fe-a17d-441a838acd8a.json | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 packages/osquery_manager/kibana/osquery_saved_query/osquery_manager-40033716-3580-48fe-a17d-441a838acd8a.json diff --git a/packages/osquery_manager/kibana/osquery_saved_query/osquery_manager-40033716-3580-48fe-a17d-441a838acd8a.json b/packages/osquery_manager/kibana/osquery_saved_query/osquery_manager-40033716-3580-48fe-a17d-441a838acd8a.json new file mode 100644 index 00000000000..a402257db7d --- /dev/null +++ b/packages/osquery_manager/kibana/osquery_saved_query/osquery_manager-40033716-3580-48fe-a17d-441a838acd8a.json @@ -0,0 +1,87 @@ +{ + "attributes": { + "created_at": "2025-12-03T10:00:00.000Z", + "created_by": "elastic", + "description": "Detects WMI event subscriptions used for persistence (MITRE ATT&CK T1546.003). Includes bound subscriptions (active persistence) AND orphaned components (filters/consumers without bindings) which may indicate residual or partially removed malware. WMI eventing allows attackers to execute arbitrary commands or scripts when specific system events occur. Enriched with file hashes and code signatures for referenced executables and scripts.", + "ecs_mapping": [ + { + "key": "event.category", + "value": { + "value": ["configuration"] + } + }, + { + "key": "event.type", + "value": { + "value": ["info"] + } + }, + { + "key": "process.command_line", + "value": { + "field": "command_line_template" + } + }, + { + "key": "process.executable", + "value": { + "field": "executable_path" + } + }, + { + "key": "process.hash.md5", + "value": { + "field": "md5" + } + }, + { + "key": "process.hash.sha256", + "value": { + "field": "sha256" + } + }, + { + "key": "process.code_signature.subject_name", + "value": { + "field": "subject_name" + } + }, + { + "key": "process.code_signature.status", + "value": { + "field": "signature_status" + } + }, + { + "key": "file.path", + "value": { + "field": "script_file_name" + } + }, + { + "key": "threat.indicator.description", + "value": { + "field": "filter_query" + } + }, + { + "key": "tags", + "value": { + "value": ["persistence", "wmi", "event_subscription", "mitre_t1546_003"] + } + } + ], + "id": "wmi_persistence_event_subscriptions_windows_elastic", + "interval": "3600", + "platform": "windows", + "query": "-- WMI Persistence Event Subscriptions - Complete Coverage (T1546.003)\n-- Detects bound subscriptions and orphaned components for full forensic visibility\n-- Fixed: Uses relative_path for proper JOIN matching per osquery schema\n\nWITH wmi_subscriptions AS (\n -- Part 1: Bound subscriptions (complete filter-consumer chains)\n SELECT\n 'bound' AS status,\n filter.name AS filter_name,\n filter.query AS filter_query,\n filter.query_language,\n filter.class AS filter_class,\n COALESCE(cli.name, script.name) AS consumer_name,\n CASE\n WHEN cli.name IS NOT NULL THEN 'CommandLineEventConsumer'\n WHEN script.name IS NOT NULL THEN 'ActiveScriptEventConsumer'\n ELSE 'Unknown'\n END AS consumer_type,\n COALESCE(cli.class, script.class) AS consumer_class,\n COALESCE(cli.relative_path, script.relative_path) AS consumer_relative_path,\n cli.command_line_template,\n cli.executable_path,\n script.scripting_engine,\n script.script_file_name,\n script.script_text,\n COALESCE(\n NULLIF(cli.executable_path, ''),\n NULLIF(cli.command_line_template, ''),\n NULLIF(script.script_file_name, '')\n ) AS hashable_path\n FROM wmi_filter_consumer_binding binding\n LEFT JOIN wmi_event_filters filter ON binding.filter = filter.relative_path\n LEFT JOIN wmi_cli_event_consumers cli ON binding.consumer = cli.relative_path\n LEFT JOIN wmi_script_event_consumers script ON binding.consumer = script.relative_path\n\n UNION ALL\n\n -- Part 2: Orphaned CLI consumers (possible residual malware)\n SELECT\n 'orphaned_consumer' AS status,\n '' AS filter_name,\n '' AS filter_query,\n '' AS query_language,\n '' AS filter_class,\n cli.name AS consumer_name,\n 'CommandLineEventConsumer' AS consumer_type,\n cli.class AS consumer_class,\n cli.relative_path AS consumer_relative_path,\n cli.command_line_template,\n cli.executable_path,\n '' AS scripting_engine,\n '' AS script_file_name,\n '' AS script_text,\n COALESCE(NULLIF(cli.executable_path, ''), NULLIF(cli.command_line_template, '')) AS hashable_path\n FROM wmi_cli_event_consumers cli\n WHERE NOT EXISTS (\n SELECT 1 FROM wmi_filter_consumer_binding binding\n WHERE binding.consumer = cli.relative_path\n )\n\n UNION ALL\n\n -- Part 3: Orphaned Script consumers (possible residual malware)\n SELECT\n 'orphaned_consumer' AS status,\n '' AS filter_name,\n '' AS filter_query,\n '' AS query_language,\n '' AS filter_class,\n script.name AS consumer_name,\n 'ActiveScriptEventConsumer' AS consumer_type,\n script.class AS consumer_class,\n script.relative_path AS consumer_relative_path,\n '' AS command_line_template,\n '' AS executable_path,\n script.scripting_engine,\n script.script_file_name,\n script.script_text,\n NULLIF(script.script_file_name, '') AS hashable_path\n FROM wmi_script_event_consumers script\n WHERE NOT EXISTS (\n SELECT 1 FROM wmi_filter_consumer_binding binding\n WHERE binding.consumer = script.relative_path\n )\n\n UNION ALL\n\n -- Part 4: Orphaned filters (possible residual malware)\n SELECT\n 'orphaned_filter' AS status,\n filter.name AS filter_name,\n filter.query AS filter_query,\n filter.query_language,\n filter.class AS filter_class,\n '' AS consumer_name,\n '' AS consumer_type,\n '' AS consumer_class,\n '' AS consumer_relative_path,\n '' AS command_line_template,\n '' AS executable_path,\n '' AS scripting_engine,\n '' AS script_file_name,\n '' AS script_text,\n '' AS hashable_path\n FROM wmi_event_filters filter\n WHERE NOT EXISTS (\n SELECT 1 FROM wmi_filter_consumer_binding binding\n WHERE binding.filter = filter.relative_path\n )\n)\n\nSELECT\n ws.status,\n ws.filter_name,\n ws.filter_query,\n ws.query_language,\n ws.filter_class,\n ws.consumer_name,\n ws.consumer_type,\n ws.consumer_class,\n ws.consumer_relative_path,\n ws.command_line_template,\n ws.executable_path,\n ws.scripting_engine,\n ws.script_file_name,\n ws.script_text,\n h.md5,\n h.sha256,\n a.subject_name,\n a.result AS signature_status\nFROM wmi_subscriptions ws\nLEFT JOIN hash h ON h.path = ws.hashable_path AND ws.hashable_path != ''\nLEFT JOIN authenticode a ON a.path = ws.hashable_path AND ws.hashable_path != ''", + "updated_at": "2025-12-03T12:30:00.000Z", + "updated_by": "elastic" + }, + "coreMigrationVersion": "9.2.0", + "id": "osquery_manager-40033716-3580-48fe-a17d-441a838acd8a", + "references": [], + "type": "osquery-saved-query", + "updated_at": "2025-12-03T12:30:00.000Z", + "version": "WzEsMV0=" +} From d8f08b1b3bf5d4310212239546e98d5347b45ec5 Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Wed, 3 Dec 2025 12:49:25 +0100 Subject: [PATCH 2/2] Update artifacts matrix with WMI persistence coverage - Mark WMI Config & Used Apps (#23) as available - Mark WMI Providers & Filters (#24) as available - Add wmi_persistence_event_subscriptions to Additional Queries - Update coverage statistics: 2/46 artifacts now fully supported (4.3%) --- packages/osquery_manager/artifacts_matrix.md | 21 ++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/osquery_manager/artifacts_matrix.md b/packages/osquery_manager/artifacts_matrix.md index fb90f03f8b0..8c23acd8647 100644 --- a/packages/osquery_manager/artifacts_matrix.md +++ b/packages/osquery_manager/artifacts_matrix.md @@ -2,10 +2,10 @@ This document tracks the coverage of forensic artifacts in Osquery. -**Last Updated**: 2025-11-07 -**Total Core Artifacts**: 1 available + 39 in progress + 6 not available = 46 total variants -**Total Queries**: 30 (3 core forensic variants + 27 additional) -**Completion Rate**: 2.2% (1/46 core artifacts fully supported) +**Last Updated**: 2025-12-03 +**Total Core Artifacts**: 2 available + 38 in progress + 6 not available = 46 total variants +**Total Queries**: 31 (4 core forensic variants + 27 additional) +**Completion Rate**: 4.3% (2/46 core artifacts fully supported) --- @@ -13,8 +13,8 @@ This document tracks the coverage of forensic artifacts in Osquery. | Status | Count | Percentage | |--------|-------|------------| -| ✅ Available (Fully Supported) | 0 | 0% | -| ⚠️ In Progress (Needs Validation) | 39 | 87.0% | +| ✅ Available (Fully Supported) | 2 | 4.3% | +| ⚠️ In Progress (Needs Validation) | 38 | 82.6% | | ❌ Not Available (Requires Extensions) | 6 | 13.0% | --- @@ -66,8 +66,8 @@ This document tracks the coverage of forensic artifacts in Osquery. | 21a | Tasks | ⚠️ | Linux | - | - | scheduled_tasks table | | 21b | Tasks | ⚠️ | Mac | - | - | scheduled_tasks table | | 22 | User Assist | ⚠️ | Win | - | - | userassist table | -| 23 | WMI Config & Used Apps | ⚠️ | Win | - | - | wmi_cli_event_consumers, wmi_script_event_consumers | -| 24 | WMI Providers & Filters | ⚠️ | Win | - | - | wmi_event_filters, wmi_filter_consumer_binding | +| 23 | WMI Config & Used Apps | ✅ | Win | wmi_persistence_event_subscriptions | [4003](kibana/osquery_saved_query/osquery_manager-40033716-3580-48fe-a17d-441a838acd8a.json) | wmi_cli_event_consumers, wmi_script_event_consumers - Combined with #24 into single comprehensive query | +| 24 | WMI Providers & Filters | ✅ | Win | wmi_persistence_event_subscriptions | [4003](kibana/osquery_saved_query/osquery_manager-40033716-3580-48fe-a17d-441a838acd8a.json) | wmi_event_filters, wmi_filter_consumer_binding - Combined with #23 into single comprehensive query | | 25 | MFT | ❌ | Win | - | - | Not natively supported. Available via Trail of Bits extension | --- @@ -105,6 +105,7 @@ These queries existed in the original repository and provide additional coverage | 24 | unsigned_startup_items_vt | ✅ | Win | [b068](kibana/osquery_saved_query/osquery_manager-b0683c20-0dbb-11ed-a49c-6b13b058b135.json) | Unsigned startup items with VirusTotal integration | | 25 | unsigned_dlls_on_system_folders_vt | ✅ | Win | [63c1](kibana/osquery_saved_query/osquery_manager-63c1fe20-176f-11ed-89c6-331eb0db6d01.json) | Unsigned DLLs in system folders with VirusTotal integration | | 26 | executables_in_temp_folder_vt | ✅ | Win | [3e55](kibana/osquery_saved_query/osquery_manager-3e553650-17fd-11ed-89c6-331eb0db6d01.json) | Executables/drivers in temp folders with VirusTotal integration | +| 27 | wmi_persistence_event_subscriptions | ✅ | Win | [4003](kibana/osquery_saved_query/osquery_manager-40033716-3580-48fe-a17d-441a838acd8a.json) | WMI persistence detection (T1546.003) - bound subscriptions and orphaned components with hash/signature enrichment | **Note**: Queries with VirusTotal integration require the VirusTotal extension configured in osquery. @@ -162,8 +163,8 @@ While some artifacts are not directly available, the existing queries provide st - ⚠️ Persistence (All platforms: multiple tables) - ⚠️ Registry (Windows: registry table) - ⚠️ Tasks (All platforms: scheduled_tasks table) -- ⚠️ WMI Config & Used Apps (Windows: wmi_cli_event_consumers, wmi_script_event_consumers) -- ⚠️ WMI Providers & Filters (Windows: wmi_event_filters, wmi_filter_consumer_binding) +- ✅ WMI Config & Used Apps (Windows: wmi_cli_event_consumers, wmi_script_event_consumers) +- ✅ WMI Providers & Filters (Windows: wmi_event_filters, wmi_filter_consumer_binding) - ⚠️ BITS Jobs Database (Windows: via windows_eventlog) ### User Activity