Skip to content

Commit c13c7aa

Browse files
authored
[DOCS] EQL: Add sequence example to tutorial (#56965)
Adds an example using the sequence syntax to the 'Run an EQL search' tutorial. Supplements other examples added with #56721
1 parent 27cab68 commit c13c7aa

File tree

1 file changed

+243
-1
lines changed

1 file changed

+243
-1
lines changed

docs/reference/eql/search.asciidoc

Lines changed: 243 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,248 @@ https://en.wikipedia.org/wiki/Unix_time[Unix epoch], in ascending order.
127127
// TESTRESPONSE[s/"took": 60/"took": $body.took/]
128128
====
129129

130+
[discrete]
131+
[[eql-search-sequence]]
132+
=== Search for a sequence of events
133+
134+
Many query languages allow you to match single events. However, EQL's
135+
<<eql-sequences,sequence syntax>> lets you match an ordered series of events.
136+
137+
.*Example*
138+
[%collapsible]
139+
====
140+
The following EQL search request matches a sequence that:
141+
142+
. Starts with an event with:
143+
+
144+
--
145+
* An `event.category` of `file`
146+
* A `file.name` of `cmd.exe`
147+
--
148+
. Followed by an event with:
149+
+
150+
--
151+
* An `event.category` of `process`
152+
* A `process.name` that contains the substring `regsvr32`
153+
--
154+
155+
[source,console]
156+
----
157+
GET /sec_logs/_eql/search
158+
{
159+
"query": """
160+
sequence
161+
[ file where file.name == "cmd.exe" ]
162+
[ process where stringContains(process.name, "regsvr32") ]
163+
"""
164+
}
165+
----
166+
167+
The API returns the following response. Matching events in
168+
the `hits.sequences.events` property are sorted by
169+
<<eql-search-api-timestamp-field,timestamp>>, converted to milliseconds since
170+
the https://en.wikipedia.org/wiki/Unix_time[Unix epoch], in ascending order.
171+
172+
[source,console-result]
173+
----
174+
{
175+
"took": 60,
176+
"timed_out": false,
177+
"hits": {
178+
"total": {
179+
"value": 1,
180+
"relation": "eq"
181+
},
182+
"sequences": [
183+
{
184+
"events": [
185+
{
186+
"_index": "sec_logs",
187+
"_id": "4",
188+
"_score": null,
189+
"_source": {
190+
"@timestamp": "2020-12-07T11:07:08.000Z",
191+
"agent": {
192+
"id": "8a4f500d"
193+
},
194+
"event": {
195+
"category": "file"
196+
},
197+
"file": {
198+
"accessed": "2020-12-07T11:07:08.000Z",
199+
"name": "cmd.exe",
200+
"path": "C:\\Windows\\System32\\cmd.exe",
201+
"type": "file",
202+
"size": 16384
203+
},
204+
"process": {
205+
"name": "cmd.exe",
206+
"path": "C:\\Windows\\System32\\cmd.exe"
207+
}
208+
},
209+
"fields": {
210+
"@timestamp": [
211+
"1607339228000"
212+
]
213+
},
214+
"sort": [
215+
1607339228000
216+
]
217+
},
218+
{
219+
"_index": "sec_logs",
220+
"_id": "5",
221+
"_score": null,
222+
"_source": {
223+
"@timestamp": "2020-12-07T11:07:09.000Z",
224+
"agent": {
225+
"id": "8a4f500d"
226+
},
227+
"event": {
228+
"category": "process"
229+
},
230+
"process": {
231+
"name": "regsvr32.exe",
232+
"path": "C:\\Windows\\System32\\regsvr32.exe"
233+
}
234+
},
235+
"fields": {
236+
"@timestamp": [
237+
"1607339229000"
238+
]
239+
},
240+
"sort": [
241+
1607339229000
242+
]
243+
}
244+
]
245+
}
246+
]
247+
}
248+
}
249+
----
250+
// TESTRESPONSE[s/"took": 60/"took": $body.took/]
251+
252+
You can further constrain matching event sequences using the `by` keyword.
253+
254+
The following EQL search request adds `by agent.id` to each event item. This
255+
ensures events matching the sequence share the same `agent.id` field value.
256+
257+
[source,console]
258+
----
259+
GET /sec_logs/_eql/search
260+
{
261+
"query": """
262+
sequence
263+
[ file where file.name == "cmd.exe" ] by agent.id
264+
[ process where stringContains(process.name, "regsvr32") ] by agent.id
265+
"""
266+
}
267+
----
268+
269+
Because the `agent.id` field is shared across all events in the sequence, it
270+
can be included using `sequence by`. The following query is equivalent to the
271+
prior one.
272+
273+
[source,console]
274+
----
275+
GET /sec_logs/_eql/search
276+
{
277+
"query": """
278+
sequence by agent.id
279+
[ file where file.name == "cmd.exe" ]
280+
[ process where stringContains(process.name, "regsvr32") ]
281+
"""
282+
}
283+
----
284+
285+
The API returns the following response. The `hits.sequences.join_keys` property
286+
contains the shared `agent.id` value for each matching event.
287+
288+
[source,console-result]
289+
----
290+
{
291+
"took": 60,
292+
"timed_out": false,
293+
"hits": {
294+
"total": {
295+
"value": 1,
296+
"relation": "eq"
297+
},
298+
"sequences": [
299+
{
300+
"join_keys": [
301+
"8a4f500d"
302+
],
303+
"events": [
304+
{
305+
"_index": "sec_logs",
306+
"_id": "4",
307+
"_score": null,
308+
"_source": {
309+
"@timestamp": "2020-12-07T11:07:08.000Z",
310+
"agent": {
311+
"id": "8a4f500d"
312+
},
313+
"event": {
314+
"category": "file"
315+
},
316+
"file": {
317+
"accessed": "2020-12-07T11:07:08.000Z",
318+
"name": "cmd.exe",
319+
"path": "C:\\Windows\\System32\\cmd.exe",
320+
"type": "file",
321+
"size": 16384
322+
},
323+
"process": {
324+
"name": "cmd.exe",
325+
"path": "C:\\Windows\\System32\\cmd.exe"
326+
}
327+
},
328+
"fields": {
329+
"@timestamp": [
330+
"1607339228000"
331+
]
332+
},
333+
"sort": [
334+
1607339228000
335+
]
336+
},
337+
{
338+
"_index": "sec_logs",
339+
"_id": "5",
340+
"_score": null,
341+
"_source": {
342+
"@timestamp": "2020-12-07T11:07:09.000Z",
343+
"agent": {
344+
"id": "8a4f500d"
345+
},
346+
"event": {
347+
"category": "process"
348+
},
349+
"process": {
350+
"name": "regsvr32.exe",
351+
"path": "C:\\Windows\\System32\\regsvr32.exe"
352+
}
353+
},
354+
"fields": {
355+
"@timestamp": [
356+
"1607339229000"
357+
]
358+
},
359+
"sort": [
360+
1607339229000
361+
]
362+
}
363+
]
364+
}
365+
]
366+
}
367+
}
368+
----
369+
// TESTRESPONSE[s/"took": 60/"took": $body.took/]
370+
====
371+
130372
[discrete]
131373
[[eql-search-specify-event-category-field]]
132374
=== Specify an event category field
@@ -145,7 +387,7 @@ field.
145387
----
146388
GET /sec_logs/_eql/search
147389
{
148-
"event_category_field": "file.type",
390+
"event_category_field": "file.type",
149391
"query": """
150392
file where agent.id == "8a4f500d"
151393
"""

0 commit comments

Comments
 (0)