SigmaLens guide
SigmaLens is a small SIEM that runs inside this page. You load event logs, hunt through them with a search bar, and write Sigma rules that are tested against the data while you type. It never connects to the internet, and your files never leave your computer.
Getting started
- Click Open files (or drag files onto the page) and pick your logs:
.json/.jsonl. - Go to Search and type a query, or just scroll through the timeline.
- Found something interesting? Turn it into a rule in the Sigma editor and check that it matches what you expect, and nothing else.
You can load more files at any time. Events are added to what is already loaded, and Sigma rules (.yml) go to the Rules tab.
Loading data
SigmaLens reads JSON objects, one event each:
- JSONL (one object per line): the recommended format.
- A JSON array of objects.
- evtx_dump / python-evtx output (
{"Event":{"System":…,"EventData":…}}), which is flattened automatically:EventID,Channel,Computer,EventRecordID,Providerand@timestampcome from System, and every EventData value becomes its own field.
Other nested objects become dotted names, for example process.parent.name. The event time is taken from the first field present among @timestamp, TimeCreated, SystemTime, UtcTime, timestamp and time. A time without a zone is read as UTC, and all times on screen are UTC.
Converting .evtx files
Browsers can't read the binary .evtx format, so convert them first. On Windows, the bundled script uses only built-in cmdlets:
.\tools\evtx2jsonl.ps1 -Path .\Logs\*.evtx -OutDir .\jsonl
It writes one .jsonl per log, with the same field names you see in Event Viewer's XML view (for Sysmon: Image, CommandLine, ParentImage…).
The interface
- Top bar
- How many events are loaded and their time span, the Mapping selector (see Logsource mapping), Open files, a quick syntax card ? and light/dark mode ◐.
- Search
- Query bar and UTC time range, a timeline of the matching events, the fields panel and the results table.
- Sigma editor
- Write or paste a rule on the left and see its matches on the right. With live on, the rule runs as you type.
- Rules
- Every rule you loaded or saved, with its hit count after Run all.
Reading the results table
Each row shows the time, the log it came from (Sysmon, Security, PowerShell…), the event ID and a Details summary chosen per event type: the command line for a process, Image → IP:port for a connection, the query for DNS, the key and value for the registry, the script for PowerShell 4104.
Click a row to see every field. Next to each value you'll find three buttons:
- + keeps only events with this value: it adds
Field:"value"to the search. - − hides events with this value: it adds
NOT Field:"value". - σ copies the field as a Sigma line (
Field: 'value'), ready to paste into a rule.
Click the Time header to flip the sort order. Export CSV saves the current results.
Search syntax
The search language is close to Kibana and Lucene. Searches are case-insensitive, both for field names and for values.
| Query | Meaning | |
|---|---|---|
EventID:1 | Field equals the value (the whole value, not part of it). | |
Image:*\powershell.exe | * is a wildcard. *text* means "contains", text* "starts with", *text "ends with". | |
CommandLine:"*-w hidden*" | Quotes keep spaces inside one value. Wildcards still work inside quotes. | |
whoami | Free text: any field contains the word. | |
EventID:22 AND NOT QueryName:*.corp.example | AND, OR, NOT in capitals, or && || !. A leading - also negates. Two terms side by side mean AND. | |
(EventID:3 OR EventID:22) Image:*updsvc* | Parentheses group conditions. | |
DestinationPort:>=1024 | Numeric comparison: > >= < <=. | |
_exists_:ScriptBlockText | The field is present and not empty. Field:* does the same. |
Equals vs contains. CommandLine:whoami only matches a command line that is exactly whoami. To find it anywhere in the command line use CommandLine:*whoami*, or plain whoami to look in every field.
Backslashes are ordinary characters in the search bar: type Windows paths as they are, C:\Windows\System32\*.
Timeline & fields
The timeline shows how the matching events spread over time. Bar width adapts to the span (1 second up to 1 week). Hover a bar to see its count, and click it to zoom: the From/To boxes take that bar's range. Reset clears the query and the time range.
The fields panel lists every field in the current results and the share of events that have it. Click a field to see its 10 most common values and the number of distinct values, then use + / − to filter or Add as column to show it in the table. Spotting rare values is often the fastest way to find the attacker: try EventID:1 and look at the values of ParentImage.
Sigma editor
Sigma is an open, vendor-neutral format for detection rules. A rule says which logs to read (logsource), what to look for (named search identifiers under detection) and how to combine them (condition):
title: Discovery from PowerShell
logsource:
category: process_creation # which events (see Logsource mapping)
product: windows
detection:
parent: # a search identifier: all fields must match (AND)
ParentImage|endswith: '\powershell.exe'
tools: # a list of maps: any of them may match (OR)
- Image|endswith: '\nltest.exe'
- CommandLine|contains: 'Domain Admins'
condition: parent and tools
level: medium
- Run (or Ctrl+Enter) tests the rule against all loaded events. The time range on the Search tab doesn't apply here.
- With live checked, the rule runs again shortly after you stop typing.
- Under the editor you see the rule's title and level, and Reads: the exact events its logsource selects. If something is wrong (bad indentation, an unknown identifier in the condition, an unsupported modifier) the error is shown there and its line number turns red.
- Save to Rules stores the rule in the Rules tab. If you opened it from there, it updates it in place.
- Show in Search sends the matches to the Search tab, where you can use the timeline and fields panel on them.
The editor remembers your last rule in this browser.
Modifiers & values
Write a field as Field|modifier. A list of values means any of them. Matching is case-insensitive unless you add |cased.
| Modifier | Matches when the field… |
|---|---|
| (none) | equals the value (wildcards allowed) |
contains | contains the value |
startswith / endswith | starts / ends with the value |
all | matches every value in the list instead of any (e.g. CommandLine|contains|all) |
re | matches a JavaScript regular expression; add i, m, s for flags (|re|i) |
windash | also tries / and the long dashes wherever the value has a - flag (-enc, /enc, –enc…) |
cased | matches with exact capitalization |
exists | is present (true) or absent (false) |
gt gte lt lte | is a number above / below the value |
cidr | is an IPv4 address inside the range (10.0.0.0/8) |
Wildcards and escaping
In Sigma values, * matches any text and ? one character. A backslash only escapes those characters and itself: \* is a literal asterisk and \\ one literal backslash. Any other backslash is literal, so paths are written as usual: 'C:\Users\Public\'.
Common trap: 'C:\Users\*' does not mean "anything under C:\Users": \* is an escaped asterisk. Write Image|startswith: 'C:\Users\' or 'C:\Users\\*'.
Empty and missing fields
Field: null matches when the field is missing or empty. A condition like not filter on a field that some events don't have will let those events through. That's a frequent source of false negatives worth testing.
Conditions
selection | one search identifier |
selection and not filter | and, or, not, with parentheses for grouping |
1 of selection_* | at least one identifier whose name matches the pattern |
all of selection_* | every identifier matching the pattern |
1 of them / all of them | any / every identifier (names starting with _ are left out) |
A search identifier can also be a plain list of strings (keywords). It matches when any field of the event contains any of them.
Logsource mapping
The logsource decides which events a rule reads. product: windows plus a category selects events by log channel and event ID:
service selects a whole log: .
The Mapping selector in the top bar changes what process_creation reads:
- Sysmon (default): Sysmon event 1.
- Security: Security event 4688.
Image,ParentImage,ProcessIdandUserare filled fromNewProcessName,ParentProcessName,NewProcessIdandSubjectDomainName\SubjectUserName. Fields that only Sysmon has (OriginalFileName,Hashes…) stay empty. - Both: either source. One process may then match twice.
Rules view
Load one or many .yml files (a file may hold several rules separated by ---) and press Run all. Each rule shows its level, the events it reads and its hit count. Rules that fail to parse show the error instead. Open takes a rule to the editor, and ✕ removes it from the list (not from disk). Changing the Mapping re-checks every rule.
Workflow: from a hunt to a rule
A typical loop, using the demo dataset:
- Find something odd. Search for processes started by PowerShell:
- Understand it. Open the rows and read the command lines. Use the timeline to see what happened just before and after.
- Describe it as a rule. Copy the key fields with σ, paste them into the Sigma editor and generalize:
endswithinstead of a full path, a list instead of a single value. - Check true positives. The rule must match the malicious events you found.
- Check false positives. Look at everything else it matches. Too much? Add a precise
filter. - Check false negatives. Ask how an attacker could do the same thing and not match: a renamed binary, another file type, a different tool, a split command line. Test those variants too.
Shortcuts
| / | jump to the search bar |
| Enter | run the search |
| Ctrl+Enter | run the rule in the editor |
| Tab | indent 4 spaces in the editor |
Limits & privacy
- Not supported: aggregations (
| count() by …,timeframe), correlation rules, and thebase64,base64offset,utf16leandwidemodifiers. They're reported as errors, never silently ignored. - Everything is kept in memory. A few hundred thousand events work well on a normal laptop. Very large datasets are slower to search, and the live editor turns itself off above 300,000 events (use Run).
- Nothing is uploaded and no network requests are made. Only your preferences (last query, last rule, mapping, theme, tab) are stored in this browser's local storage.
SigmaLens · MIT License · Carlos Fernández (N4zar1). Sigma is an open standard maintained by SigmaHQ; SigmaLens is an independent project.