Skip to content

Commit

Permalink
Merge pull request #1532 from bvirgilioamnh/iris-alert-updated-defaults
Browse files Browse the repository at this point in the history
Updating IRIS Alerter to use ElastAlert Alerter defaults
  • Loading branch information
jertel committed Sep 17, 2024
2 parents ca54fee + 9486200 commit 928746b
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Breaking changes
- Drop python3.9, python3.10, python3.11 from `python_requires` - [#1528](https://github.com/jertel/elastalert2/pull/1528) - @kmurphy4
- [IRIS] Updated alert_title to leverage ElastAlert built-in ``create_title`` function. Updated alert_description to use ElastAlert2 built-in function ``create_alert_body`` if alert_description is not set within the rule - [#1532](https://github.com/jertel/elastalert2/pull/1532) - @bvirgilioamnh

## New features
- [MS Power Automate] New Alert Channel with Microsoft Power Automate - [#1505](https://github.com/jertel/elastalert2/pull/1505) [#1513](https://github.com/jertel/elastalert2/pull/1513) [#1519](https://github.com/jertel/elastalert2/pull/1519) - @marssilva, @jertel
Expand Down
2 changes: 1 addition & 1 deletion docs/source/alerts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1191,7 +1191,7 @@ Optional:

``iris_ignore_ssl_errors``: Ignore ssl error. The default value is: ``False``.

``iris_description``: Description of the alert or case.
``iris_description``: Description of the alert or case. If left blank and ``iris_type`` is ``alert`` (default value) description will automatically be generated utilizing the ``alert_text``, and optionally ``alert_text_args``/``alert_text_type``, field(s) to generate a description.

``iris_overwrite_timestamp``: Should the timestamp be overridden when creating an alert. By default, the alert's creation time will be the trigger time. If you want to use the event's timestamp as the ticket creation time, set this value to ``True``. Default value is ``False``.

Expand Down
6 changes: 5 additions & 1 deletion elastalert/alerters/iris.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,12 @@ def make_alert(self, matches):
else:
event_timestamp = datetime.now().strftime("%Y-%m-%dT%H:%M:%S")

# If no description is supplied use the built-in alert body generator which accounts for alert_text and alert_text_args
if not self.description:
self.description = self.create_alert_body(matches)

alert_data = {
"alert_title": self.rule.get('name'),
"alert_title": self.create_title(matches),
"alert_description": self.description,
"alert_source": self.alert_source,
"alert_severity_id": self.alert_severity_id,
Expand Down
182 changes: 181 additions & 1 deletion tests/alerters/iris_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ def test_iris_make_alert_minimal(caplog):

expected_data = {
"alert_title": 'Test Minimal Alert Body',
"alert_description": None,
"alert_description": "Test Minimal Alert Body\n\n@timestamp: 2023-10-21 20:00:00.000\ndst_ip: 10.0.0.1\n\
event_status: success\nevent_type: login\nsrc_ip: 172.20.1.1\nusername: evil_user\n",
"alert_source": "ElastAlert2",
"alert_severity_id": 1,
"alert_status_id": 2,
Expand Down Expand Up @@ -223,6 +224,185 @@ def test_iris_make_alert_maximal(caplog):
assert expected_data == actual_data


def test_iris_make_alert_auto_description(caplog):
"""Test for the built-in elastalert2 create_title and create_body functions
These functions use the alert_subject and alert_text fields to automatically
build the title and description based on alert match data if available.
"""

caplog.set_level(logging.INFO)
rule = {
'name': 'Test Maximal Alert Body',
'alert_subject': 'Test Alert Subject',
'alert_text': 'Test alert text',
'type': 'any',
'iris_host': '127.0.0.1',
'iris_api_token': 'token 12345',
'iris_customer_id': 1,
'iris_alert_note': 'test note',
'iris_alert_tags': 'test, alert',
'iris_overwrite_timestamp': True,
'iris_alert_source_link': 'https://example.com',
'iris_iocs': [
{
'ioc_description': 'source address',
'ioc_tags': 'ip, ipv4',
'ioc_tlp_id': 1,
'ioc_type_id': 76,
'ioc_value': 'src_ip'
},
{
'ioc_description': 'target username',
'ioc_tags': 'login, username',
'ioc_tlp_id': 3,
'ioc_type_id': 3,
'ioc_value': 'username'
}
],
'iris_alert_context': {'username': 'username', 'ip': 'src_ip', 'login_status': 'event_status'},
'alert': [],
}

rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = IrisAlerter(rule)

match = {
'@timestamp': '2023-10-21 20:00:00.000', 'username': 'evil_user', 'src_ip': '172.20.1.1', 'dst_ip': '10.0.0.1',
'event_type': 'login', 'event_status': 'success'
}

expected_data = {
"alert_title": 'Test Alert Subject',
"alert_description": 'Test alert text\n\n@timestamp: 2023-10-21 20:00:00.000\ndst_ip: 10.0.0.1\n\
event_status: success\nevent_type: login\nsrc_ip: 172.20.1.1\nusername: evil_user\n',
"alert_source": "ElastAlert2",
"alert_severity_id": 1,
"alert_status_id": 2,
"alert_source_event_time": '2023-10-21 20:00:00.000',
"alert_note": 'test note',
"alert_tags": 'test, alert',
"alert_customer_id": 1,
"alert_source_link": 'https://example.com',
"alert_iocs": [
{
'ioc_description': 'source address',
'ioc_tags': 'ip, ipv4',
'ioc_tlp_id': 1,
'ioc_type_id': 76,
'ioc_value': '172.20.1.1'
},
{
'ioc_description': 'target username',
'ioc_tags': 'login, username',
'ioc_tlp_id': 3,
'ioc_type_id': 3,
'ioc_value': 'evil_user'
}
],
"alert_context": {
'username': 'evil_user',
'ip': '172.20.1.1',
'login_status': 'success'
},
}

actual_data = alert.make_alert([match])
assert expected_data == actual_data


def test_iris_make_alert_auto_description_args(caplog):
"""Test for the built-in elastalert2 create_title and create_body functions
These functions use the alert_subject and alert_text fields to automatically
build the title and description based on alert match data if available.
This test specifically uses _args for the alert_text to ensure match args
are passed through properly.
"""
caplog.set_level(logging.INFO)
rule = {
'name': 'Test Maximal Alert Body',
'alert_subject': 'Test Alert Subject',
'alert_text': 'Username: {0} from {1}',
'alert_text_type': 'alert_text_only',
'alert_text_args': ['username', 'src_ip'],
'type': 'any',
'iris_host': '127.0.0.1',
'iris_api_token': 'token 12345',
'iris_customer_id': 1,
'iris_alert_note': 'test note',
'iris_alert_tags': 'test, alert',
'iris_overwrite_timestamp': True,
'iris_alert_source_link': 'https://example.com',
'iris_iocs': [
{
'ioc_description': 'source address',
'ioc_tags': 'ip, ipv4',
'ioc_tlp_id': 1,
'ioc_type_id': 76,
'ioc_value': 'src_ip'
},
{
'ioc_description': 'target username',
'ioc_tags': 'login, username',
'ioc_tlp_id': 3,
'ioc_type_id': 3,
'ioc_value': 'username'
}
],
'iris_alert_context': {'username': 'username', 'ip': 'src_ip', 'login_status': 'event_status'},
'alert': [],
}

rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = IrisAlerter(rule)

match = {
'@timestamp': '2023-10-21 20:00:00.000', 'username': 'evil_user', 'src_ip': '172.20.1.1', 'dst_ip': '10.0.0.1',
'event_type': 'login', 'event_status': 'success'
}

expected_data = {
"alert_title": 'Test Alert Subject',
"alert_description": 'Username: evil_user from 172.20.1.1\n\n',
"alert_source": "ElastAlert2",
"alert_severity_id": 1,
"alert_status_id": 2,
"alert_source_event_time": '2023-10-21 20:00:00.000',
"alert_note": 'test note',
"alert_tags": 'test, alert',
"alert_customer_id": 1,
"alert_source_link": 'https://example.com',
"alert_iocs": [
{
'ioc_description': 'source address',
'ioc_tags': 'ip, ipv4',
'ioc_tlp_id': 1,
'ioc_type_id': 76,
'ioc_value': '172.20.1.1'
},
{
'ioc_description': 'target username',
'ioc_tags': 'login, username',
'ioc_tlp_id': 3,
'ioc_type_id': 3,
'ioc_value': 'evil_user'
}
],
"alert_context": {
'username': 'evil_user',
'ip': '172.20.1.1',
'login_status': 'success'
},
}

actual_data = alert.make_alert([match])
assert expected_data == actual_data


def test_iris_make_alert_maximal_with_nested_json(caplog):
caplog.set_level(logging.INFO)
rule = {
Expand Down

0 comments on commit 928746b

Please sign in to comment.