Need some assitance on integration with slack for alerts

354 views
Skip to first unread message

abhi

unread,
Aug 13, 2024, 3:47:24 AM8/13/24
to Wazuh | Mailing List
Hi,

I would like to know, how do i integrate wazuh with slack to receive the alerts and how to get notified only for level 10 and above on the slack channel

kindly assist me on the above mentioned integration
Message has been deleted

Juan Manuel Segura Duarte

unread,
Aug 13, 2024, 5:04:38 AM8/13/24
to Wazuh | Mailing List
Hello abhi,

To set up the Slack integration, perform the following steps:
1. Enable incoming webhooks and create one for your Slack channel. Follow the Slack guide on incoming webhooks for this.

2. Append the configuration below to the `/var/ossec/etc/ossec.conf` file on the Wazuh server (manager). Replace `<WEBHOOK_URL>` with your incoming webhook.
```
<ossec_config>
  <integration>
    <name>slack</name>
    <hook_url><SLACK_WEBHOOK_URL></hook_url> <!-- Replace with your Slack hook URL -->
    <alert_format>json</alert_format>
    <level>10</level>   <!-- Only get notified for alerts with level 10 or greater -->
  </integration>
</ossec_config>

```

Note

 

You can set a JSON object with customization fields using the options tag. Visit the Slack API reference for information about available customization fields.



3. Restart the Wazuh manager to apply the changes:
`systemctl restart wazuh-manager`

Once the configuration is complete, alerts start showing in the selected channel.

Alerts in selected Slack channel

Here you can find the official documentation about integrating Slack with Wazuh: https://documentation.wazuh.com/current/user-manual/manager/integration-with-external-apis.html#slack
And here you can find the full reference for the `<integration>` field: https://documentation.wazuh.com/current/user-manual/reference/ossec-conf/integration.html
In the reference, you can find more settings to fine-tune the alerts you want to get notified about (for example, filter by group).

We hope you find this information useful.
Regards,
Juan Manuel
Message has been deleted
Message has been deleted

abhi

unread,
Aug 13, 2024, 6:54:34 AM8/13/24
to Wazuh | Mailing List
Hi Juan,

I'm able to receive logs to slack successfully for level 10 alerts 
I'm attaching a screenshot were in agent, location and rule id is mentioned, I also wanted to know on the slack dashboard if we can add more fields to understand the logs such as targetUserName,targetip,event id.


wazuslackalerts.png

Juan Manuel Segura Duarte

unread,
Aug 13, 2024, 7:16:20 AM8/13/24
to Wazuh | Mailing List
Hello again abhi,

Yes, using the `<options>` field in the integration is possible to do so. You can set a JSON object with customization fields using the options tag. Visit the Slack API reference for information about available customization fields.

Regards,
Juan Manuel

abhi

unread,
Aug 13, 2024, 11:42:06 PM8/13/24
to Wazuh | Mailing List
Hi Juan, 

I just want to know on which configuration file i need to do the changes in order to take achieve it.

Juan Manuel Segura Duarte

unread,
Aug 14, 2024, 4:34:35 AM8/14/24
to Wazuh | Mailing List
Hello again abhi,

The changes have to be made in the manager configuration file (`/var/ossec/etc/ossec.conf`), specifically in the `<integration>` section you added. For example the `<integration>` section could look like this:
```
<integration>
  <name>slack</name>
  <hook_url>HOOK_URL</hook_url> <!-- Replace with your Slack hook URL -->
  <level>10</level>
  <alert_format>json</alert_format>
  <options>{"pretext": "Custom Title"}</options> <!-- Replace with your custom JSON object --> 
</integration>
```

Regards,
Juan Manuel

abhi

unread,
Aug 14, 2024, 4:54:46 AM8/14/24
to Wazuh | Mailing List
Okay thanks!

abhi

unread,
Aug 14, 2024, 5:25:04 AM8/14/24
to Wazuh | Mailing List
Hi Juan,

I'm sharing below the syntax , is this correct?


<level>10</level>
<alert_format>json</alert_format>
<options>
    {
      "pretext": "Wazuh Alerts",
      "fields": [
        {"title": "Target User", "value": "{targetUserName}", "short": true},
        {"title": "Location", "value": "{location}", "short": true},
        {"title": "Rule ID", "value": "{rule[id]}", "short": true}
      ]
    }
  </options>
</integration>

abhi

unread,
Aug 14, 2024, 5:51:27 AM8/14/24
to Wazuh | Mailing List
I have tested it out but im not able to get the results as desired, instead its only displaying targetusername and not the value of username

PFA
1111.png

abhi

unread,
Aug 18, 2024, 11:57:24 PM8/18/24
to Wazuh | Mailing List
Hi Juan,

Can you kindly provide any solution to the above mentioned issue

Juan Manuel Segura Duarte

unread,
Aug 19, 2024, 6:49:27 AM8/19/24
to Wazuh | Mailing List
Hello again abhi,

After investigating the issue I have reached the conclusion that it's not possible to use variable values without modifying the Python integration script. After attempting in multiple ways of using the different string substitution methods that Python has to offer, no satisfactory results were obtained. Here is the function that parses the options set in the configuration:
```
def get_json_options(file_location: str) -> any:
    """Read JSON options object from file

    Parameters
    ----------
    file_location : str
        Path to the JSON file location.

    Returns
    -------
    dict: any
        The JSON object read it.

    Raises
    ------
    JSONDecodeError
        If no valid JSON file are used
    """
    try:
        with open(file_location) as options_file:
            return json.load(options_file)
    except FileNotFoundError:
        debug("# JSON file for options %s doesn't exist" % file_location)
    except BaseException as e:
        debug('Failed getting JSON options. Error: %s' % e)
        sys.exit(ERR_INVALID_JSON)
```

An example of a failed attempt at leveraging python f-string for achieving the desired functionality:
```
{'fields': [{'title': 'Location', 'value': 'f"{location}"', 'short': True}]}
```

Having said this, this functionality can be achieved by modifying the Python integration script for Slack (`/var/ossec/integrations/slack.py`) and modifying the function to replace those placeholders that are variables. One way of achieving this is by using the `eval` function in order to interpret the string "f"{location}"" as a string with an f-string inside which should be replaced accordingly. 
WARNING: Using eval() can be risky if the content being evaluated comes from an untrusted source. It executes the content as code, so if the content is not controlled, it can lead to security vulnerabilities. This allows for code injection since the `eval` function can't know if the code is malicious or not.

That's just one of the many ways this can be achieved. Another way could be to define your own format for variables (so that they can be distinguished from actual strings) and process the object containing the options once is read in the script.
For example, you could use this format for variables: ${variable}.
[
    {"title": "Fixed value", "value": "test"},
    {"title": "Rule ID", "value": "${alert['rule']['id']}"}
]

Here is one way of integrating a function for parsing this format:
```
def preprocess_json(data):
    """Replace placeholders in the JSON data with environment variable values.

    Parameters
    ----------
    data : dict or list
        The JSON data to preprocess.

    Returns
    -------
    dict or list
        The JSON data with placeholders replaced.
    """
    if isinstance(data, dict):
        return {k: preprocess_json(v) for k, v in data.items()}
    elif isinstance(data, list):
        return [preprocess_json(v) for v in data]
    elif isinstance(data, str):
        # Replace placeholders in the form of ${PLACEHOLDER}
        return os.path.expandvars(data)
    else:
        return data


def get_json_options(file_location: str) -> any:
    """Read JSON options object from file and preprocess it.

    Parameters
    ----------
    file_location : str
        Path to the JSON file location.

    Returns
    -------
    dict
        The JSON object with placeholders replaced.

    Raises
    ------
    JSONDecodeError
        If no valid JSON file is used
    """
    try:
        with open(file_location) as options_file:
            data = json.load(options_file)

        # Preprocess the JSON data to replace placeholders
        data = preprocess_json(data)

        return data
    except FileNotFoundError:
        debug("# JSON file for options %s doesn't exist" % file_location)
    except BaseException as e:
        debug("Failed getting JSON options. Error: %s" % e)
        sys.exit(ERR_INVALID_JSON)
```


We hope you find this information useful.
Regards,
Juan Manuel
Reply all
Reply to author
Forward
0 new messages