Skip to content

Commit

Permalink
Updating the IRIS alerter for scenarios where fields are requested fr…
Browse files Browse the repository at this point in the history
…om nested JSON. See discussions #1348
  • Loading branch information
malinkinsa committed Jan 8, 2024
1 parent 436d338 commit 9239593
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 1 deletion.
17 changes: 16 additions & 1 deletion elastalert/alerters/iris.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,28 @@ def __init__(self, rule):
self.alert_context = self.rule.get('iris_alert_context', None)
self.iocs = self.rule.get('iris_iocs', None)

def lookup_field(self, match: dict, field_name: str, default):
"""Populates a field with values depending on the contents of the Elastalert match
provided to it.
Uses a similar algorithm to that implemented to populate the `alert_text_args`.
First checks any fields found in the match provided, then any fields defined in
the rule, finally returning the default value provided if no value can be found.
"""
field_value = lookup_es_key(match, field_name)
if field_value is None:
field_value = self.rule.get(field_name, default)

return field_value

def make_alert_context_records(self, matches):
alert_context = {}

for key, value in self.alert_context.items():
data = str(self.lookup_field(matches[0], value, ''))
alert_context.update(
{
key: matches[0].get(value)
key: data
}
)

Expand Down
80 changes: 80 additions & 0 deletions tests/alerters/iris_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,86 @@ def test_iris_make_alert_maximal(caplog):
assert expected_data == actual_data


def test_iris_make_alert_maximal_with_nested_json(caplog):
caplog.set_level(logging.INFO)
rule = {
'name': 'Test Maximal Alert Body',
'type': 'any',
'iris_host': '127.0.0.1',
'iris_api_token': 'token 12345',
'iris_customer_id': 1,
'iris_description': 'test description in alert',
'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': 'host.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': 'host.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', 'host': {'src_ip': '172.20.1.1'}, 'dst_ip': '10.0.0.1',
'event_type': 'login', 'event_status': 'success'
}

expected_data = {
"alert_title": 'Test Maximal Alert Body',
"alert_description": 'test description in alert',
"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_case_minimal(caplog):
caplog.set_level(logging.INFO)
rule = {
Expand Down

0 comments on commit 9239593

Please sign in to comment.