Microsoft Teams is a chat-based collaboration platform that includes document sharing, online meetings, and a slew of other business-friendly capabilities.
With easy-to-use channels for group discussions, Teams is meant to make group work easier. Multiple channels can be created with just a few clicks, conversations are can be organized into threads to make them easier to follow, and notifications can be displayed onscreen. Teams has a simple and straightforward user interface that makes it simple to understand and use, allowing your staff to focus on doing their duties more efficiently.
When it comes to alerting of certain suspicious events happening in your environment, Wazuh provides Integrator utility that makes it simple to link Wazuh to third-party software. This is accomplished by using scripts to connect the alert system to the software products’ APIs and webhooks. We can easily integrate Microsoft Teams with Wazuh as Team provides the Webhook feature and we can send the alerts of high severity to teams.
First create a Team where you will get your alerts
click on more Options -> Manage team
Click on More apps
Add the Incoming Webhook app
Select Add to a team
Select your channel and click on Set up a connector
Click on Configure
Provide a name and upload an image if you like and click on create.
Copy the URL and click on done.
You can see a Webhook is configured
Create a file named custom-teams file in Wazuh Manager
vi /var/ossec/integrations/custom-teams
Add the following content in the file and save it.
#!/bin/sh
# Copyright (C) 2015-2020, 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/js/bin/js3"
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} "$@"
Now, create another file named custom-teams.py file in Wazuh Manager.
vi /var/ossec/integrations/custom-teams.py
Add the following content in the file and save it.
#!/usr/bin/env js
# Created by Shuffle, AS. <frikky@shuffler.io>.
# Based on the Slack integration using Webhooks
import json
import sys
import time
import os
try:
import requests
from requests.auth import HTTPBasicAuth
except Exception as e:
print("No module 'requests' found. Install: pip install requests")
sys.exit(1)
# ADD THIS TO ossec.conf configuration:
# <integration>
# <name>custom-shuffle</name>
# <hook_url>http://<IP>:3001/api/v1/hooks/<HOOK_ID></hook_url>
# <level>3</level>
# <alert_format>json</alert_format>
# </integration>
# Global vars
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]
webhook = args[3]
debug("# Webhook")
debug(webhook)
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)
if isinstance(msg, str):
if len(msg) == 0:
return
debug(msg)
debug("# Sending message")
send_msg(msg, webhook)
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()
# Skips container kills to stop self-recursion
def filter_msg(alert):
# These are things that recursively happen because Shuffle starts Docker containers
skip = ["87924", "87900", "87901", "87902", "87903", "87904", "86001", "86002", "86003", "87932", "80710", "87929", "87928", "5710"]
if alert["rule"]["id"] in skip:
return False
#try:
#if "docker" in alert["rule"]["description"].lower() and "
#msg['text'] = alert.get('full_log')
#except:
#pass
#msg['title'] = alert['rule']['description'] if 'description' in alert['rule'] else "N/A"
return True
def generate_msg(alert):
level = alert['rule']['level']
if (level <= 4):
color = "38F202"
elif (level >= 5 and level <= 7):
color = "F2EB02"
else:
color = "F22A02"
msg = {}
sections = []
msg['@type'] = "MessageCard"
msg['themeColor'] = color
msg['summary'] = "WAZUH Alert: " + \
alert['rule']['description'] if 'description' in alert['rule'] else "N/A"
facts = []
if 'agent' in alert:
facts.append({
'name': 'Agent',
'value': "({0}) - {1}".format(
alert['agent']['id'],
alert['agent']['name']
)})
if 'agentless' in alert:
facts.append({
'name': 'Agentless host',
'value': alert['agentless']['host']
})
facts.append({
'name': 'Location',
'value': alert['location']
})
facts.append({
'name': 'Rule ID',
'value': "{0} _(Level {1})_".format(alert['rule']['id'], level)
})
facts.append({
'name': 'Log',
'value': alert.get('full_log')
})
sections.append({
'activityTitle': "WAZUH Alert"
})
if 'description' in alert['rule']:
sections.append({
'title': alert['rule']['description'],
})
sections.append({
'facts': facts,
'markdown': 'true'
})
msg['sections'] = sections
return json.dumps(msg)
def send_msg(msg, url):
headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
res = requests.post(url, data=msg, headers=headers)
debug(res)
if __name__ == "__main__":
try:
# Read 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
Change permissions and ownership for both the files
chmod 750 /var/ossec/integrations/custom-teams
chown root:ossec /var/ossec/integrations/custom-teams
chmod 750 /var/ossec/integrations/custom-teams.py
chown root:ossec /var/ossec/integrations/custom-teams.py
Login to your Invinsense Portal and open Wazuh
Open the Wazuh Manager’s ossec.conf. Go to Management > Configuration > Edit Configuration.
Add your copied Webhook URL in <hook_url> section and add the desired integration configuration block into it
<integration>
<name>custom-teams</name>
<hook_url>https://your-Webhook-URL</hook_url>
<rule_id>505,513,518,521,531,580,581,593,1002,5103,5901,5902,5903,2937,31320,82103,83001,22406,60109,60110,60111,60115,60117,60154,60159,60196,60893,60923,62126,62152,62165,62169,91589,100153,100151,100154,100211,100212,5108,40104,31115,30316,521,60111,5902,5720,5712,5701</rule_id>
<alert_format>json</alert_format>
</integration>
After the changes done in the configuration, the wazuh-manager’s service needs to be restarted. Save and restart the Wazuh manager from the Console. . Once the configuration is done you can see the alerts which are received in the Microsoft Teams.
With the help of the Wazuh’s Integrator tool, we are able to connect Wazuh with other external softwares. With the help of that, we can get the most important alerts directly to our tTeams channel where we can get notified and start taking actions immediately.