Synthèse
The curl and wget ES|QL COMPLETION triage rules follow the same structure. They’re additive companions to existing deterministic rules, not replacements. The original rules remain enabled, while the LLM-triage versions focus on the events that survive the known-good filters. The flow is intentionally conservative: Select Linux process execution events where process.name is curl or wget. Build a normalized argument string from process.args. Parse a destination host from a schema://host URL. Drop
The curl and wget ES|QL COMPLETION triage rules follow the same structure. They’re additive companions to existing deterministic rules, not replacements. The original rules remain enabled, while the LLM-triage versions focus on the events that survive the known-good filters. The flow is intentionally conservative: Select Linux process execution events where process. name is curl or wget.
Build a normalized argument string from process. args. Parse a destination host from a schema://host URL. Drop events without a parsed destination. Apply deterministic allow-lists for known package repositories, metadata endpoints, internal services, and expected automation.
Redact credentials and tokens from the command line. Aggregate by host and destination. Cap the rows sent to COMPLETION. Ask the LLM for a structured verdict. Alert only on TP or SUSPICIOUS results with confidence above 0.
7. Here’s a generic version of that shape. Your own rule should split curl and wget if they need different allow-lists, but the core approach is the same. /* 1. Select Linux curl/wget process-execution events that carry arguments.
Point FROM at the index patterns where your process events live. ECS data tags process events with event. category "process"; Auditbeat uses event. action "executed". */ FROM logs-endpoint.
events. process-*, logs-auditd_manager. auditd-*, auditbeat-* | WHERE (event. category == "process" OR event. action == "executed") AND process.
name IN ("curl", "wget") AND process. args IS NOT NULL /* 2-4. Normalize the arguments, parse the schema://host destination, and drop events where no destination could be parsed, for example a curl or wget run with only -h or -v and no URL to download. */ | EVAL Esql. args_str = CONCAT(" ", MV_CONCAT(process.
args, " ")) | EVAL Esql. full_command_line = COALESCE(process. command_line, process. title, Esql. args_str) | EVAL Esql.
full_command_line = MV_CONCAT(Esql. full_command_line, " ") | GROK Esql.
Source originale
elastic.co