commit
f4a66df0f6
11
test.go
Normal file
11
test.go
Normal file
@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("hier")
|
||||
os.Stderr.Write([]byte("hier2"))
|
||||
}
|
||||
31
wazuh-notifier-conf.yaml
Executable file
31
wazuh-notifier-conf.yaml
Executable file
@ -0,0 +1,31 @@
|
||||
---
|
||||
#start of yaml
|
||||
|
||||
# This is the yaml config file for both the wazuh-ntfy-notifier.py and wazuh-discord-notifier.py.
|
||||
# The yaml needs to be in the same folder as the wazuh-ntfy-notifier.py and wazuh-discord-notifier.py
|
||||
|
||||
# COMMON (custom-wazuh-notifiers.py) configuration settings start here.
|
||||
# 1 = messages will be sent through this message server. 0 = messages will NOT be sent through this message server.
|
||||
|
||||
targets: "discord,ntfy"
|
||||
|
||||
# Exclude rules that are listed in the ossec.conf active response definition.
|
||||
|
||||
excluded_rules: "5401, 5403"
|
||||
excluded_agents: "999"
|
||||
|
||||
# Priority mapping from 1-12 (Wazuh events) to 1-5 (Discord and ntfy notification)
|
||||
|
||||
notifier_priority_1: 12, 11, 10
|
||||
notifier_priority_2: 9, 8
|
||||
notifier_priority_3: 7, 6
|
||||
notifier_priority_4: 5, 4
|
||||
notifier_priority_5: 3 ,2, 1
|
||||
|
||||
sender: "Wazuh (IDS)"
|
||||
click: "https://google.com"
|
||||
|
||||
|
||||
#end of yaml
|
||||
...
|
||||
|
||||
@ -16,11 +16,11 @@ excluded_agents: "999"
|
||||
|
||||
# Priority mapping from 1-12 (Wazuh events) to 1-5 (Discord and ntfy notification)
|
||||
|
||||
notifier_priority_1: 12, 11, 10
|
||||
notifier_priority_2: 9, 8
|
||||
notifier_priority_3: 7, 6
|
||||
notifier_priority_4: 5, 4
|
||||
notifier_priority_5: 3 ,2, 1
|
||||
priority_1: 12, 11, 10
|
||||
priority_2: 9, 8
|
||||
priority_3: 7, 6
|
||||
priority_4: 5, 4
|
||||
priority_5: 3 ,2, 1
|
||||
|
||||
sender: "Wazuh (IDS)"
|
||||
click: "https://google.com"
|
||||
|
||||
14
wazuh-notify-go/log/log.go
Normal file
14
wazuh-notify-go/log/log.go
Normal file
@ -0,0 +1,14 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
var f, _ = os.OpenFile("active-responses.log", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
|
||||
|
||||
func Log(message string) {
|
||||
if _, err := f.WriteString("\n" + time.Now().Format(time.DateTime) + message); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@ -2,19 +2,21 @@ package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"wazuh-notify/log"
|
||||
"wazuh-notify/notification"
|
||||
"wazuh-notify/types"
|
||||
"wazuh-notify/services"
|
||||
)
|
||||
|
||||
var inputParams types.Params
|
||||
|
||||
func main() {
|
||||
initNotify()
|
||||
inputParams := services.InitNotify()
|
||||
|
||||
for _, target := range strings.Split(inputParams.Targets, ",") {
|
||||
switch target {
|
||||
case "discord":
|
||||
log.Log(target)
|
||||
notification.SendDiscord(inputParams)
|
||||
case "ntfy":
|
||||
log.Log(target)
|
||||
notification.SendNtfy(inputParams)
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,26 +3,30 @@ package notification
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"wazuh-notify/types"
|
||||
)
|
||||
|
||||
func SendDiscord(params types.Params) {
|
||||
embedDescription := fmt.Sprintf("\n\n %s \n\nPriority: %x\nTags: %s\n\n%s",
|
||||
params.Message,
|
||||
params.Priority,
|
||||
params.Tags,
|
||||
params.Click,
|
||||
)
|
||||
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
|
||||
|
||||
message := types.Message{
|
||||
Username: params.Sender,
|
||||
Embeds: []types.Embed{
|
||||
{
|
||||
Title: params.Destination,
|
||||
Title: params.Sender,
|
||||
Description: embedDescription,
|
||||
},
|
||||
},
|
||||
|
||||
@ -11,7 +11,12 @@ import (
|
||||
|
||||
func SendNtfy(params types.Params) {
|
||||
|
||||
payload := time.Now().Format(time.RFC3339) + "\n\n" + params.Message
|
||||
payload := time.Now().Format(time.RFC3339) + "\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"
|
||||
|
||||
req, _ := http.NewRequest("POST", os.Getenv("NTFY_URL"), strings.NewReader(payload))
|
||||
req.Header.Set("Content-Type", "text/plain")
|
||||
|
||||
@ -1,34 +1,56 @@
|
||||
package main
|
||||
package services
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"github.com/joho/godotenv"
|
||||
"gopkg.in/yaml.v2"
|
||||
"log"
|
||||
"os"
|
||||
"wazuh-notify/log"
|
||||
"wazuh-notify/types"
|
||||
)
|
||||
|
||||
var inputParams types.Params
|
||||
var configParams types.Params
|
||||
var wazuhData types.WazuhMessage
|
||||
|
||||
func initNotify() {
|
||||
func InitNotify() types.Params {
|
||||
err := godotenv.Load()
|
||||
if err != nil {
|
||||
log.Fatalf(".env not found: %v", err)
|
||||
return
|
||||
log.Log("env failed to load")
|
||||
} else {
|
||||
log.Log("env loaded")
|
||||
}
|
||||
|
||||
wazuhInput()
|
||||
|
||||
yamlFile, err := os.ReadFile("./config.yaml")
|
||||
yaml.Unmarshal(yamlFile, &configParams)
|
||||
|
||||
flag.StringVar(&inputParams.Server, "server", "", "is the webhook URL of the Discord server. It is stored in .env.")
|
||||
log.Log("yaml loaded")
|
||||
|
||||
flag.StringVar(&inputParams.Url, "url", "", "is the webhook URL of the Discord server. It is stored in .env.")
|
||||
flag.StringVar(&inputParams.Click, "click", configParams.Click, "is a link (URL) that can be followed by tapping/clicking inside the message. Default is https://google.com.")
|
||||
flag.StringVar(&inputParams.Destination, "destination", "", "is the destination (actually the originator) of the message, either an app name or a person. Default is \"Wazuh (IDS)\"")
|
||||
flag.StringVar(&inputParams.Message, "message", "", "is the text of the message to be sent. Default is \"Test message\", but may include --tags and/or --click.")
|
||||
flag.IntVar(&inputParams.Priority, "priority", 0, "is the priority of the message, ranging from 1 (highest), to 5 (lowest). Default is 5.")
|
||||
flag.StringVar(&inputParams.Sender, "sender", configParams.Sender, "is the sender of the message, either an app name or a person. The default is \"Security message\".")
|
||||
flag.StringVar(&inputParams.Tags, "tags", "", "is an arbitrary strings of tags (keywords), seperated by a \",\" (comma). Default is \"informational,testing,hard-coded\".")
|
||||
flag.StringVar(&inputParams.Targets, "targets", "", "is a list of targets to send notifications to. Default is \"discord\".")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
log.Log("yaml loaded")
|
||||
inputParams.Targets = configParams.Targets
|
||||
|
||||
return inputParams
|
||||
}
|
||||
|
||||
func wazuhInput() {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
json.NewDecoder(reader).Decode(&wazuhData)
|
||||
|
||||
mapPriority()
|
||||
|
||||
inputParams.WazuhMessage = wazuhData
|
||||
}
|
||||
21
wazuh-notify-go/services/mapping.go
Normal file
21
wazuh-notify-go/services/mapping.go
Normal file
@ -0,0 +1,21 @@
|
||||
package services
|
||||
|
||||
import "slices"
|
||||
|
||||
func mapPriority() {
|
||||
if slices.Contains(configParams.Priority1, wazuhData.Parameters.Alert.Rule.Level) {
|
||||
inputParams.Priority = wazuhData.Parameters.Alert.Rule.Level
|
||||
}
|
||||
if slices.Contains(configParams.Priority2, wazuhData.Parameters.Alert.Rule.Level) {
|
||||
inputParams.Priority = wazuhData.Parameters.Alert.Rule.Level
|
||||
}
|
||||
if slices.Contains(configParams.Priority3, wazuhData.Parameters.Alert.Rule.Level) {
|
||||
inputParams.Priority = wazuhData.Parameters.Alert.Rule.Level
|
||||
}
|
||||
if slices.Contains(configParams.Priority4, wazuhData.Parameters.Alert.Rule.Level) {
|
||||
inputParams.Priority = wazuhData.Parameters.Alert.Rule.Level
|
||||
}
|
||||
if slices.Contains(configParams.Priority5, wazuhData.Parameters.Alert.Rule.Level) {
|
||||
inputParams.Priority = wazuhData.Parameters.Alert.Rule.Level
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,18 @@
|
||||
package types
|
||||
|
||||
type Params struct {
|
||||
Server string
|
||||
Url string
|
||||
Sender string `yaml:"sender,omitempty"`
|
||||
Destination string
|
||||
Priority int
|
||||
Message string
|
||||
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"`
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
|
||||
72
wazuh-notify-go/types/wazuh.go
Normal file
72
wazuh-notify-go/types/wazuh.go
Normal file
@ -0,0 +1,72 @@
|
||||
package types
|
||||
|
||||
type WazuhMessage struct {
|
||||
Version int `json:"version"`
|
||||
Origin Origin `json:"origin"`
|
||||
Command string `json:"command"`
|
||||
Parameters Parameters `json:"parameters"`
|
||||
}
|
||||
|
||||
type Origin struct {
|
||||
Name string `json:"name"`
|
||||
Module string `json:"module"`
|
||||
}
|
||||
|
||||
type Parameters struct {
|
||||
ExtraArgs []interface{} `json:"extra_args"`
|
||||
Alert Alert `json:"alert"`
|
||||
Program string `json:"program"`
|
||||
}
|
||||
|
||||
type Alert struct {
|
||||
Timestamp string `json:"timestamp"`
|
||||
Rule Rule `json:"rule"`
|
||||
Agent Agent `json:"agent"`
|
||||
Manager Manager `json:"manager"`
|
||||
ID string `json:"id"`
|
||||
FullLog string `json:"full_log"`
|
||||
Decoder Decoder `json:"decoder"`
|
||||
Data Data `json:"data"`
|
||||
Location string `json:"location"`
|
||||
}
|
||||
|
||||
type Rule struct {
|
||||
Level int `json:"level"`
|
||||
Description string `json:"description"`
|
||||
ID string `json:"id"`
|
||||
Mitre Mitre `json:"mitre"`
|
||||
Info string `json:"info"`
|
||||
Firedtimes int `json:"firedtimes"`
|
||||
Mail bool `json:"mail"`
|
||||
Groups []string `json:"groups"`
|
||||
PciDss []string `json:"pci_dss"`
|
||||
Gdpr []string `json:"gdpr"`
|
||||
Nist80053 []string `json:"nist_800_53"`
|
||||
Tsc []string `json:"tsc"`
|
||||
}
|
||||
|
||||
type Mitre struct {
|
||||
ID []string `json:"id"`
|
||||
Tactic []string `json:"tactic"`
|
||||
Technique []string `json:"technique"`
|
||||
}
|
||||
|
||||
type Agent struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type Decoder struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type Data struct {
|
||||
Protocol string `json:"protocol"`
|
||||
Srcip string `json:"srcip"`
|
||||
ID string `json:"id"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
@ -45,7 +45,7 @@ def set_environment():
|
||||
wazuh_path = "/var/ossec"
|
||||
# wazuh_path = os.path.abspath(os.path.join(__file__, "../../.."))
|
||||
ar_path = '{0}/logs/active-responses.log'.format(wazuh_path)
|
||||
config_path = 'wazuh-notifier-config.yaml'.format(wazuh_path)
|
||||
config_path = 'wazuh-notifier-conf.yaml'.format(wazuh_path)
|
||||
|
||||
return wazuh_path, ar_path, config_path
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user