TEC-CYBE44-06 · Lesson 3 · 14 clock hours · lab
Searching, Filtering, and Query Languages
Objective. Students write targeted SIEM queries using the platform's search language to retrieve specific event sets, filter noise, and calculate basic statistics.
⚠ Pending professional review
This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.
VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.
Why SIEM Queries Matter
A SIEM platform collects logs from dozens or hundreds of sources—firewalls, endpoints, servers, cloud services—and stores them in a central index. Raw volume alone makes manual review impossible. A well-written query lets you cut through millions of events in seconds and surface exactly the activity you need to investigate. Weak or imprecise queries produce either too much noise (everything matches) or too little signal (nothing matches). Learning to write targeted queries is a core analyst skill and is tested on both CompTIA Security+ and CySA+.
Query Language Basics
Most enterprise SIEMs use a proprietary search language. Splunk uses Search Processing Language (SPL); Microsoft Sentinel uses Kusto Query Language (KQL); Elastic Stack uses Lucene syntax with optional EQL or KQL extensions. The concepts below apply broadly across platforms, though exact syntax differs. Always consult your platform's reference card during practice.
Keyword Search
The simplest query is a plain keyword. The engine searches every field in every indexed event for that string.
```
failed login
```
This returns any event containing both words. Keyword searches are useful for quick triage but produce false positives because the words may appear in unrelated fields.
Field Filter
When you know which field holds the value you care about, narrow your search to that field. This dramatically reduces noise.
SPL example: `source_ip="192.168.1.105"`
KQL example: `source_ip == "192.168.1.105"`
Field names are defined by the SIEM's data model or by the source log format. Common fields include `src_ip`, `dest_ip`, `user`, `action`, `event_id`, and `severity`.
Time-Range Filter
Logs grow continuously. Scoping your query to a time window keeps results relevant and reduces processing load. Most platforms let you set the time range in the UI picker, but you can also express it in the query itself.
SPL example: `earliest=-24h latest=now`
KQL example: `TimeGenerated > ago(24h)`
Always anchor queries to the time window relevant to the incident. Leaving the range open on a large index wastes resources and slows results.
Stats and Count by Field
Aggregation commands summarize events rather than listing them individually. The most common pattern is counting events grouped by a field value—for example, counting failed logins per user.
SPL: `stats count by user`
KQL: `summarize count() by user`
This produces a table showing each unique user and how many matching events exist for that user. Sorting descending (`sort -count` in SPL, `sort by count_ desc` in KQL) puts the highest-volume entries first.
Top N Values
A shortcut command returns the most frequent values of a field without writing a full stats-and-sort chain.
SPL: `top 10 src_ip`
This shows the ten source IPs that appear most often in the result set, with count and percentage columns automatically included. Use `top N` during initial triage to identify outliers or heavy hitters quickly.
Building Compound Queries
Real investigative queries chain multiple clauses together. A typical pattern in SPL uses the pipe character `|` to pass results from one command to the next:
```
index=main action="failure" earliest=-24h
| stats count by src_ip
| sort -count
| head 5
```
This query: (1) filters to failure events in the last 24 hours, (2) counts events per source IP, (3) sorts highest first, (4) returns the top five. Read a piped query left-to-right; each pipe narrows or transforms the previous result set.
In KQL, the same logic uses the `|` pipe and different command names:
```
SecurityEvent
| where Activity == "failure" and TimeGenerated > ago(24h)
| summarize count() by IpAddress
| sort by count_ desc
| take 5
```
Common Query Errors
Most broken queries fall into a small set of patterns:
- Misspelled field name – the field exists in the data model under a slightly different name; check the reference card.
- Missing or mismatched quotes – string values containing spaces must be quoted; forgetting the closing quote breaks the entire query.
- Wrong comparison operator – SPL uses `=` for equality inside a search; KQL uses `==`. Mixing them causes parse errors.
- Incorrect time syntax – `earliest=-24hours` will not parse in SPL; the correct unit is `h`, not `hours`.
- Pipe order mistake – placing a `where` filter after a `stats` command filters aggregated results, not raw events; the order matters.
- Case sensitivity – field names are often case-sensitive. `SRC_IP` and `src_ip` may be treated differently depending on platform configuration.
Responsible Use and Lab Safety
SIEM platforms have access to sensitive organizational data. In a production environment, analysts must operate under a defined authorization scope and handle query results as confidential. In this lab, you are working with a pre-loaded sample dataset (such as BOTS v3); do not attempt to connect your instance to live external systems or import data from outside the lab environment without instructor approval. Log off your instance when you finish. Do not share credentials for the lab platform with classmates; each student uses their own account so that query logs remain individually traceable for assessment.
Key terms9
SIEMSecurity Information and Event Management — a platform that collects, normalizes, and indexes log data from multiple sources so analysts can search and correlate events centrally.
SPL (Search Processing Language)The proprietary query language used in Splunk; commands are chained left-to-right with pipe characters to filter, transform, and aggregate events.
KQL (Kusto Query Language)The query language used in Microsoft Sentinel and Azure Monitor; it uses a pipe-based syntax similar to SPL but with different command names and operators.
Field filterA query clause that restricts results to events where a specific named field matches a given value, reducing noise compared to a plain keyword search.
AggregationA query operation that groups events and computes a summary statistic (such as count, sum, or average) across those groups rather than returning individual raw events.
Time-range filterA query parameter that limits results to events logged within a defined start and end time, keeping analysis focused and reducing processing load.
Top NA SIEM command that returns the N most frequently occurring values of a specified field, along with their counts and percentages.
IndexThe structured data store within a SIEM where ingested log events are saved and made searchable; queries typically target one or more named indexes.
Pipeline (pipe)In SIEM query languages, the `|` character that passes the output of one command as the input to the next, allowing multi-step data transformation in a single query.
Worked examples4
1. Write an SPL query that counts the number of failed login events per user over the last 48 hours and shows only the top three users by count.
- Start with the base search scoping to the correct index and action field: `index=main action="failure"`
- Add the time-range filter: append `earliest=-48h latest=now`
- Pipe to stats to count by user: `| stats count by user`
- Pipe to sort to order highest first: `| sort -count`
- Pipe to head to limit output to three rows: `| head 3`
Answer: `index=main action="failure" earliest=-48h latest=now | stats count by user | sort -count | head 3`
2. A broken SPL query reads: `index=main src_ip=10.0.0.5 earliest=-24hours | stats Count by dest_port`. Identify all errors and write the corrected query.
- Error 1: Time unit — SPL uses abbreviated units; `hours` is not valid. The correct form is `h`, so `earliest=-24h`.
- Error 2: Stats function capitalization — SPL functions are lowercase; `Count` should be `count`.
- No error exists in the field filter syntax (`src_ip=10.0.0.5`) or the pipe structure for this platform.
- Rewrite the query combining both fixes.
Answer: `index=main src_ip=10.0.0.5 earliest=-24h | stats count by dest_port`
3. Using KQL in Microsoft Sentinel, write a query that shows the top 5 source IP addresses with the most events of type 'PortScan' in the last 6 hours.
- Reference the correct table; assume events are in `SecurityAlert` and the alert type field is `AlertName`.
- Filter rows: `SecurityAlert | where AlertName == "PortScan" and TimeGenerated > ago(6h)`
- Aggregate by source IP — assume the field is `RemoteIP`: `| summarize count() by RemoteIP`
- Sort descending: `| sort by count_ desc`
- Limit to 5 results: `| take 5`
Answer: `SecurityAlert | where AlertName == "PortScan" and TimeGenerated > ago(6h) | summarize count() by RemoteIP | sort by count_ desc | take 5`
4. An analyst runs `index=main | top 5 src_ip | where count > 100` in SPL but gets no results even though high-volume IPs exist. Explain the logical error and write the corrected query.
- The `top` command returns a summary table with columns `src_ip`, `count`, and `percent`. SPL names the count column `count` in this output.
- The `where` filter after `top` filters the already-aggregated top-5 table. If none of those five rows has count > 100, zero rows are returned even if many IPs have count > 100 in the full dataset.
- Correct approach: use `stats count by src_ip`, apply the `where count > 100` filter first, then sort and limit to 5.
- Write the corrected query.
Answer: `index=main | stats count by src_ip | where count > 100 | sort -count | head 5`
In class: Guided practice: instructor demonstrates five foundational query patterns (keyword search, field filter, time-range filter, stats/count by field, top N values) using live data; students replicate each query on their own instance. · Query challenge: students receive a list of eight investigative questions (e.g., 'Which source IP generated the most failed SSH logins in the last 24 hours?') and must write a working query answering each one; queries are submitted as a query log. · Error-correction exercise: students receive six intentionally broken queries and must identify and fix the syntax error in each, explaining the mistake in a comment line.
Materials: SIEM instance with pre-loaded sample dataset (BOTS dataset v3 or equivalent open-source security dataset), query language reference card (SPL or KQL/Lucene depending on platform), lab workbook
Check: Students submit the query log with all eight investigative queries returning correct results; instructor spot-checks three queries live. Pass = 6 of 8 queries return accurate, relevant results.
Practice check8
Answer each question, then check it. Nothing is recorded; this is your own practice.
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.