Skip to content

Instantly share code, notes, and snippets.

@redsfyre
Last active September 17, 2024 14:18
Show Gist options
  • Save redsfyre/8f4887ba9440a008661cbdfef1b3d8eb to your computer and use it in GitHub Desktop.
Save redsfyre/8f4887ba9440a008661cbdfef1b3d8eb to your computer and use it in GitHub Desktop.
An example script for Wazuh - Opsgenie integrations. You need to edit the issue_data variable within the generate_msg function. For example, you should write the name of the team you created on opsgenie in the responder field. Find "XXXX Team" in the code below. Below code tested on Wazuh 4.3.7
#!/bin/bash
# Copyright (C) 2015, Wazuh Inc.
# Created by Wazuh, Inc. <info@wazuh.com>.
# This program is free software; you can redistribute it and/or modify it under the terms of GPLv2
WPYTHON_BIN="framework/python/bin/python3"
SCRIPT_PATH_NAME="$0"
DIR_NAME="$(cd $(dirname ${SCRIPT_PATH_NAME}); pwd -P)"
SCRIPT_NAME="$(basename ${SCRIPT_PATH_NAME})"
case ${DIR_NAME} in
*/active-response/bin | */wodles*)
if [ -z "${WAZUH_PATH}" ]; then
WAZUH_PATH="$(cd ${DIR_NAME}/../..; pwd)"
fi
PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
;;
*/bin)
if [ -z "${WAZUH_PATH}" ]; then
WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
fi
PYTHON_SCRIPT="${WAZUH_PATH}/framework/scripts/${SCRIPT_NAME}.py"
;;
*/integrations)
if [ -z "${WAZUH_PATH}" ]; then
WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
fi
PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
;;
esac
${WAZUH_PATH}/${WPYTHON_BIN} ${PYTHON_SCRIPT} "$@"
#!/usr/bin/env python
import sys
import json
import time
import os
try:
import requests
from requests.auth import HTTPBasicAuth
except Exception as e:
print ("No module named requests. Please install using: pip install requests")
sys.exit(1)
# Global variables
debug_enabled = False
pwd = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
json_alert = {}
now = time.strftime("%a %b %d %H:%M:%S %Z %Y")
# Set paths
log_file = '{0}/logs/integrations.log'.format(pwd)
def main(args):
debug("# Starting")
# Read args
alert_file_location = args[1]
api_key = args[2]
hook_url = args[3]
debug("# Webhook")
debug(hook_url)
debug("# File location")
debug(alert_file_location)
# Load alert. Parse JSON object.
with open(alert_file_location) as alert_file:
json_alert = json.load(alert_file)
debug("# Processing alert")
debug(json_alert)
debug("# Generating message")
msg = generate_msg(json_alert)
debug(msg)
debug("# Sending message")
send_msg(msg, api_key, hook_url)
def debug(msg):
if debug_enabled:
msg = "{0}: {1}\n".format(now, msg)
print(msg)
f = open(log_file, "a")
f.write(msg)
f.close()
def generate_msg(alert):
alert_level = alert['rule']['level']
ruleid = alert['rule']['id']
description = alert['rule']['description']
agentid = alert['agent']['id']
agentname = alert['agent']['name']
full_log = alert['full_log']
issue_data = {
"message": 'Wazuh alert' + ' - ' + agentname + ' - ' + description,
"alias": 'Wazuh alert' + ' - ' + agentname + ' - ' + description,
"description": full_log,
"responders": [{"name": "XXXX Team", "type": "team"}],
"visibleTo": [{'name': 'all', "type": "team"}],
"tags": ['Wazuh', 'Alert', 'Level ' + str(alert_level), 'Rule ' + str(ruleid), 'Agent ' + str(agentid)],
"actions": ['acknowledge', 'close'],
"details": {},
"entity": 'Wazuh alert' + ' - ' + agentname + ' - ' + description,
"priority": "P3"
}
return json.dumps(issue_data)
def send_msg(msg, api_key, hook_url):
headers = {'content-type': 'application/json','Authorization': 'GenieKey ' + api_key}
res = requests.post(hook_url, data=msg, headers=headers)
debug(res)
if __name__ == "__main__":
try:
# Check arguments
bad_arguments = False
if len(sys.argv) >= 4:
msg = '{0} {1} {2} {3} {4}'.format(
now,
sys.argv[1],
sys.argv[2],
sys.argv[3],
sys.argv[4] if len(sys.argv) > 4 else '',
)
debug_enabled = (len(sys.argv) > 4 and sys.argv[4] == 'debug')
else:
msg = '{0} Wrong arguments'.format(now)
bad_arguments = True
# Logging the call
f = open(log_file, 'a')
f.write(msg + '\n')
f.close()
if bad_arguments:
debug("# Exiting: Bad arguments.")
sys.exit(1)
# Main function
main(sys.argv)
except Exception as e:
debug(str(e))
raise
<!--Opsgenie Integration -->
<integration>
<name>custom-opsgenieintegration</name>
<hook_url>WEBHOOK</hook_url>
<level>12</level>
<api_key>API_KEY</api_key>
<alert_format>json</alert_format>
</integration>
@redsfyre
Copy link
Author

redsfyre commented Sep 9, 2022

The name of the custom integration must start with "custom-" and the rest of the name must not have a "-" sign. Otherwise the integration is not triggered by Wazuh

@mpeirone
Copy link

Thank you very much, it works! When you install this module you must also remember to set the correct groups and permissions.

@redsfyre
Copy link
Author

redsfyre commented Sep 17, 2024

Thank you very much, it works! When you install this module you must also remember to set the correct groups and permissions.

I'm glad to hear that @mpeirone . This is one of the first projects that I share with the community, and I was very happy that it really worked for someone.

Also in the new wazuh versions there is a new feature called active response. I haven't had a chance to try it yet, but maybe it works better than this.

AFAIK the Opsgenie API has not changed in the last two years, but it may be useful to review the relevant documentations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment