Documentation
¶
Overview ¶
Package sigmalite provides a parser and an execution engine for the Sigma detection format.
Example ¶
package main
import (
"fmt"
sigma "github.com/runreveal/sigmalite"
)
func main() {
rule, err := sigma.ParseRule([]byte(`
title: My example rule
detection:
keywords:
- foo
- bar
selection:
EventId: 1234
condition: keywords and selection
`))
if err != nil {
// Handle error...
}
entry := &sigma.LogEntry{
Message: "Hello foo",
Fields: map[string]string{
"EventId": "1234",
},
}
isMatch := rule.Detection.Matches(entry, nil)
fmt.Println("Rule:", rule.Title)
fmt.Println("Matches?", isMatch)
}
Output: Rule: My example rule Matches? true
Example (FieldResolver) ¶
package main
import (
"fmt"
sigma "github.com/runreveal/sigmalite"
)
// ExampleResolver demonstrates custom field resolution
type ExampleResolver struct{}
func (r *ExampleResolver) Resolve(fieldName string, entry *sigma.LogEntry) []string {
switch fieldName {
case "process.users":
var users []string
if user, ok := entry.Fields["Event.Process.User"]; ok {
users = append(users, user)
}
if user, ok := entry.Fields["Event.Login.User"]; ok {
users = append(users, user)
}
if user, ok := entry.Fields["Event.Session.User"]; ok {
users = append(users, user)
}
return users
default:
return nil
}
}
func main() {
// Example demonstrating custom field resolution
rule, err := sigma.ParseRule([]byte(`
title: Field Resolver Example
detection:
selection:
process.users: "administrator"
condition: selection
`))
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
resolver := &ExampleResolver{}
opts := &sigma.MatchOptions{
FieldResolver: resolver,
}
// This entry will match because the resolver finds "administrator" in Event.Process.User
entry1 := &sigma.LogEntry{
Fields: map[string]string{
"Event.Process.User": "administrator",
"Event.Process.Name": "cmd.exe",
},
}
// This entry will also match because the resolver finds "administrator" in Event.Session.User
entry2 := &sigma.LogEntry{
Fields: map[string]string{
"Event.Session.User": "administrator",
"Event.Session.Type": "Remote",
},
}
// This entry won't match because no user field contains "administrator"
entry3 := &sigma.LogEntry{
Fields: map[string]string{
"Event.Process.User": "regular_user",
"Event.Login.User": "guest_user",
},
}
fmt.Println("Rule:", rule.Title)
fmt.Println("Entry 1 matches?", rule.Detection.Matches(entry1, opts))
fmt.Println("Entry 2 matches?", rule.Detection.Matches(entry2, opts))
fmt.Println("Entry 3 matches?", rule.Detection.Matches(entry3, opts))
}
Output: Rule: Field Resolver Example Entry 1 matches? true Entry 2 matches? true Entry 3 matches? false
Index ¶
Examples ¶
Constants ¶
const EmDash = "—"
const EnDash = "–"
const HorizontalBar = "―"
Variables ¶
var WinDashMatcher = regexp.MustCompile(`\B[-/]\b`)
Functions ¶
This section is empty.
Types ¶
type AndExpr ¶
type AndExpr struct {
X []Expr
}
AndExpr is an Expr that evaluates to true if and only if all of its sub-expressions evaluate to true.
func (*AndExpr) ExprMatches ¶
func (a *AndExpr) ExprMatches(entry *LogEntry, opts *MatchOptions) bool
type Date ¶
type Date struct {
// contains filtered or unexported fields
}
A Date is a Gregorian date. The zero value is January 1, year 1.
func NewDate ¶
NewDate returns the Date with the given values. The arguments may be outside their usual ranges and will be normalized during the conversion.
func (Date) MarshalText ¶
MarshalText formats the date in Sigma's YYYY/MM/DD format, like "2006-01-02".
func (*Date) UnmarshalText ¶
UnmarshalText parses a date in Sigma format (i.e. "YYYY/MM/DD").
type Detection ¶
type Detection struct {
Expr Expr
}
Detection describes the pattern that a Rule is matching on.
type Expr ¶
type Expr interface {
ExprMatches(*LogEntry, *MatchOptions) bool
}
An Expr is a sub-expression inside of a Detection.
ExprMatches reports whether an entry matches the expression. Implementations of ExprMatches must be safe to call concurrently from multiple goroutines.
type FieldResolver ¶
FieldResolver allows custom field lookup logic. The Resolve method takes a field name and returns all matching values. This enables complex field resolution including wildcards, arrays, nested objects, etc. If no matches are found, it should return nil or an empty slice.
type Level ¶
type Level string
Level is an enumeration of the criticalities of a triggered Rule.
const ( // Informational indicates a rule is intended for enrichment of events, // e.g. by tagging them. // No case or alerting should be triggered by such rules // because it is expected that a huge amount of events will match these rules. Informational Level = "informational" // Low indicates that a rule is a notable event but rarely an incident. // Low rated events can be relevant in high numbers or combination with others. // Immediate reaction shouldn't be necessary, but a regular review is recommended. Low Level = "low" // Medium indicates that a rule is a relevant event that should be reviewed manually // on a more frequent basis. Medium Level = "medium" // High indicates that a rule is a relevant event that should trigger an internal alert // and requires a prompt review. High Level = "high" // Critical indicates that a rule is a highly relevant event that indicates an incident. // Critical events should be reviewed immediately. // It is used only for cases in which probability borders certainty. Critical Level = "critical" )
Defined levels.
type MatchOptions ¶
type MatchOptions struct {
Placeholders map[string][]string
// FieldResolver provides optional custom field lookup logic.
// If nil, standard field lookup is used (exact match, then case-insensitive).
FieldResolver FieldResolver
}
MatchOptions are the parameters to Detection.Matches and Expr.ExprMatches.
type NamedExpr ¶
NamedExpr is an Expr that has a name. These are referred to as "search identifiers" in the specification.
func (*NamedExpr) ExprMatches ¶
func (n *NamedExpr) ExprMatches(entry *LogEntry, opts *MatchOptions) bool
type NotExpr ¶
type NotExpr struct {
X Expr
}
NotExpr is a negated Expr.
func (*NotExpr) ExprMatches ¶
func (x *NotExpr) ExprMatches(entry *LogEntry, opts *MatchOptions) bool
type OrExpr ¶
type OrExpr struct {
X []Expr
}
OrExpr is an Expr that evaluates to true if at least one of its sub-expressions evaluate to true.
func (*OrExpr) ExprMatches ¶
func (o *OrExpr) ExprMatches(entry *LogEntry, opts *MatchOptions) bool
type Relation ¶
type Relation struct {
ID string
Type RelationType
}
Relation is a reference to another related rule.
type RelationType ¶
type RelationType string
RelationType is an enumeration of relation types.
const ( // Derived signals the rule was derived from the referred rule or rules, // which may remain active. Derived RelationType = "derived" // Obsoletes signals the rule obsoletes the referred rule or rules, // which aren't used anymore. Obsoletes RelationType = "obsoletes" // Merged signals the rule was merged from the referred rules. // The rules may be still existing and in use. Merged RelationType = "merged" // Renamed signals the rule had previously the referred identifier or identifiers // but was renamed for whatever reason, // e.g. from a private naming scheme to UUIDs, to resolve collisions etc. // It's not expected that a rule with this id exists anymore. Renamed RelationType = "renamed" // Similar is used to relate similar rules to each other // (e.g. same detection content applied to different log sources, // rule that is a modified version of another rule with a different level). Similar RelationType = "similar" )
Defined relation types.
func (RelationType) IsKnown ¶
func (typ RelationType) IsKnown() bool
IsKnown reports whether the relation type string matches one of the known constants.
type Rule ¶
type Rule struct {
// Title is a short description of what the rule detects.
Title string
// ID is an optional globally unique identifier for the rule.
ID string
// Related is a set of references to other rules.
Related []Relation
// Status is an optional indicator of the stability of the rule.
Status Status
// Description is a long-form description of what the rule detects.
Description string
// References is a set of references that the rule was derived from.
// By convention, this is a set of URLs.
References []string
// Author is the creator of the rule.
Author string
// Date is the creation date of the rule.
Date Date
// Modified is the last modification date of the rule.
// By convention, Modified is updated whenever
// the Detection, Level, LogSource, or Title is changed,
// or whenever Status changes to [Deprecated].
Modified Date
// Tags is a set of categories applied to the rule.
// See https://github.com/SigmaHQ/sigma-specification/blob/main/Tags_specification.md
// for more details.
Tags []string
// Level indicates the criticality of the rule.
Level Level
// LogSource describes the log data on which the detection is meant to be applied to.
LogSource *LogSource
// Detection describes the pattern that a rule is matching on.
Detection *Detection
// Fields is a list of log fields that could be interesting in further analysis of the event
// and should be displayed to the analyst.
Fields []string
// FalsePositives is a list of known false positives that may occur.
FalsePositives []string
// Extra is a set of YAML nodes for the unprocessed top-level fields.
Extra map[string]Decoder
}
Rule represents a parsed Sigma rule file.
type SearchAtom ¶
type SearchAtom struct {
// Field is the name of the field to match against.
// If empty, then this matches against the message.
Field string
// Modifiers is a sequence of zero or more modifiers to apply against the field
// before checking Patterns.
Modifiers []string
// Patterns is the set of patterns to check against the field.
// If one of them matches, then the field matches this atom.
Patterns []string
// contains filtered or unexported fields
}
A SearchAtom is an Expr that matches against a single field.
func (*SearchAtom) ExprMatches ¶
func (atom *SearchAtom) ExprMatches(entry *LogEntry, opts *MatchOptions) bool
func (*SearchAtom) Validate ¶
func (atom *SearchAtom) Validate() error
Validate returns an error if the search atom won't match because the modifiers or patterns are invalid.
type Status ¶
type Status string
Status is an enumeration of Rule stability classifications.
const ( // Stable indicates that the rule didn't produce any obvious false positives // in multiple environments over a long period of time. Stable Status = "stable" // Test indicates that the rule doesn't show any obvious false positives // on a limited set of test systems. Test Status = "test" // Experimental indicates a new rule that hasn't been tested outside of lab environments // and could lead to many false positives. Experimental Status = "experimental" // Deprecated indicates the rule is to replace or cover another one. // The link between both rules is made via the related field. Deprecated Status = "deprecated" // Unsupported indicates the rule can not be used in its current state // (special correlation log, home-made fields, etc.). Unsupported Status = "unsupported" )
Defined statuses.