gonids

package module
v0.0.0-...-5e1727c Latest Latest
Warning

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

Go to latest
Published: Mar 30, 2021 License: Apache-2.0 Imports: 9 Imported by: 0

README

gonids is a library to parse IDS rules for engines like Snort and Suricata.

Installation

$ go get github.com/google/gonids

Quick Start

Add this import line to the file you're working in:

import "github.com/google/gonids"

To parse a rule:

rule := `alert tcp $HOME_NET any -> $EXTERNAL_NET 80 (msg:"GONIDS TEST hello world"; flow:established,to_server; content:"hello world"; classtype:trojan-activity; sid:1; rev:1;)`
r, err := gonids.ParseRule(rule)
if err != nil {
  // Handle parse error
}
// Do something with your rule.
switch r.Action {
case "alert":
  // This is an 'alert' rule.
case "drop":
  // This is a 'drop' rule.
case "pass":
  // This is a 'pass' rule.
default:
  // I have no idea what this would be. =)
}

To create a rule a DNS rule (using dns_query sticky buffer) and print it:

r := gonids.Rule{
	Action:   "alert",
	Protocol: "dns",
	Source: Network{
		Nets:  []string{"any"},
		Ports: []string{"any"},
	},
	Destination: Network{
		Nets:  []string{"any"},
		Ports: []string{"any"},
	},
	SID:         1234,
	Revision:    1,
}

badDomain := "c2.evil.com"
dnsRule.Description = fmt.Sprintf("DNS query for %s", badDomain)

sb, _ := gonids.StickyBuffer("dns_query")
c := &gonids.Content{
			DataPosition: sb,
			Pattern:      []byte(badDomain),
			Options: []*gonids.ContentOption{
				{"nocase", ""},
			},
		}
}

fmt.Println(r)

To optimize a Snort HTTP rule for Suricata:

rule := `alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"GONIDS TEST hello world"; flow:established,to_server; content:"hello.php"; http_uri; classtype:trojan-activity; sid:1; rev:1;)`
r, err := gonids.ParseRule(rule)
if err != nil {
  // Handle parse error
}
r.OptimizeHTTP()

Miscellaneous

This is not an official Google product.

Documentation

Overview

Package gonids implements a basic parser of IDS rules.

For now the parser is very basic and it only parses a subset of fields. We intentionally omit http_encode as it doesn't seem to be used in practice.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FuzzParseRule

func FuzzParseRule(data []byte) int

FuzzParseRule is used by OSS-Fuzz to fuzz the library.

Types

type ByteMatch

type ByteMatch struct {
	// DataPosition defaults to pkt_data state, can be modified to apply to file_data, base64_data locations.
	// This value will apply to all following contents, to reset to default you must reset DataPosition during processing.
	DataPosition DataPos
	// Kind is a specific operation type we're taking.
	Kind byteMatchType
	// Negate indicates negation of a value, currently only used for isdataat.
	Negate bool
	// A variable name being extracted by byte_extract.
	Variable string
	// Number of bytes to operate on. "bytes to convert" in Snort Manual. This can be an int, or a var from byte_extract.
	NumBytes string
	// Operator for comparison in byte_test.
	Operator string
	// Value to compare against using byte_test.
	Value string
	// Offset within given buffer to operate on.
	Offset int
	// Other specifics required for jump/test here. This might make sense to pull out into a "ByteMatchOption" later.
	Options []string
}

ByteMatch describes a byte matching operation, similar to a Content.

func (ByteMatch) String

func (b ByteMatch) String() string

String returns a string for a ByteMatch.

type Content

type Content struct {
	// DataPosition defaults to pkt_data state, can be modified to apply to file_data, base64_data locations.
	// This value will apply to all following contents, to reset to default you must reset DataPosition during processing.
	DataPosition DataPos
	// FastPattern settings for the content.
	FastPattern FastPattern
	// Pattern is the pattern match of a content (e.g. HTTP in content:"HTTP").
	Pattern []byte
	// Negate is true for negated content match.
	Negate bool
	// Options are the option associated to the content (e.g. http_header).
	Options []*ContentOption
}

Content describes a rule content. A content is composed of a pattern followed by options.

func (*Content) FormatPattern

func (c *Content) FormatPattern() string

FormatPattern returns a string for a Pattern in a content

func (Content) SnortHTTPHeader

func (c Content) SnortHTTPHeader() bool

SnortHTTPHeader returns true if a specific content contains double CRLF at the end.

func (Content) String

func (c Content) String() string

String returns a string for a Content (ignoring sticky buffers.)

func (*Content) ToRegexp

func (c *Content) ToRegexp() string

ToRegexp returns a string that can be used as a regular expression to identify content matches in an ASCII dump of a packet capture (tcpdump -A).

type ContentOption

type ContentOption struct {
	// Name is the name of the option (e.g. offset).
	Name string
	// Value is the value associated to the option, default to "" for option without value.
	Value string
}

ContentOption describes an option set on a rule content.

func (ContentOption) String

func (co ContentOption) String() string

String returns a string for a ContentOption.

type DataPos

type DataPos int

DataPos indicates the data position for content matches. These should be referenced for creation by using their Suricata keywords and the StickyBuffer() function.

func StickyBuffer

func StickyBuffer(s string) (DataPos, error)

StickyBuffer returns the data position value for the string representation of a sticky buffer name (e.g. "file_data")

func (DataPos) String

func (d DataPos) String() string

type FastPattern

type FastPattern struct {
	Enabled bool
	Only    bool
	Offset  int
	Length  int
}

FastPattern describes various properties of a fast_pattern value for a content.

func (FastPattern) String

func (f FastPattern) String() string

String returns a string for a FastPattern.

type Flowbit

type Flowbit struct {
	Action string
	Value  string
}

Flowbit describes a flowbit. A flowbit consists of an Action, and optional Value.

func (Flowbit) String

func (fb Flowbit) String() string

String returns a string for a Flowbit.

type Flowint

type Flowint struct {
	Name     string
	Modifier string
	Value    string
}

Flowint describes a flowint.

func (Flowint) String

func (fi Flowint) String() string

String returns a string for a Flowbit.

type LenMatch

type LenMatch struct {
	// DataPosition defaults to pkt_data state, can be modified to apply to file_data, base64_data locations.
	// This value will apply to all following contents, to reset to default you must reset DataPosition during processing.
	DataPosition DataPos
	Kind         lenMatchType
	Min          int
	Max          int
	Num          int
	Operator     string
	Options      []string
}

LenMatch holds the values to represent an Length Match.

func (LenMatch) String

func (i LenMatch) String() string

String returns a string for an length match.

type Metadata

type Metadata struct {
	Key   string
	Value string
}

Metadata describes metadata tags in key-value struct.

func MetadataModifier

func MetadataModifier(s string) *Metadata

MetadataModifier returns a metadata that identifies a given modification.

type Metadatas

type Metadatas []*Metadata

Metadatas allows for a Stringer on []*Metadata

func (Metadatas) String

func (ms Metadatas) String() string

String returns a string for all of the metadata values.

type Network

type Network struct {
	Nets  []string // Currently just []string because these can be variables $HOME_NET, not a valid IPNet.
	Ports []string // Currently just []string because these can be variables $HTTP_PORTS, not just ints.
}

Network describes the IP addresses and port numbers used in a rule. TODO: Ensure all values either begin with $ (variable) or they are valid IPNet/int.

func (Network) String

func (n Network) String() string

String retunrs a string for a Network.

type PCRE

type PCRE struct {
	Pattern []byte
	Negate  bool
	Options []byte
}

PCRE describes a PCRE item of a rule.

func (PCRE) String

func (p PCRE) String() string

String returns a string for a PCRE.

type Reference

type Reference struct {
	// Type is the system name for the reference: (url, cve, md5, etc.)
	Type string
	// Value is the identifier in the system: (address, cvd-id, hash)
	Value string
}

Reference describes a gonids reference in a rule.

func (Reference) String

func (r Reference) String() string

String returns a string for a Reference.

type Rule

type Rule struct {
	// Disbled identifies if the rule is disabled/commented out.
	Disabled bool
	// Action is the action the rule will take (alert, pass, drop, etc.).
	Action string
	// Protocol is the protocol the rule looks at.
	Protocol string
	// Source is the address and ports for the source of the traffic.
	Source Network
	// Destination is the address and ports for the source of the traffic.
	Destination Network
	// Bidirectional indicates the directionality of a rule (-> or <>).
	Bidirectional bool
	// SID is the identifier of the rule.
	SID int
	// Revision is the revision of the rule.
	Revision int
	// Description is the msg field of the rule.
	Description string
	// References contains references associated to the rule (e.g. CVE number).
	References []*Reference
	// Contents are all the decoded content matches.
	Tags map[string]string
	// Statements is a slice of string. These items are similar to Tags, but have no value. (e.g. 'sameip;')
	Statements []string
	// TLSTags is a slice of TLS related matches.
	TLSTags []*TLSTag
	// StreamMatch holds stream_size parameters.
	StreamMatch *StreamCmp
	// Metas is a slice of Metadata.
	Metas Metadatas
	// Flowbits is a slice of Flowbit.
	Flowbits []*Flowbit
	// Xbits is a slice of Xbit
	Xbits []*Xbit
	// Flowints is a slice of Flowint
	Flowints []*Flowint
	// Matchers are internally used to ensure relative matches are printed correctly.
	// Make this private before checkin?
	Matchers []orderedMatcher
}

Rule describes an IDS rule.

func ParseRule

func ParseRule(rule string) (*Rule, error)

ParseRule parses an IDS rule and returns a struct describing the rule.

func (*Rule) ByteMatchers

func (r *Rule) ByteMatchers() []*ByteMatch

ByteMatchers returns all *ByteMatch for a rule.

func (*Rule) CVE

func (r *Rule) CVE() string

CVE extracts CVE from a rule.

func (*Rule) Contents

func (r *Rule) Contents() []*Content

Contents returns all *Content for a rule.

func (*Rule) ExpensivePCRE

func (r *Rule) ExpensivePCRE() bool

ExpensivePCRE returns true if a rule appears to use a PCRE without conditions that make it expensive to compute.

func (*Rule) GetSidMsg

func (r *Rule) GetSidMsg() string

GetSidMsg returns a string representing a sidmsg.map entry.

func (*Rule) HasVar

func (r *Rule) HasVar(s string) bool

HasVar returns true if a variable with the provided name exists.

func (*Rule) InsertMatcher

func (r *Rule) InsertMatcher(m orderedMatcher, pos int) error

InsertMatcher will insert an ordered matcher at a position specified.

func (*Rule) LastContent

func (r *Rule) LastContent() *Content

LastContent returns the last *Content from Matchers

func (*Rule) LenMatchers

func (r *Rule) LenMatchers() []*LenMatch

LenMatchers returns all *LenMatch for a rule.

func (*Rule) NoReferences

func (r *Rule) NoReferences() bool

NoReferences returns true if there are no references in the rule.

func (*Rule) OnlyShortContents

func (r *Rule) OnlyShortContents() bool

OnlyShortContents returns true if all Matchers are Contents and all matches are very short.

func (*Rule) OptimizeHTTP

func (r *Rule) OptimizeHTTP() bool

OptimizeHTTP tunes an old style rule to leverage port agnostic HTTP detection.

func (*Rule) PCREs

func (r *Rule) PCREs() []*PCRE

PCREs returns all *PCRE for a rule.

func (*Rule) RE

func (r *Rule) RE() string

RE returns all content matches as a single and simple regexp.

func (*Rule) ShouldBeHTTP

func (r *Rule) ShouldBeHTTP() bool

ShouldBeHTTP returns true if a rule looks like the protocol should be http, but is not.

func (*Rule) SnortHTTPHeader

func (r *Rule) SnortHTTPHeader() bool

SnortHTTPHeader returns true if any content contains double CRLF at the end.

func (*Rule) SnortHTTPHeaderFix

func (r *Rule) SnortHTTPHeaderFix() bool

SnortHTTPHeaderFix will fix broken http_header matches.

func (*Rule) SnortURILenFix

func (r *Rule) SnortURILenFix() bool

SnortURILenFix will optimize a urilen keyword from a Snort rule for Suricata.

func (Rule) String

func (r Rule) String() string

String returns a string for a rule.

func (*Rule) UpgradeToSuri5

func (r *Rule) UpgradeToSuri5() bool

UpgradeToSuri5 optimizes a Suricata 4.x rule to Suricata 5.x features.

type StreamCmp

type StreamCmp struct {
	// Direction of traffic to inspect: server, client, both, either.
	Direction string
	// Operator is the comparison operator to apply >, <, !=, etc.
	Operator string
	// TODO: Can this number be a variable, if yes s/int/string.
	// Number is the size to compare against
	Number int
}

StreamCmp represents a stream comparison (stream_size:>20).

func (*StreamCmp) String

func (s *StreamCmp) String() string

type TLSTag

type TLSTag struct {
	// Is the match negated (!).
	Negate bool
	// Key holds the thing we're inspecting (tls.version, tls.fingerprint, etc.).
	Key string
	// TODO: Consider string -> []byte and handle hex input.
	// TODO: Consider supporting []struct if we can support things like: tls.version:!1.2,!1.3
	// Value holds the value for the match.
	Value string
}

TLSTag describes a TLS specific match (non-sticky buffer based).

func (*TLSTag) String

func (t *TLSTag) String() string

type UnsupportedOptionError

type UnsupportedOptionError struct {
	Rule    *Rule
	Options []string
}

UnsupportedOptionError contains a partially parsed rule, and the options that aren't supported for parsing.

func (*UnsupportedOptionError) Error

func (uoe *UnsupportedOptionError) Error() string

Error returns a string for UnsupportedOptionError

type Xbit

type Xbit struct {
	Action string
	Name   string
	Track  string
	// Expire should be an int, default 0 value makes stringer difficult because this is an
	// optional parameter. If we can confirm that this must be > 0 we can convert to int.
	Expire string
}

Xbit describes an Xbit. TODO: Consider adding more structure to Track and Expire.

func (Xbit) String

func (xb Xbit) String() string

String returns a string for a Flowbit.

Jump to

Keyboard shortcuts

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