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.
1
///reducted///
2
3
<integration>
4
<name>custom-air</name>
5
<hook_url>The Webhook URL copied in Step 1</hook_url>
6
<rule_id>The Rule ID you want to trigger AIR</rule_id>
7
<alert_format>json</alert_format>
8
</integration>
9
10
</ossec_config>
Copied!

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.
1
#!/bin/sh
2
3
WPYTHON_BIN="framework/python/bin/python3"
4
5
SCRIPT_PATH_NAME="$0"
6
7
DIR_NAME="$(cd $(dirname ${SCRIPT_PATH_NAME}); pwd -P)"
8
9
SCRIPT_NAME="$(basename ${SCRIPT_PATH_NAME})"
10
11
case ${DIR_NAME} in
12
*/active-response/bin | */wodles*)
13
if [ -z "${WAZUH_PATH}" ]; then
14
WAZUH_PATH="$(cd ${DIR_NAME}/../..; pwd)"
15
fi
16
PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
17
;;
18
*/bin)
19
if [ -z "${WAZUH_PATH}" ]; then
20
WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
21
fi
22
PYTHON_SCRIPT="${WAZUH_PATH}/framework/scripts/${SCRIPT_NAME}.py"
23
;;
24
*/integrations)
25
if [ -z "${WAZUH_PATH}" ]; then
26
WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
27
fi
28
PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
29
;;
30
esac
31
${WAZUH_PATH}/${WPYTHON_BIN} ${PYTHON_SCRIPT} "[email protected]"
Copied!
  • 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.
1
#!/usr/bin/env python
2
3
import json
4
import sys
5
import time
6
import os
7
8
try:
9
import requests
10
from requests.auth import HTTPBasicAuth
11
except Exception as e:
12
print("No module 'requests' found. Install: pip3 install requests")
13
sys.exit(1)
14
15
# ossec.conf configuration:
16
# <integration>
17
# <name>custom-air</name>
18
# <hook_url>Wazuh WebHook URL</hook_url>
19
# <rule_id>XXXXXX</rule_id>
20
# <alert_format>json</alert_format>
21
# </integration>
22
23
24
debug_enabled = False
25
pwd = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
26
json_alert = {}
27
now = time.strftime("%a %b %d %H:%M:%S %Z %Y")
28
29
# Set paths
30
log_file = '{0}/logs/integrations.log'.format(pwd)
31
32
33
def main(args):
34
debug("# Starting")
35
36
# Read args
37
alert_file_location = args[1]
38
webhook = args[3]
39
40
debug("# Webhook")
41
debug(webhook)
42
debug("# File location")
43
debug(alert_file_location)
44
45
# Load alert. Parse JSON object.
46
with open(alert_file_location) as alert_file:
47
json_alert = json.load(alert_file)
48
debug("# Processing alert")
49
debug(json_alert)
50
debug("# Generating message")
51
msg = generate_msg(json_alert)
52
debug(msg)
53
debug("# Sending message")
54
send_msg(msg, webhook)
55
56
def debug(msg):
57
if debug_enabled:
58
msg = "{0}: {1}\n".format(now, msg)
59
print(msg)
60
f = open(log_file, "a")
61
f.write(msg)
62
f.close()
63
64
def generate_msg(alert):
65
level = alert['rule']['level']
66
msg = {}
67
msg['pretext'] = "WAZUH AIR integration"
68
msg['Name'] = alert['agent']['name']
69
msg['IP'] = alert['agent']['ip']
70
msg['Title'] = alert['rule']['description'] if 'description' in alert['rule'] else "N/A"
71
msg['Rule ID'] = alert['rule']['id']
72
msg['ts'] = alert['id']
73
attach = {'attachments': [msg]}
74
return json.dumps(attach)
75
76
def send_msg(msg, url):
77
headers = {'User-Agent': 'Binalyze AIR Script', 'Content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
78
res = requests.post(url, data=msg, headers=headers)
79
debug(res)
80
81
if __name__ == "__main__":
82
83
try:
84
# Read arguments
85
bad_arguments = False
86
if len(sys.argv) >= 4:
87
msg = '{0} {1} {2} {3} {4}'.format(
88
now,
89
sys.argv[1],
90
sys.argv[2],
91
sys.argv[3],
92
sys.argv[4] if len(sys.argv) > 4 else '',
93
)
94
debug_enabled = (len(sys.argv) > 4 and sys.argv[4] == 'debug')
95
96
else:
97
msg = '{0} Wrong arguments'.format(now)
98
bad_arguments = True
99
100
# Logging the call
101
f = open(log_file, 'a')
102
f.write(msg + '\n')
103
f.close()
104
105
if bad_arguments:
106
debug("# Exiting: Bad arguments.")
107
sys.exit(1)
108
109
# Main function
110
main(sys.argv)
111
112
except Exception as e:
113
debug(str(e))
114
raise
Copied!
  • 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:
1
#chmod 750 /var/ossec/integrations/custom-air
2
3
#chown root:ossec /var/ossec/integrations/custom-air
4
5
#chmod 750 /var/ossec/integrations/custom-air.py
6
7
#chown root:ossec /var/ossec/integrations/custom-air.py
Copied!
Last modified 1mo ago
Copy link