config

package
v5.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 22, 2025 License: GPL-3.0 Imports: 12 Imported by: 0

Documentation

Index

Constants

View Source
const (
	NONE_CATEGORY_SCORE   = 0.2
	LOW_CATEGORY_SCORE    = 0.4
	MEDIUM_CATEGORY_SCORE = 0.6
	HIGH_CATEGORY_SCORE   = 0.8

	CriticalThreat ImpactCategory = "critical"
	HighThreat     ImpactCategory = "high"
	MediumThreat   ImpactCategory = "medium"
	LowThreat      ImpactCategory = "low"
	NoneThreat     ImpactCategory = "none"
)
View Source
const DefaultConfigPath = "./config.hjson"

Variables

View Source
var Version string

Functions

func GetMandatoryNeverIncludeSubnets added in v5.0.5

func GetMandatoryNeverIncludeSubnets() []util.Subnet

func GetScoreFromImpactCategory

func GetScoreFromImpactCategory(category ImpactCategory) (float64, error)

func NewValidator added in v5.1.0

func NewValidator() (*validator.Validate, error)

NewValidator creates a new validator with custom validation rules

func ValidateImpactCategory

func ValidateImpactCategory(value ImpactCategory) error

ValidateImpactCategory checks if the provided string is a valid impact value. this function is meant to parse the category from the value a user places in the config Since a score is only critical if its modifiers boost the score over the high category, we do not add the CriticalThreat category here

Types

type BeaconScoring added in v5.1.0

type BeaconScoring struct {
	UniqueConnectionThreshold         int64           `ch:"unique_connection_threshold" json:"unique_connection_threshold" validate:"gte=4"`
	TimestampScoreWeight              float64         `ch:"timestamp_score_weight" json:"timestamp_score_weight" validate:"gte=0,lte=1"`
	DatasizeScoreWeight               float64         `ch:"datasize_score_weight" json:"datasize_score_weight" validate:"gte=0,lte=1"`
	DurationScoreWeight               float64         `ch:"duration_score_weight" json:"duration_score_weight" validate:"gte=0,lte=1"`
	HistogramScoreWeight              float64         `ch:"histogram_score_weight" json:"histogram_score_weight" validate:"gte=0,lte=1"`
	DurationMinHoursSeen              int32           `ch:"duration_min_hours_seen" json:"duration_min_hours_seen" validate:"gte=1,lte=24"`
	DurationConsistencyIdealHoursSeen int32           `ch:"duration_consistency_ideal_hours_seen" json:"duration_consistency_ideal_hours_seen" validate:"gte=1,lte=24"`
	HistogramModeSensitivity          float64         `ch:"histogram_mode_sensitivity" json:"histogram_mode_sensitivity" validate:"gte=0,lte=1"`
	HistogramBimodalOutlierRemoval    int32           `ch:"histogram_bimodal_outlier_removal" json:"histogram_bimodal_outlier_removal" validate:"gte=0,lte=24"`
	HistogramBimodalMinHoursSeen      int32           `ch:"histogram_bimodal_min_hours_seen" json:"histogram_bimodal_min_hours_seen" validate:"gte=3,lte=24"`
	ScoreThresholds                   ScoreThresholds `ch:"score_thresholds" json:"score_thresholds" validate:"score_thresholds_range=0 100"`
}

type Config

type Config struct {
	Env          Env `json:"env" validate:"required"`
	RITA         `validate:"required"`
	Filtering    Filtering    `json:"filtering" validate:"required"`
	Scoring      Scoring      `json:"scoring" validate:"required"`
	Modifiers    Modifiers    `json:"modifiers" validate:"required"`
	ZoneTransfer ZoneTransfer `json:"zone_transfer"`
}

func GetDefaultConfig added in v5.0.5

func GetDefaultConfig() Config

GetDefaultConfig returns a Config object with default values

func ReadConfigFromMemory added in v5.1.0

func ReadConfigFromMemory(data []byte, env Env) (*Config, error)

ReadConfigFromMemory reads the config from bytes already read into memory as opposed to reading from a file It also provides its own environment struct that must already be completely set

func ReadFileConfig

func ReadFileConfig(afs afero.Fs, path string) (*Config, error)

ReadFileConfig attempts to read the config file at the specified path and returns a config object, using the default config if the file was unable to be read.

func ReadTestFileConfig added in v5.1.0

func ReadTestFileConfig(afs afero.Fs, path string) (*Config, error)

ReadTestFileConfig is for TESTS only

func (*Config) Reset added in v5.1.0

func (cfg *Config) Reset() error

Reset resets the config values to default note: Env values are not reset

func (*Config) SetTestEnv added in v5.1.0

func (c *Config) SetTestEnv()

ONLY TO BE CALLED IN TESTS helper function to set the env variables that are reliant on paths since tests use the path of the package

func (*Config) UnmarshalJSON added in v5.0.6

func (c *Config) UnmarshalJSON(bytes []byte) error

// UnmarshalJSON unmarshals the JSON bytes into the config struct // overrides the default unmarshalling method to allow for custom parsing

func (*Config) Validate

func (cfg *Config) Validate() error

Validate validates the config struct values

type Env added in v5.1.0

type Env struct {
	DBConnection                    string `validate:"required,hostname_port"` // DB_ADDRESS
	DBUsername                      string `json:"-"`
	DBPassword                      string `json:"-"`
	HTTPExtensionsFilePath          string `validate:"file"`        // CONFIG_DIR/http_extensions_list.csv
	LogLevel                        int8   `validate:"min=0,max=6"` // LOG_LEVEL
	ThreatIntelCustomFeedsDirectory string `validate:"dir"`         // CONFIG_DIR/threat_intel_feeds
}

type Filter

type Filter struct {
	InternalSubnetsJSON []string `json:"internal_subnets"`
	InternalSubnets     []*net.IPNet

	AlwaysIncludedSubnetsJSON []string `json:"always_included_subnets"`
	AlwaysIncludedSubnets     []*net.IPNet

	NeverIncludedSubnetsJSON []string `json:"never_included_subnets"`
	NeverIncludedSubnets     []*net.IPNet

	AlwaysIncludedDomains []string `json:"always_included_domains"`
	NeverIncludedDomains  []string `json:"never_included_domains"`

	FilterExternalToInternal bool `json:"filter_external_to_internal"`
}

Filter provides methods for excluding IP addresses, domains, and determining proxy servers during the import step based on the user configuration

type Filtering added in v5.1.0

type Filtering struct {
	// subnets do not need a validate tag because they are validated when they are unmarshalled
	InternalSubnets          []util.Subnet `ch:"internal_subnets" json:"internal_subnets" validate:"required,gt=0"`
	AlwaysIncludedSubnets    []util.Subnet `ch:"always_included_subnets" json:"always_included_subnets"`
	AlwaysIncludedDomains    []string      `ch:"always_included_domains" json:"always_included_domains" validate:"omitempty,dive,wildcard_fqdn"`
	NeverIncludedSubnets     []util.Subnet `ch:"never_included_subnets" json:"never_included_subnets" validate:"required,gt=0"`
	NeverIncludedDomains     []string      `ch:"never_included_domains" json:"never_included_domains" validate:"omitempty,dive,wildcard_fqdn"`
	FilterExternalToInternal bool          `ch:"filter_external_to_internal" json:"filter_external_to_internal" validate:"boolean"`
}

func (*Filtering) CheckIfInternal added in v5.1.0

func (fs *Filtering) CheckIfInternal(host net.IP) bool

func (*Filtering) FilterConnPair added in v5.1.0

func (fs *Filtering) FilterConnPair(srcIP net.IP, dstIP net.IP) bool

filterConnPair returns true if a connection pair is filtered/excluded. This is determined by the following rules, in order:

  1. Not filtered if either IP is on the AlwaysInclude list
  2. Filtered if either IP is on the NeverInclude list
  3. Not filtered if InternalSubnets is empty
  4. Filtered if both IPs are internal or both are external
  5. Filtered if the source IP is external and the destination IP is internal and FilterExternalToInternal has been set in the configuration file
  6. Not filtered in all other cases

func (*Filtering) FilterConnPairForHTTP added in v5.1.0

func (fs *Filtering) FilterConnPairForHTTP(srcIP net.IP, dstIP net.IP) bool

FilterConnPairForHTTP returns true if a connection pair is filtered based on criteria that should apply regardless of whether or not there is a proxy connection for it

func (*Filtering) FilterDNSPair added in v5.1.0

func (fs *Filtering) FilterDNSPair(srcIP net.IP, dstIP net.IP) bool

filterDNSPair returns true if a DNS connection pair is filtered/excluded. DNS is treated specially since we need to capture internal -> internal DNS traffic in order to detect C2 over DNS with an internal resolver. This is determined by the following rules, in order:

  1. Not filtered if either IP is on the AlwaysInclude list
  2. Filtered if either IP is on the NeverInclude list
  3. Not filtered if InternalSubnets is empty
  4. Filtered if both IPs are external (this is different from filterConnPair which filters internal to internal connections)
  5. Filtered if the source IP is external and the destination IP is internal and FilterExternalToInternal has been set in the configuration file
  6. Not filtered in all other cases

func (*Filtering) FilterDomain added in v5.1.0

func (fs *Filtering) FilterDomain(domain string) bool

FilterDomain returns true if a domain is filtered/excluded. This is determined by the following rules, in order:

  1. Not filtered if domain is on the AlwaysInclude list
  2. Filtered if domain is on the NeverInclude list
  3. Not filtered in all other cases

func (*Filtering) FilterSNIPair added in v5.1.0

func (fs *Filtering) FilterSNIPair(srcIP net.IP) bool

FilterSNIPair returns true if a SNI connection pair is filtered/excluded.

func (*Filtering) FilterSingleIP added in v5.1.0

func (fs *Filtering) FilterSingleIP(ip net.IP) bool

filterSingleIP returns true if an IP is filtered/excluded. This is determined by the following rules, in order:

  1. Not filtered IP is on the AlwaysInclude list
  2. Filtered IP is on the NeverInclude list
  3. Not filtered in all other cases

type ImpactCategory

type ImpactCategory string

func GetImpactCategoryFromScore

func GetImpactCategoryFromScore(score float64) ImpactCategory

type Modifiers

type Modifiers struct {
	ThreatIntelScoreIncrease         float64 `ch:"threat_intel_score_increase" json:"threat_intel_score_increase" validate:"gte=0,lte=1"`
	ThreatIntelDataSizeThreshold     int64   `ch:"threat_intel_datasize_threshold" json:"threat_intel_datasize_threshold"  validate:"gte=1,lte=5000000000"`
	PrevalenceScoreIncrease          float64 `ch:"prevalence_score_increase" json:"prevalence_score_increase" validate:"gte=0,lte=1"`
	PrevalenceIncreaseThreshold      float64 `ch:"prevalence_increase_threshold" json:"prevalence_increase_threshold" validate:"gte=0,lte=1"`
	PrevalenceScoreDecrease          float64 `ch:"prevalence_score_decrease" json:"prevalence_score_decrease" validate:"gte=0,lte=1"`
	PrevalenceDecreaseThreshold      float64 `` /* 130-byte string literal not displayed */
	FirstSeenScoreIncrease           float64 `ch:"first_seen_score_increase" json:"first_seen_score_increase" validate:"gte=0,lte=1"`
	FirstSeenIncreaseThreshold       float64 `ch:"first_seen_increase_threshold" json:"first_seen_increase_threshold" validate:"gte=1,lte=90"`
	FirstSeenScoreDecrease           float64 `ch:"first_seen_score_decrease" json:"first_seen_score_decrease" validate:"gte=0,lte=1"`
	FirstSeenDecreaseThreshold       float64 `` /* 130-byte string literal not displayed */
	MissingHostCountScoreIncrease    float64 `ch:"missing_host_count_score_increase" json:"missing_host_count_score_increase" validate:"gte=0,lte=1"`
	RareSignatureScoreIncrease       float64 `ch:"rare_signature_score_increase" json:"rare_signature_score_increase" validate:"gte=0,lte=1"`
	C2OverDNSDirectConnScoreIncrease float64 `ch:"c2_over_dns_direct_conn_score_increase" json:"c2_over_dns_direct_conn_score_increase" validate:"gte=0,lte=1"`
	MIMETypeMismatchScoreIncrease    float64 `ch:"mime_type_mismatch_score_increase" json:"mime_type_mismatch_score_increase" validate:"gte=0,lte=1"`
}

type RITA added in v5.1.0

type RITA struct {
	UpdateCheckEnabled              bool  `ch:"update_check_enabled" json:"update_check_enabled" validate:"boolean"`
	BatchSize                       int32 `ch:"batch_size" json:"batch_size" validate:"gte=25000,lte=2000000"`
	MaxQueryExecutionTime           int32 `ch:"max_query_execution_time" json:"max_query_execution_time" validate:"gte=1,lte=2000000"`
	MonthsToKeepHistoricalFirstSeen int32 `ch:"months_to_keep_historical_first_seen" json:"months_to_keep_historical_first_seen" validate:"gte=1,lte=60"`
	ThreatIntel                     `json:"threat_intel"`
}

type ScoreImpact

type ScoreImpact struct {
	Category ImpactCategory `json:"category"`
	Score    float64
}

ScoreImpact is used for indicators that have a binary outcomes but still need to express the impact of being true on the overall score.

func (*ScoreImpact) Scan added in v5.1.0

func (s *ScoreImpact) Scan(src any) error

func (ScoreImpact) String added in v5.1.0

func (s ScoreImpact) String() string

type ScoreThresholds

type ScoreThresholds struct {
	Base int32 `json:"base" ch:"base" validate:"ltfield=Low"`
	Low  int32 `json:"low" ch:"low" validate:"ltfield=Med"`
	Med  int32 `json:"medium" ch:"med" validate:"ltfield=High"`
	High int32 `json:"high" ch:"high"`
}

ScoreThresholds is used for indicators that have prorated (graduated) values rather than binary outcomes. This allows for the definition of the severity of an indicator by categorizing it into one of several buckets (Base, Low, Med, High), each representing a range of values. These values must be in increasing order and unique.

func (*ScoreThresholds) ToMap added in v5.1.0

func (s *ScoreThresholds) ToMap() map[string]int32

type Scoring

type Scoring struct {
	Beacon        BeaconScoring `json:"beacon" validate:"required"`
	ThreatScoring `validate:"required"`
}

type ThreatIntel

type ThreatIntel struct {
	OnlineFeeds []string `ch:"threat_intel_online_feeds" json:"online_feeds" validate:"omitempty,dive,url"`
}

type ThreatScoring added in v5.1.0

type ThreatScoring struct {
	LongConnectionScoreThresholds ScoreThresholds `json:"long_connection_score_thresholds" validate:"score_thresholds_range=1 86400"` // 24 * 3600
	C2ScoreThresholds             ScoreThresholds `json:"c2_score_thresholds" validate:"score_thresholds_range=1 -1"`
	StrobeImpact                  ScoreImpact     `ch:"strobe_impact_category" json:"strobe_impact" validate:"impact_category"`
	ThreatIntelImpact             ScoreImpact     `ch:"threat_intel_impact_category" json:"threat_intel_impact" validate:"impact_category"`
}

type ZoneTransfer added in v5.1.0

type ZoneTransfer struct {
	Enabled    bool   `ch:"enabled" json:"enabled"`
	DomainName string `ch:"domain_name" json:"domain_name" validate:"required_if=Enabled true,omitempty,fqdn"`
	NameServer string `ch:"name_server" json:"name_server" validate:"required_if=Enabled true,omitempty,hostname_port"`
}

Jump to

Keyboard shortcuts

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