Custom NTFY integration; perhaps you forgot a comma?

51 views
Skip to first unread message

Zero Two

unread,
Nov 1, 2024, 5:39:57 PM11/1/24
to Wazuh | Mailing List
Greetings:

I modified the Iris.py so that I could send notifications to a ntfy server.  Here is my config:

#!/var/ossec/framework/python/bin/python3
# custom-wazuh_ntfy.py
# Custom Wazuh integration script to send alerts to ntfy

import sys
import json
import requests
import logging
from datetime import datetime

# Configure logging
logging.basicConfig(filename='/var/ossec/logs/integrations.log', level=logging.INFO,
                    format='%(asctime)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S')

# Function to create a formatted string from alert details
def format_alert_details(alert_json):
    rule = alert_json.get("rule", {})
    agent = alert_json.get("agent", {})
   
    # Extracting MITRE information from the nested 'rule' structure
    mitre = rule.get("mitre", {})
    mitre_ids = ', '.join(mitre.get("id", ["N/A"]))
    mitre_tactics = ', '.join(mitre.get("tactic", ["N/A"]))
    mitre_techniques = ', '.join(mitre.get("technique", ["N/A"]))

    details = [
        f"Rule ID: {rule.get('id', 'N/A')}",
        f"Rule Level: {rule.get('level', 'N/A')}",
        f"Rule Description: {rule.get('description', 'N/A')}",
        f"Agent ID: {agent.get('id', 'N/A')}",
        f"Agent Name: {agent.get('name', 'N/A')}",
        f"MITRE IDs: {mitre_ids}",
        f"MITRE Tactics: {mitre_tactics}",
        f"MITRE Techniques: {mitre_techniques}",
        f"Location: {alert_json.get('location', 'N/A')}",
        f"Full Log: {alert_json.get('full_log', 'N/A')}"
    ]
    return '\n'.join(details)

def main():
    # Read parameters when integration is run
    if len(sys.argv) < 4:
        logging.error("Insufficient arguments provided. Exiting.")
        sys.exit(1)
   
    alert_file = sys.argv[1]
    api_key = sys.argv[2]
    hook_url = sys.argv[3]

    # Read the alert file
    try:
        with open(alert_file) as f:
            alert_json = json.load(f)
    except Exception as e:
        logging.error(f"Failed to read alert file: {e}")
        sys.exit(1)

    # Prepare alert details
    alert_details = format_alert_details(alert_json)

    # Convert Wazuh rule levels(0-15) -> ntfy severity(1-6)
    alert_level = alert_json.get("rule", {}).get("level", 0)
    if alert_level < 5:
        severity = 1
    elif alert_level >= 5 and alert_level < 7:
        severity = 2
    elif alert_level >= 7 and alert_level < 10:
        severity = 3
    elif alert_level >= 10 and alert_level < 13:
        severity = 4
    elif alert_level >= 13:
        severity = 5
    else:
        severity = 1

    # Convert Wazuh rule levels(0-15) -> ntfy icons
    alert_level = alert_json.get("rule", {}).get("level", 0)
    if alert_level < 5:
        tag = "love_you_gesture"
    elif alert_level >= 5 and alert_level < 7:
        tag = "+1"
    elif alert_level >= 7 and alert_level < 10:
        tag = "pinching_hand"
    elif alert_level >= 10 and alert_level < 13:
        tag = "-1"
    elif alert_level >= 13:
        tag = "middle_finger"
    else:
        tag = "+1"

    # Generate request
    payload = json.dumps({
"topic": "wazuh",
"title": alert_json.get("rule", {}).get("description", "No Description"),
"message": "Details:" alert_details,
"click": "https://wazuhdashboard-0.dauntless.local/app/wz-home",
        "priority": severity,
"tags": tag
    })

    # Send request to ntfy
    try:
        response = requests.post(hook_url, data=payload, headers={"Authorization": "Bearer " + api_key, "content-type": "application/json"}, verify=False)
        if response.status_code in [200, 201, 202, 204]:
            logging.info(f"Sent alert to ntfy. Response status code: {response.status_code}")
        else:
            logging.error(f"Failed to send alert to ntfy. Response status code: {response.status_code}")
    except Exception as e:
        logging.error(f"Failed to send alert to ntfy: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()

Unfortunately, I keep getting this error:
2024/11/01 21:33:37 wazuh-integratord: ERROR: Exit status was: 1
2024/11/01 21:33:37 wazuh-integratord: ERROR: Unable to run integration for custom-wazuh_ntfy.py -> integrations
2024/11/01 21:33:37 wazuh-integratord: ERROR: While running custom-wazuh_ntfy.py -> integrations. Output: SyntaxError: invalid syntax. Perhaps you forgot a comma?

Any suggestions?

Thank you!

Jose Camargo

unread,
Nov 1, 2024, 6:18:33 PM11/1/24
to Wazuh | Mailing List
Hello,

Have you tried running the script manually? Do you get any results? Try to add debug lines (print) to the script so you see where it is failing once it runs.

I'll be awaiting your comments.

Regards,
Jose

Zero Two

unread,
Nov 1, 2024, 9:34:12 PM11/1/24
to Wazuh | Mailing List
Thank you, Jose.  Don't know why, but "alert_details" was causing a formatting/syntax error.

Now, any idea how to properly render  these alerts?  My alerts in ntfy look like the json isn't being decoded properly (or encoded, depending how you look at it)

Screenshot_20241101_210429.png

Thank you!

Jose Camargo

unread,
Nov 4, 2024, 3:22:14 PM11/4/24
to Wazuh | Mailing List
Hello,

You can check an example on how to parse the alerts in the JIRA integration script here https://wazuh.com/blog/how-to-integrate-external-software-using-integrator/

I'll be awaiting your comments.

Regards,
Jose

Reply all
Reply to author
Forward
0 new messages