diff --git a/wazuh-notify-go/notification/discord.go b/wazuh-notify-go/notification/discord.go index 372d8b2..f6b977a 100644 --- a/wazuh-notify-go/notification/discord.go +++ b/wazuh-notify-go/notification/discord.go @@ -6,39 +6,79 @@ import ( "log" "net/http" "os" + "slices" "strconv" + "strings" "wazuh-notify/types" ) func SendDiscord(params types.Params) { - embedDescription := "\n\n" + - "**Agent:** " + params.WazuhMessage.Parameters.Alert.Agent.Name + "\n" + - "**Event id:** " + params.WazuhMessage.Parameters.Alert.Rule.ID + "\n" + - "**Description:** " + params.WazuhMessage.Parameters.Alert.Rule.Description + "\n" + - "**Threat level:** " + strconv.Itoa(params.WazuhMessage.Parameters.Alert.Rule.Level) + "\n" + - "**Times fired:** " + strconv.Itoa(params.WazuhMessage.Parameters.Alert.Rule.Firedtimes) + - "\n\n" + - "Priority: " + strconv.Itoa(params.Priority) + "\n" + - "Tags: " + params.Tags + "\n\n" + - params.Click + + var embedDescription string + + if slices.Contains(strings.Split(params.FullMessage, ","), "discord") { + fullMessage, _ := json.MarshalIndent(params.WazuhMessage, "", " ") + fullMessageString := strings.ReplaceAll(string(fullMessage), `"`, "") + fullMessageString = strings.ReplaceAll(fullMessageString, "{", "") + fullMessageString = strings.ReplaceAll(fullMessageString, "}", "") + fullMessageString = strings.ReplaceAll(fullMessageString, "[", "") + fullMessageString = strings.ReplaceAll(fullMessageString, "]", "") + fullMessageString = strings.ReplaceAll(fullMessageString, " ,", "") + + embedDescription = "\n\n ```" + + fullMessageString + + "```\n\n" + + "Priority: " + strconv.Itoa(params.Priority) + "\n" + + "Tags: " + params.Tags + "\n\n" + + params.Click + } else { + embedDescription = "\n\n" + + "**Agent:** " + params.WazuhMessage.Parameters.Alert.Agent.Name + "\n" + + "**Event id:** " + params.WazuhMessage.Parameters.Alert.Rule.ID + "\n" + + "**Rule:** " + params.WazuhMessage.Parameters.Alert.Rule.Description + "\n" + + "**Description: **" + params.WazuhMessage.Parameters.Alert.FullLog + "\n" + + "**Threat level:** " + strconv.Itoa(params.WazuhMessage.Parameters.Alert.Rule.Level) + "\n" + + "**Times fired:** " + strconv.Itoa(params.WazuhMessage.Parameters.Alert.Rule.Firedtimes) + + "\n\n" + + "Priority: " + strconv.Itoa(params.Priority) + "\n" + + "Tags: " + params.Tags + "\n\n" + + params.Click + } var color int + var mention string switch params.Priority { case 1: - color = 0x339900 + color = params.PriorityMaps[4].Color + if params.WazuhMessage.Parameters.Alert.Rule.Firedtimes >= params.PriorityMaps[4].MentionThreshold { + mention = "@here" + } case 2: - color = 0x99cc33 + color = params.PriorityMaps[3].Color + if params.WazuhMessage.Parameters.Alert.Rule.Firedtimes >= params.PriorityMaps[3].MentionThreshold { + mention = "@here" + } case 3: - color = 0xffcc00 + color = params.PriorityMaps[2].Color + if params.WazuhMessage.Parameters.Alert.Rule.Firedtimes >= params.PriorityMaps[2].MentionThreshold { + mention = "@here" + } case 4: - color = 0xff9966 + color = params.PriorityMaps[1].Color + if params.WazuhMessage.Parameters.Alert.Rule.Firedtimes >= params.PriorityMaps[1].MentionThreshold { + mention = "@here" + } case 5: - color = 0xcc3300 + color = params.PriorityMaps[0].Color + if params.WazuhMessage.Parameters.Alert.Rule.Firedtimes >= params.PriorityMaps[0].MentionThreshold { + mention = "@here" + } } message := types.Message{ Username: params.Sender, + Content: mention, Embeds: []types.Embed{ { Title: params.Sender, diff --git a/wazuh-notify-go/services/filters.go b/wazuh-notify-go/services/filters.go new file mode 100644 index 0000000..8f630b3 --- /dev/null +++ b/wazuh-notify-go/services/filters.go @@ -0,0 +1,24 @@ +package services + +import ( + "os" + "strings" + "wazuh-notify/log" +) + +func Filter() { + for _, rule := range strings.Split(inputParams.ExcludedRules, ",") { + if rule == inputParams.WazuhMessage.Parameters.Alert.Rule.ID { + log.Log("rule excluded") + log.CloseLogFile() + os.Exit(0) + } + } + for _, agent := range strings.Split(inputParams.ExcludedAgents, ",") { + if agent == inputParams.WazuhMessage.Parameters.Alert.Agent.ID { + log.Log("agent excluded") + log.CloseLogFile() + os.Exit(0) + } + } +} diff --git a/wazuh-notify-go/services/init.go b/wazuh-notify-go/services/init.go index f6f14a7..88aabb6 100644 --- a/wazuh-notify-go/services/init.go +++ b/wazuh-notify-go/services/init.go @@ -36,7 +36,10 @@ func InitNotify() types.Params { log.Log("yaml failed to load") yamlFile, err = os.ReadFile(path.Join(BaseDirPath, "wazuh-notify-config.yaml")) } - yaml.Unmarshal(yamlFile, &configParams) + err = yaml.Unmarshal(yamlFile, &configParams) + if err != nil { + print(err) + } log.Log("yaml loaded") configParamString, _ := json.Marshal(configParams) @@ -56,6 +59,10 @@ func InitNotify() types.Params { log.Log(string(inputParamString)) inputParams.Targets = configParams.Targets + inputParams.FullMessage = configParams.FullMessage + inputParams.ExcludedAgents = configParams.ExcludedAgents + inputParams.ExcludedRules = configParams.ExcludedRules + inputParams.PriorityMaps = configParams.PriorityMaps wazuhInput() @@ -73,6 +80,8 @@ func wazuhInput() { inputParams.WazuhMessage = wazuhData + Filter() + log.Log("Wazuh data loaded") inputParamString, _ := json.Marshal(inputParams) log.Log(string(inputParamString)) diff --git a/wazuh-notify-go/services/mapping.go b/wazuh-notify-go/services/mapping.go index 051ff0f..c289491 100644 --- a/wazuh-notify-go/services/mapping.go +++ b/wazuh-notify-go/services/mapping.go @@ -3,19 +3,19 @@ package services import "slices" func mapPriority() int { - if slices.Contains(configParams.Priority1, wazuhData.Parameters.Alert.Rule.Level) { + if slices.Contains(configParams.PriorityMaps[4].ThreatMap, wazuhData.Parameters.Alert.Rule.Level) { return 1 } - if slices.Contains(configParams.Priority2, wazuhData.Parameters.Alert.Rule.Level) { + if slices.Contains(configParams.PriorityMaps[3].ThreatMap, wazuhData.Parameters.Alert.Rule.Level) { return 2 } - if slices.Contains(configParams.Priority3, wazuhData.Parameters.Alert.Rule.Level) { + if slices.Contains(configParams.PriorityMaps[2].ThreatMap, wazuhData.Parameters.Alert.Rule.Level) { return 3 } - if slices.Contains(configParams.Priority4, wazuhData.Parameters.Alert.Rule.Level) { + if slices.Contains(configParams.PriorityMaps[1].ThreatMap, wazuhData.Parameters.Alert.Rule.Level) { return 4 } - if slices.Contains(configParams.Priority5, wazuhData.Parameters.Alert.Rule.Level) { + if slices.Contains(configParams.PriorityMaps[0].ThreatMap, wazuhData.Parameters.Alert.Rule.Level) { return 5 } return 0 diff --git a/wazuh-notify-go/types/types.go b/wazuh-notify-go/types/types.go index 75a77e2..c543cc4 100644 --- a/wazuh-notify-go/types/types.go +++ b/wazuh-notify-go/types/types.go @@ -1,18 +1,23 @@ package types type Params struct { - Url string - Sender string `yaml:"sender,omitempty"` - Priority int - Tags string - Click string `yaml:"click,omitempty"` - Targets string `yaml:"targets,omitempty"` - WazuhMessage WazuhMessage - Priority1 []int `yaml:"priority_1"` - Priority2 []int `yaml:"priority_2"` - Priority3 []int `yaml:"priority_3"` - Priority4 []int `yaml:"priority_4"` - Priority5 []int `yaml:"priority_5"` + Url string + Sender string `yaml:"sender,omitempty"` + Priority int + Tags string + Click string `yaml:"click,omitempty"` + Targets string `yaml:"targets,omitempty"` + FullMessage string `yaml:"full_message,omitempty"` + ExcludedRules string `yaml:"excluded_rules,omitempty"` + ExcludedAgents string `yaml:"excluded_agents,omitempty"` + WazuhMessage WazuhMessage + PriorityMaps []PriorityMap `yaml:"priority_map"` +} + +type PriorityMap struct { + ThreatMap []int `yaml:"threat_map"` + MentionThreshold int `yaml:"mention_threshold"` + Color int `yaml:"color"` } type Message struct { diff --git a/wazuh-notify-go/wazuh-notify-config.yaml b/wazuh-notify-go/wazuh-notify-config.yaml index 0721c5f..e455811 100644 --- a/wazuh-notify-go/wazuh-notify-config.yaml +++ b/wazuh-notify-go/wazuh-notify-config.yaml @@ -5,20 +5,38 @@ # The yaml needs to be in the same folder as the wazuh-ntfy-notifier.py and wazuh-discord-notifier.py targets: "discord,ntfy" -full_message: "discord,ntfy" +full_message: "ntfy" # Exclude rules that are listed in the ossec.conf active response definition. -excluded_rules: "5401, 5403" +excluded_rules: "5401,5403" excluded_agents: "999" # Priority mapping from 1-12 (Wazuh events) to 1-5 (Discord and ntfy notification) +# Discord mention after x amount of event fired times + +priority_map: + - + threat_map: [15,14,13,12] + mention_threshold: 1 + color: 0xcc3300 + - + threat_map: [11,10,9] + mention_threshold: 1 + color: 0xff9966 + - + threat_map: [8,7,6] + mention_threshold: 5 + color: 0xffcc00 + - + threat_map: [5,4] + mention_threshold: 5 + color: 0x99cc33 + - + threat_map: [3,2,1,0] + mention_threshold: 5 + color: 0x339900 -priority_5: [ 15,14,13,12 ] -priority_4: [ 11,10,9 ] -priority_3: [ 8,7,6 ] -priority_2: [ 5,4 ] -priority_1: [ 3,2,1,0 ] sender: "Wazuh (IDS)" click: "https://google.com"