Links
Comment on page

Wazuh Integration

Integration of AIR with Wazuh is possible via the feature called "Integrations".
When Wazuh's configuration file has the integration setting with specified RuleID, It runs a defined script. The defined python script sends the relevant information with a POST request to the AIR.

Steps to Integrate

Step 1: Create a Trigger for Wazuh

  • Visit the Webhooks page in Binalyze AIR,
  • Click the "+ New Webhook" button on the upper right corner,
  • Provide a self-explanatory name (examples: RDP Brute Force Trigger, Phishing Detected Trigger, etc.),
  • Select "Wazuh: Wazuh AIR Integration" as the parser for this webhook,
  • Select an Acquisition Profile when Wazuh activates this webhook,
  • Select the Ignore option or leave with its default value (defaults to 24 hours for recurrent alerts for a single endpoint),
  • Provide other settings such as Evidence Repository, CPU Limit, Compression & Encryption to use or let AIR configure them automatically based on the matching policy
  • Click the "Save" button,
  • Hover your mouse over the link below the Webhook name and double-click to copy (see below),

Step 2: Add the Integration Settings in Wazuh

Open the ossec.conf file with a preferred text editor and add the following line to the end of the file before closing the ossec_config. The name must be precisely custom-air. For detailed information, please see the Wazuh Documentation.
///reducted///
<integration>
<name>custom-air</name>
<hook_url>The Webhook URL copied in Step 1</hook_url>
<rule_id>The Rule ID you want to trigger AIR</rule_id>
<alert_format>json</alert_format>
</integration>
</ossec_config>

Step 3: Creating the scripts in Wazuh

  • Every time the relevant rule_id is triggered, a bash script named custom-air is executed. Create a file named custom-air in /var/ossec/integrations/ paste the following script. For detailed information, please refer to the Wazuh Documentation.
#!/bin/sh
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} "$@"
  • Create a python script named custom-air.py /var/ossec/integrations/ and paste the following script. The script runs another python script and makes a request to the air server.
#!/usr/bin/env python
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: pip3 install requests")
sys.exit(1)
# ossec.conf configuration:
# <integration>
# <name>custom-air</name>
# <hook_url>Wazuh WebHook URL</hook_url>
# <rule_id>XXXXXX</rule_id>
# <alert_format>json</alert_format>
# </integration>
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)
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()
def generate_msg(alert):
level = alert['rule']['level']
msg = {}
msg['pretext'] = "WAZUH AIR integration"
msg['Name'] = alert['agent']['name']
msg['IP'] = alert['agent']['ip']
msg['Title'] = alert['rule']['description'] if 'description' in alert['rule'] else "N/A"
msg['Rule ID'] = alert['rule']['id']
msg['ts'] = alert['id']
attach = {'attachments': [msg]}
return json.dumps(attach)
def send_msg(msg, url):
headers = {'User-Agent': 'Binalyze AIR Script', '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
  • The scripts must be placed in /var/ossec/integrations, have the same name as indicated in the configuration block, contain execution permissions, and belong to the root user of the ossec group. Execute the following two commands:
#chmod 750 /var/ossec/integrations/custom-air
#chown root:ossec /var/ossec/integrations/custom-air
#chmod 750 /var/ossec/integrations/custom-air.py
#chown root:ossec /var/ossec/integrations/custom-air.py