engine

package
v2.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 2, 2022 License: GPL-3.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	//TypeOperand constant to type a ConditionElement
	TypeOperand = 0x1 << iota
	//TypeOperator constant to type a ConditionElement
	TypeOperator
	//TypeNegate constant to type a ConditionElement
	TypeNegate
)
View Source
const (
	CriticalityBound = 10
)

Variables

View Source
var (
	//ErrEOT End Of Tokens
	ErrEOT = fmt.Errorf("End of tokens")
	//ErrUnexpectedToken definition
	ErrUnexpectedToken = fmt.Errorf("Unexpected tokens")
	//ErrEmptyToken definition
	ErrEmptyToken = fmt.Errorf("Empty token")
)
View Source
var (

	// DefaultRuleExtensions default extensions for rule files
	DefaultRuleExtensions = datastructs.NewInitSyncedSet(".gen", ".gene")
	// DefaultTplExtensions default extensions for template files
	DefaultTplExtensions           = datastructs.NewInitSyncedSet(".toml")
	EngineMinimalRuleSchemaVersion = ParseVersion("2.0.0")
)
View Source
var (

	// GeneInfoPath path to the Gene information in a modified event
	GeneInfoPath = Path("/Event/GeneInfo")

	ErrItemNotFound = errors.New("item not found")
)
View Source
var (
	//ErrContainerAlreadyExists should be returned in case an container name is already used in Containers
	ErrContainerAlreadyExists = fmt.Errorf("Already existing container")
)
View Source
var (
	//ErrUnkOperator error to return when an operator is not known
	ErrUnkOperator = fmt.Errorf("Unknown operator")
)

Functions

func Compute

func Compute(ce *ConditionElement, operands OperandReader) bool

Compute computes a given condition given the operands

func EventGetString

func EventGetString(evt Event, p *XPath) (string, bool)

func GetOperands

func GetOperands(ce *ConditionElement) []string

GetOperands retrieves all the operands involed in a condition

func IsContainerMatch

func IsContainerMatch(s string) bool

IsContainerMatch returns true if match is compliant with ContainerMatch syntax

func IsFieldMatch

func IsFieldMatch(s string) bool

IsFieldMatch returns true if s compiliant with FieldMatch syntax

func Pretty

func Pretty(c *ConditionElement, group bool) string

func PrettySplit

func PrettySplit(split []*ConditionElement) string

Types

type Attack

type Attack struct {
	ID          string
	Tactic      string
	Description string `json:",omitempty"`
	Reference   string
}

Attack structure definiton to encode information from ATT&CK Mitre

type CompiledRule

type CompiledRule struct {
	Name        string
	Criticality int
	EventFilter EventFilter
	Computers   *datastructs.SyncedSet
	Tags        *datastructs.SyncedSet
	AtomMap     *datastructs.SyncedMap
	Disabled    bool // Way to deal with no container issue
	Filter      bool // whether it is a Filter rule or not
	Conditions  *ConditionElement
	Actions     []string
	// ATT&CK information
	Attack []Attack
	Schema Version
	// contains filtered or unexported fields
}

CompiledRule definition

func Load

func Load(b []byte, containers *ContainerDB) (*CompiledRule, error)

Load loads rule to EvtxRule

func NewCompiledRule

func NewCompiledRule(schema Version) (er CompiledRule)

NewCompiledRule initializes and returns an EvtxRule object

func (*CompiledRule) AddMatcher

func (er *CompiledRule) AddMatcher(m Matcher)

AddMatcher adds an atom rule to the CompiledRule func (er *CompiledRule) AddMatcher(a *AtomRule) {

func (*CompiledRule) Match

func (er *CompiledRule) Match(evt Event) bool

Match returns whether the CompiledRule matches the EVTX event

func (*CompiledRule) SetContainers

func (er *CompiledRule) SetContainers(containers *ContainerDB)

SetContainers sets the ContainerDB pointer of rule

type ConditionElement

type ConditionElement struct {
	Operand  string
	Operator rune
	Negate   bool
	Level    int
	Group    int
	Type     int
	Next     *ConditionElement
	Prev     *ConditionElement
}

ConditionElement structure definition

func (*ConditionElement) DebugString

func (c *ConditionElement) DebugString() string

DebugString formats a ConditionElement to be nicely printed

func (*ConditionElement) GetGroup

func (ce *ConditionElement) GetGroup() []*ConditionElement

GetGroup retrieves an array with the condition elements part of the same group as current condition

func (*ConditionElement) GetLevels

func (ce *ConditionElement) GetLevels(lvl int) [][]*ConditionElement

GetLevels retrieve all the levels from condition

func (*ConditionElement) Pretty

func (c *ConditionElement) Pretty(group bool) string

func (*ConditionElement) Prioritize

func (ce *ConditionElement) Prioritize()

Prioritize creates precedence between boolean operators

func (*ConditionElement) Simplify

func (ce *ConditionElement) Simplify()

Simplify condition

func (*ConditionElement) String

func (c *ConditionElement) String() string

type ContainerDB

type ContainerDB map[string]*datastructs.SyncedSet

ContainerDB structure used to store several containers

func NewContainers

func NewContainers() *ContainerDB

NewContainers initializes a new Containers structure

func (*ContainerDB) AddContainer

func (c *ContainerDB) AddContainer(name string, container *datastructs.SyncedSet) error

AddContainer adds a new container to c

func (*ContainerDB) AddNewContainer

func (c *ContainerDB) AddNewContainer(name string) error

AddNewContainer adds an empty container to the DB

func (*ContainerDB) AddStringToContainer

func (c *ContainerDB) AddStringToContainer(name string, values ...string)

AddStringToContainer adds new strings (converted to lower case) into a container and creates a new container if it does not exist yet.

func (*ContainerDB) AddToContainer

func (c *ContainerDB) AddToContainer(name string, values ...interface{})

AddToContainer adds a new value into a container and creates a new container if it does not exist yet

func (*ContainerDB) Contains

func (c *ContainerDB) Contains(name string, value string) bool

Contains checks if named container contains value

func (*ContainerDB) ContainsString

func (c *ContainerDB) ContainsString(name string, value string) bool

ContainsString checks if named container contains value ignoring value case

func (*ContainerDB) Get

func (c *ContainerDB) Get(name string) (*datastructs.SyncedSet, bool)

Get get a container by its name

func (*ContainerDB) Has

func (c *ContainerDB) Has(name string) bool

Has checks if a named container is in the DB

func (*ContainerDB) Len

func (c *ContainerDB) Len(name string) int

Len gives the size of a Container

func (*ContainerDB) String

func (c *ContainerDB) String() string

type ContainerMatch

type ContainerMatch struct {
	Name      string `regexp:"name"`
	RexName   string `regexp:"rexname"`
	Regexp    string `regexp:"regexp"`
	Operand   string `regexp:"operand"`
	Container string `regexp:"container"`
	// contains filtered or unexported fields
}

ContainerMatch atomic extract structure

func NewContainerMatch

func NewContainerMatch() *ContainerMatch

NewContainerMatch creates a new ContainerMatch structure

func ParseContainerMatch

func ParseContainerMatch(extract string) (ae *ContainerMatch, err error)

ParseContainerMatch parses an extract and returns an AtomExtract from it

func (*ContainerMatch) Compile

func (c *ContainerMatch) Compile() (err error)

Compile compiles an AtomExtract, any AtomExtract must be compiled before use

func (*ContainerMatch) Extract

func (c *ContainerMatch) Extract(evt Event) (string, bool)

Extract uses the AtomExtract to extract a substring from a value of a Windows Event

func (*ContainerMatch) ExtractFromString

func (c *ContainerMatch) ExtractFromString(s string) (string, bool)

ExtractFromString uses the AtomExtract to extract a substring from s

func (*ContainerMatch) GetName

func (c *ContainerMatch) GetName() string

GetName implements Matcher interface

func (*ContainerMatch) Match

func (c *ContainerMatch) Match(evt Event) bool

Match matches the extract rule against a ContainerDB and implements Matcher interface the string matched against the container are converted to lower case (default behaviour of ContainsString method)

func (*ContainerMatch) SetContainerDB

func (c *ContainerMatch) SetContainerDB(db *ContainerDB)

SetContainerDB sets the containerDB member

func (*ContainerMatch) String

func (c *ContainerMatch) String() string

type Detection

type Detection struct {
	Signature   *datastructs.Set
	Criticality int
	ATTACK      []Attack         `json:",omitempty"`
	Actions     *datastructs.Set `json:",omitempty"`
	// contains filtered or unexported fields
}

func NewDetection

func NewDetection(attack, action bool) *Detection

func (*Detection) AlsoMatchedFilter

func (d *Detection) AlsoMatchedFilter() bool

func (*Detection) Count

func (d *Detection) Count() int

func (*Detection) IsAlert

func (d *Detection) IsAlert() bool

func (*Detection) Names

func (d *Detection) Names() []string

func (*Detection) OnlyMatchedFilters

func (d *Detection) OnlyMatchedFilters() bool

func (*Detection) Update

func (d *Detection) Update(r *CompiledRule)

type Engine

type Engine struct {
	sync.RWMutex

	// engine statistics
	Stats       Stats
	ShowActions bool
	ShowAttack  bool
	// contains filtered or unexported fields
}

Engine defines the engine managing several rules

func NewEngine

func NewEngine() (e *Engine)

NewEngine creates a new engine

func (*Engine) AddToContainer

func (e *Engine) AddToContainer(container, value string)

AddToContainer adds a value to a given container and creates it if needed the string pushed to the container is lower cased (behaviour of AddSTringToContainer)

func (*Engine) Blacklist

func (e *Engine) Blacklist(value string)

Blacklist insert a value to be blacklisted

func (*Engine) BlacklistLen

func (e *Engine) BlacklistLen() int

BlacklistLen returns the size of the blacklist

func (*Engine) Count

func (e *Engine) Count() int

Count returns the number of rules successfuly loaded

func (*Engine) GetCRuleByName

func (e *Engine) GetCRuleByName(name string) (r *CompiledRule)

GetCRuleByName gets a compile rule by its name

func (*Engine) GetRawRule

func (e *Engine) GetRawRule(regex string) (cs chan string)

GetRawRule returns the raw rule according to its name it is convenient to get the rule after template replacement

func (*Engine) GetRawRuleByName

func (e *Engine) GetRawRuleByName(name string) string

GetRawRuleByName returns the raw rule for a given rule name

func (*Engine) GetRuleNames

func (e *Engine) GetRuleNames() (names []string)

GetRuleNames returns a slice of containing the names of all the rules loaded in the engine

func (*Engine) LoadBytes added in v2.2.0

func (e *Engine) LoadBytes(data []byte) error

LoadBytes loads rules from []byte data

func (*Engine) LoadContainer

func (e *Engine) LoadContainer(container string, reader io.Reader) error

LoadContainer loads every line found in reader into the container

func (*Engine) LoadDirectory

func (e *Engine) LoadDirectory(rulesDir string) error

LoadDirectory loads all the templates and rules inside a directory

func (*Engine) LoadFile added in v2.2.0

func (e *Engine) LoadFile(rulefile string) error

LoadFile loads a rule file into the current engine

func (*Engine) LoadReader

func (e *Engine) LoadReader(reader io.ReadSeeker) error

LoadReader loads rule from a ReadSeeker

func (*Engine) LoadRule added in v2.2.0

func (e *Engine) LoadRule(rule *Rule) error

func (*Engine) LoadString added in v2.2.0

func (e *Engine) LoadString(data string) error

LoadString loads rules from string data

func (*Engine) LoadTemplate

func (e *Engine) LoadTemplate(templatefile string) error

LoadTemplate loads a template from a file

func (*Engine) MatchOrFilter

func (e *Engine) MatchOrFilter(evt Event) (names []string, criticality int, filtered bool)

MatchOrFilter checks if there is a match in any rule of the engine. The only difference with Match function is that it also return a flag indicating if the event is filtered.

func (*Engine) SetDefaultActions

func (e *Engine) SetDefaultActions(low, high int, actions []string)

SetDefaultActions sets default actions given to event reaching certain criticality within [low; high]

func (*Engine) SetDumpRaw

func (e *Engine) SetDumpRaw(value bool)

SetDumpRaw setter for dumpRaw flag

func (*Engine) SetFilters

func (e *Engine) SetFilters(names, tags []string)

SetFilters sets the filters to use in the engine

func (*Engine) SetShowAttck

func (e *Engine) SetShowAttck(value bool)

SetShowAttck sets engine flag to display ATT&CK information in matching events Update: member was private before, this method is kept for compatibility purposes

func (*Engine) Tags

func (e *Engine) Tags() []string

Tags returns the tags of the rules currently loaded into the engine

func (*Engine) Whitelist

func (e *Engine) Whitelist(value string)

Whitelist insert a value to be whitelisted

func (*Engine) WhitelistLen

func (e *Engine) WhitelistLen() int

WhitelistLen returns the size of the whitelist

type ErrRuleExist

type ErrRuleExist struct {
	// contains filtered or unexported fields
}

ErrRuleExist definition

func (ErrRuleExist) Error

func (e ErrRuleExist) Error() string

Error error implementation

type Event

type Event interface {
	Set(*XPath, interface{}) error
	SetDetection(d *Detection)
	Get(*XPath) (interface{}, bool)
	GetDetection() *Detection
	Channel() string
	Computer() string
	EventID() int64
	Timestamp() time.Time
}

type EventFilter

type EventFilter map[string]*datastructs.Set

func NewEventFilter

func NewEventFilter(m map[string][]int64) EventFilter

func (EventFilter) Match

func (f EventFilter) Match(e Event) bool

type EventOpReader

type EventOpReader struct {
	// contains filtered or unexported fields
}

EventOpReader OperandReader interface to access operand value of a rule on an event

func (*EventOpReader) Read

func (oe *EventOpReader) Read(operand string) (value bool, ok bool)

Read OperandStore interface definition

type FieldMatch

type FieldMatch struct {
	Name     string `regexp:"name"`
	Operand  string `regexp:"operand"`
	Operator string `regexp:"operator"`
	Value    string `regexp:"value"`
	// contains filtered or unexported fields
}

FieldMatch is the smallest rule we can have

func NewFieldMatch

func NewFieldMatch(name, operand, operator, value string) *FieldMatch

NewFieldMatch creates a new FieldMatch rule from data

func ParseFieldMatch

func ParseFieldMatch(rule string) (ar FieldMatch, err error)

ParseFieldMatch parses a string and returns an FieldMatch

func (*FieldMatch) Compile

func (f *FieldMatch) Compile() error

Compile AtomRule into a regexp

func (*FieldMatch) GetName

func (f *FieldMatch) GetName() string

GetName implements Matcher interface

func (*FieldMatch) Match

func (f *FieldMatch) Match(se Event) bool

Match checks whether the AtomRule match the SysmonEvent

func (*FieldMatch) String

func (f *FieldMatch) String() string

type GenericEvent

type GenericEvent map[string]interface{}

func (GenericEvent) Channel

func (g GenericEvent) Channel() string

func (GenericEvent) Computer

func (g GenericEvent) Computer() string

func (GenericEvent) EventID

func (g GenericEvent) EventID() (id int64)

func (GenericEvent) Get

func (e GenericEvent) Get(p *XPath) (interface{}, bool)

func (GenericEvent) GetDetection

func (g GenericEvent) GetDetection() *Detection

func (GenericEvent) Set

func (g GenericEvent) Set(p *XPath, new interface{}) error

func (GenericEvent) SetDetection

func (g GenericEvent) SetDetection(d *Detection)

func (GenericEvent) Timestamp

func (g GenericEvent) Timestamp() time.Time

type Matcher

type Matcher interface {
	GetName() string
	Match(Event) bool
}

Matcher interface

type MetaSection

type MetaSection struct {
	Events      map[string][]int64
	Computers   []string
	Attack      []Attack `json:"ATTACK,omitempty"`
	Criticality int
	Disable     bool
	Filter      bool
	Schema      Version
}

MetaSection defines the section holding the metadata of the rule

type OperandMap

type OperandMap map[string]bool

OperandMap defines a simple structure to implement OperandReader

func (OperandMap) Read

func (om OperandMap) Read(operand string) (value, ok bool)

type OperandReader

type OperandReader interface {
	// Return operand value and ok (true if operand found false otherwise)
	Read(string) (bool, bool)
}

OperandReader interface

type Rule

type Rule struct {
	Name      string
	Tags      []string
	Meta      MetaSection
	Matches   []string
	Condition string
	Actions   []string
}

Rule is a JSON parsable rule

func NewRule

func NewRule() Rule

NewRule creates a new rule used to deserialize from JSON

func (*Rule) Compile

func (jr *Rule) Compile(e *Engine) (*CompiledRule, error)

Compile a Rule

func (*Rule) IsDisabled

func (jr *Rule) IsDisabled() bool

IsDisabled returns true if the rule has been disabled

func (*Rule) JSON

func (jr *Rule) JSON() (string, error)

JSON returns the JSON string corresponding to the rule

func (*Rule) ReplaceTemplate

func (jr *Rule) ReplaceTemplate(tm *TemplateMap)

ReplaceTemplate the regexp templates found in the matches

type Stats

type Stats struct {
	Scanned   uint64
	Positives uint64
}

type Template

type Template struct {
	Name  string
	Value string
}

Template structure definition

func (*Template) Replace

func (t *Template) Replace(s string) (new string)

Replace function

type TemplateMap

type TemplateMap struct {
	*datastructs.SyncedMap
}

TemplateMap structure

func NewTemplateMap

func NewTemplateMap() *TemplateMap

NewTemplateMap creates a new TemplateMap structure

func (*TemplateMap) AddTemplate

func (tm *TemplateMap) AddTemplate(t *Template)

AddTemplate adds a new template to the TemplateMap

func (*TemplateMap) GetTemplate

func (tm *TemplateMap) GetTemplate(name string) (ok bool, tpl *Template)

GetTemplate return the template associated to the name

func (*TemplateMap) LoadReader

func (tm *TemplateMap) LoadReader(r io.Reader) (err error)

LoadReader loads templates from a reader, one template per line If the line starts with #, it is considered as comment and is not parsed

func (*TemplateMap) ReplaceAll

func (tm *TemplateMap) ReplaceAll(s string) (new string)

ReplaceAll replaces all templates in string and return the new string

type Tokenizer

type Tokenizer struct {
	// contains filtered or unexported fields
}

Tokenizer structure

func NewTokenizer

func NewTokenizer(condition string) (c Tokenizer)

NewTokenizer creates and inits a new Tokenizer struct

func (*Tokenizer) NextExpectedToken

func (t *Tokenizer) NextExpectedToken(expects ...string) (token string, err error)

NextExpectedToken grabs the next token and returns it. ErrUnexpectedToken is returned if the token returned is not in the list of expected tokens

func (*Tokenizer) NextToken

func (t *Tokenizer) NextToken() (token string, err error)

NextToken grabs the next token

func (*Tokenizer) ParseCondition

func (t *Tokenizer) ParseCondition(group, level int) (*ConditionElement, error)

ParseCondition parses a condition from a Tokenizer object

type Version

type Version struct {
	Major int
	Minor int
	Patch int
}

func ParseVersion

func ParseVersion(s string) (v Version)

func (Version) Above

func (v Version) Above(other Version) bool

func (Version) Below

func (v Version) Below(other Version) bool

func (Version) Equals

func (v Version) Equals(other Version) bool

func (Version) IsZero

func (v Version) IsZero() bool

func (Version) MarshalJSON

func (v Version) MarshalJSON() ([]byte, error)

func (Version) String

func (v Version) String() string

func (*Version) UnmarshalJSON

func (v *Version) UnmarshalJSON(b []byte) error

type XPath

type XPath struct {
	Path  []string
	Flags struct {
		EventDataField bool
		UserDataField  bool
	}
}

func Path

func Path(p string) (x *XPath)

func (*XPath) Equal

func (p *XPath) Equal(other *XPath) bool

Equal is an optimized equality check between two paths

func (*XPath) Get added in v2.3.0

func (p *XPath) Get(i int) string

func (*XPath) Last

func (p *XPath) Last() string

func (*XPath) Len added in v2.3.0

func (p *XPath) Len() int

func (*XPath) StartsWith

func (p *XPath) StartsWith(start *XPath) bool

func (*XPath) String

func (p *XPath) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL