Links

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} "[email protected]"
  • 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