Defender for Endpoints Integration

395 views
Skip to first unread message

meganie

unread,
Sep 26, 2023, 8:16:43 AM9/26/23
to Wazuh | Mailing List
Hi, I would like to integrate Windows Defender for Endpoints alerts into Wazuh.

Unfortunately the alerts don't show up in the dashboard.
Here are all the steps I've done:

1. Added a file to /var/ossec/integrations/defender_for_endpoint_alerts.py

#!/usr/bin/python3

import argparse
import json
import urllib.request
import urllib.parse
import sys
import logging
from datetime import datetime, timedelta
from socket import socket, AF_UNIX, SOCK_DGRAM

tenantId = 'xxx' # Paste your own tenant ID here
appId = 'xxx' # Paste your own app ID here
appSecret = 'xxx' # Paste your own app secret here

# Wazuh manager analisysd socket address
socketAddr = '/var/ossec/queue/sockets/queue'

parser = argparse.ArgumentParser(description='SOCFortress Wazuh - Office Defender Alerts and Indicators information.')
args = parser.parse_args()

# Send event to Wazuh manager
def send_event(msg):
    logging.debug('Sending {} to {} socket.'.format(msg, socketAddr))
    string = '1:office_defender:{}'.format(msg)
    sock = socket(AF_UNIX, SOCK_DGRAM)
    sock.connect(socketAddr)
    sock.send(string.encode())
    sock.close()

# Request Token
url = "https://login.microsoftonline.com/%s/oauth2/token" % (tenantId)

resourceAppIdUri = 'https://api.securitycenter.microsoft.com'

body = {
    'resource' : resourceAppIdUri,
    'client_id' : appId,
    'client_secret' : appSecret,
    'grant_type' : 'client_credentials'
}

data = urllib.parse.urlencode(body).encode("utf-8")

# Read Access Token
req = urllib.request.Request(url, data)
response = urllib.request.urlopen(req)
jsonResponse = json.loads(response.read())
aadToken = jsonResponse["access_token"]


#build get-alerts API
filterTime = datetime.utcnow() - timedelta(hours = 1)          #If you want to include alerts from longer then an hour, change here (days, weeks)
filterTime = filterTime.strftime("%Y-%m-%dT%H:%M:%SZ")

## Get Alerts #########################################################
url = "https://api.securitycenter.microsoft.com/api/alerts?$filter=alertCreationTime+ge+{}".format(filterTime)
headers = {
    'Content-Type' : 'application/json',
    'Accept' : 'application/json',
    'Authorization' : "Bearer " + aadToken
}


req = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(req)
jsonResponse = json.loads(response.read())
for alert in jsonResponse["value"]:
        office_defender_event = {}
        office_defender_event['office_defender'] = alert
        office_defender_event['query'] = 'alerts'
        send_event(json.dumps(office_defender_event))

## Get Indicators#################################################################
url = "https://api.securitycenter.microsoft.com/api/indicators"
headers = {
    'Content-Type' : 'application/json',
    'Accept' : 'application/json',
    'Authorization' : "Bearer " + aadToken
}


req = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(req)
jsonResponse = json.loads(response.read())
for alert in jsonResponse["value"]:
        office_defender_event = {}
        office_defender_event['office_defender'] = alert
        office_defender_event['query'] = 'indicators'
        send_event(json.dumps(office_defender_event))

2. Fixed the file permissions:
chmod +x
chown root:wazuh
chmod 750

3. Added the rule file 109000-microsoft_defender.xml via the dashboard.

4. Added this part to the ossec.conf of my manager and restarted the manager:

  <integration>
    <name>defender_for_endpoint_alerts.py</name>
    <alert_format>json</alert_format>
  </integration>


5. If I understand that correctly I have to execute the script via a cronjob to pull the alerts. For the test I've executed the script manually after I've created an alert.
Incidents.PNG

The script executed without an error so the authentication and Azure permissions (Alert.ReadWrite.All & Ti.ReadWrite.All) should be fine. But I don't see any alerts with those rule.ids. If I see that correctly this incident should trigger alert 109002

Marcos Darío Buslaiman

unread,
Sep 26, 2023, 9:29:14 AM9/26/23
to Wazuh | Mailing List
Hi  Meganie,
Thanks for using Wazuh!
This integration will work by executing the Python script from your Wazuh Manager, connecting to the API with the data provided (
tenantId ,appID, secret), and collecting the data.
You can execute the script from the Wazuh Manager to verify if it runs without errors, and then with the integration module, you will add the script to be executed by Wazuh.
  <integration>
    <name>defender_for_endpoint_alerts.py</name>
    <alert_format>json</alert_format>
  </integration>
If the scripts run without error from Wazuh Manager, the integration is configured and Wazuh Manager was restarted, you can verify the logs at /var/ossec/logs/ossec.log and /var/ossec/logs/integrations.log to verify if it is running with errors.

Please also share your Wazuh Manager version in order to validate the integration.

Regards
Marcos

Marcos Darío Buslaiman

unread,
Sep 26, 2023, 9:46:12 AM9/26/23
to Wazuh | Mailing List
Sorry, I forgot to mention, what I mean by running the script from the WAzuh Manager like this, and verifying if it runs successfully.
[root@wazuh-server ~]# /var/ossec/integrations/defender_for_endpoint_alerts.py

Regards

meganie

unread,
Sep 26, 2023, 10:50:52 AM9/26/23
to Wazuh | Mailing List

Thanks for the fast answer. I got something here:

root@wazuh-server:/tmp# grep defender /var/ossec/logs/ossec.log | tail -1
2023/09/26 16:29:06 wazuh-integratord: ERROR: Invalid integration: 'defender_for_endpoint_alerts.py'. Not currently supported.


After that I've changed the name to custom-defender_for_endpoint_alerts.py

root@wazuh-server:/tmp# grep defender /var/ossec/logs/ossec.log | tail -2
2023/09/26 16:43:08 wazuh-integratord: ERROR: Unable to run integration for custom-defender_for_endpoint_alerts.py -> integrations
2023/09/26 16:43:08 wazuh-integratord: ERROR: While running custom-defender_for_endpoint_alerts.py -> integrations. Output: custom-defender_for_endpoint_alerts.py: error: unrecognized arguments: /tmp/custom-defender_for_endpoint_alerts.py-1695739388-933230296.alert    > /dev/null 2>&1


Where does that argument come from? My Wazuh Manager version is 4.5.2

Marcos Darío Buslaiman

unread,
Sep 26, 2023, 11:42:29 AM9/26/23
to Wazuh | Mailing List
Hi Meganie,
Let me verify this error and I'll keep you updated.
In the meantime, have you executed the script from your Wazuh Manager server? it's running ok, or are getting errors?
[root@wazuh-server ~]# /var/ossec/integrations/defender_for_endpoint_alerts.py

Regards

meganie

unread,
Sep 26, 2023, 12:06:05 PM9/26/23
to Wazuh | Mailing List
Yes, I ran it manually from my Wazuh manager server and it looks ok to me. By the way: It is ok to have an integration only on one node of a 3 node cluster right?
script.PNG

Marcos Darío Buslaiman

unread,
Sep 26, 2023, 2:34:43 PM9/26/23
to Wazuh | Mailing List
Hi meganie,
According to that is mentioned in the documentation of this script.
Microsoft Defender for Endpoint has an API that we can interact with to pull alerts and events through Wazuh. The Python scripts will pull events from the supported Defender for Endpoint API queries. These can be tied to a cronjob to pull during set intervals.

This script, on each execution, will pull the alerts and will be sent to the wazuh manager socket to be analyzed and alerted in case they match with the rules.
So I will recommend you use the wodle command instead of the integration
To configure this you will need to:
  1. Allow the execution of the commands by adding "wazuh_command.remote_commands=1" to the file /var/ossec/etc/local_internal_options.conf
  2. Configure the   wodle command  on the configuration file /var/ossec/etc/ossec.conf on your manager
    <wodle name="command">
    <disabled>no</disabled>
    <tag>WinDefenderAlerts</tag>
    <command>/var/ossec/integrations/defender_for_endpoint_alerts.py</command>
    <interval>5m</interval>
    <ignore_output>yes</ignore_output>
    <run_on_start>yes</run_on_start>
    <timeout>0</timeout>
    </wodle>
This is an example you can add the configurations that you need, you can check the following documentation:
https://documentation.wazuh.com/current/user-manual/reference/ossec-conf/wodle-command.html#command

The other approach is scheduling this script with a cronjob.

Regarding to your question "It is ok to have an integration only on one node of a 3 node cluster right?"
This depends on the integration for instance if the integration will be forwarding alerts, like the Slack integration, you will need to set this on all of your nodes where you are receiving events from agents, due to the alerts will be on each node.

Regards

meganie

unread,
Sep 27, 2023, 9:18:13 AM9/27/23
to Wazuh | Mailing List
For future reference:

Running the script via wodle or cronjob works fine.
(Adding "wazuh_command.remote_commands=1" to the file /var/ossec/etc/local_internal_options.conf is not required if you run scripts from the ossec.conf of the manager, only if you run it from agent.conf: https://documentation.wazuh.com/current/user-manual/reference/ossec-conf/wodle-command.html#centralized-configuration)

My main problem was that there were no alerts in the Wazuh Dashboard.
The cause was that my events didn't came from "microsoft_defender" but from "office_defender" so the rules couldn't match.
If you have the same problem just replace every "microsoft" with "office" in the rules file and your good to go.

Only problem I have now is that the script pulls all alerts from the last hour no matter if they were pulled previously or not.
I've set the wodle interval to 1m to pull new alerts as quickly as possible because I actually use those events for incident response in TheHive.
I've edited the line in the defender_for_endpoint_alerts.py accordingly but I still get multiple alerts per Defender Event.
filterTime = datetime.utcnow() - timedelta(minutes= 1) #If you want to include alerts from longer then an hour, change here (days, weeks)

Is it possible to tell a rule that it should only trigger once per unique value in a field?
Fox example: office_defender.firstEventTime or data.office_defender.incidentId
The rule should only trigger again if the value in one of those fields changes.

Marcos Darío Buslaiman

unread,
Sep 28, 2023, 2:29:24 PM9/28/23
to Wazuh | Mailing List
Hi meganie,
Thanks for your feedback about this issue.

Regarding your question, you can use the rule parameter same_field or different-field that should be used with a frequency to match a value if it was repeated in the timeframe defined.
Here you can check an example.

<!-- {"key":"value", "key2":"AAAA"} -->
<rule id="100001" level="3">
  <decoded_as>json</decoded_as>
  <field name="key">value</field>
  <description>Testing JSON alert</description>
</rule>

<rule id="100002" level="10" frequency="4" timeframe="300">
  <if_matched_sid>100001</if_matched_sid>
  <same_field>key2</same_field>
  <description>Testing same_field option</description>
</rule>

Rule 100002 will fire when key2 in the currently considered event is the same in four events that matched rule 100001 before within the last 300 seconds. Therefore, for the sequence of the following events:
{"key":"value", "key2":"AAAA"}
{"key":"value", "key2":"AAAA"}
{"key":"value", "key2":"BBBB"}
{"key":"value", "key2":"AAAA"}
{"key":"value", "key2":"CCCC"}
{"key":"value", "key2":"CCCC"}
{"key":"value", "key2":"AAAA"}

The last event will fire rule 100002 instead of 100001 because it found the value AAAA in three of the previous events.

Here you can find more information about rule syntax and some examples.
Reply all
Reply to author
Forward
0 new messages