jertel / elastalert2

ElastAlert 2 is a continuation of the original yelp/elastalert project. Pull requests are appreciated!
https://elastalert2.readthedocs.org
Apache License 2.0
914 stars 287 forks source link

Error generating alerts on Iris | 'NoneType' object has no attribute 'removesuffix' #1457

Closed rober-fuji closed 2 weeks ago

rober-fuji commented 4 months ago

Good morning,

An attempt has been made to run elastalert on Docker, version 2.2, with the following file:

es_host: ***************
es_port: *******
alert:
- debug
description: Test Rule
filter:
- query_string:
    query: (data.office365.Workload:AzureActiveDirectory AND data.office365.Operation:UserLoginFailed AND data.offic>
index: *******
name: Test Alert
priority: 3
realert:
  minutes: 0
type: any
alert:
- "iris"

iris_host: ***************
iris_api_token: *********************************************
iris_customer_id: 2
iris_description: 'Test alert from ElastAlert2'
iris_alert_note: 'Alert triggered by opened session'
iris_alert_tags: 'test, login, ssh'
#iris_alert_context:
#  username: data.office365.UserId
#  ip: data.office365.ClientIP
iris_iocs:

  - ioc_value: data.office365.ClientIP
    ioc_description: source ip address
    ioc_tlp_id: 1
    ioc_type_id: 79
    ioc_tags: ip-src

The first alert pops up in Iris, including its IoCs and everything is correct, but when the second alert pops up, it appears without IoCs and the following exception pops up

elastalert_error - {'message': "Uncaught exception running rule Test Alert: 'NoneType' object has no attribute 'remov                                                                                                                        esuffix'", 'traceback': ['Traceback (most recent call last):', '  File "/usr/local/lib/python3.12/site-packages/elast                                                                                                                        alert/elastalert.py", line 1324, in alert', '    return self.send_alert(matches, rule, alert_time=alert_time, retried                                                                                                                        =retried)', '           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/                                                                                                                        lib/python3.12/site-packages/elastalert/elastalert.py", line 1409, in send_alert', '    alert.alert(matches)', '  Fil                                                                                                                        e "/usr/local/lib/python3.12/site-packages/elastalert/alerters/iris.py", line 138, in alert', '    alert_data = self.                                                                                                                        make_alert(matches)', '                 ^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/e                                                                                                                        lastalert/alerters/iris.py", line 96, in make_alert', '    iocs = self.make_iocs_records(matches)', '           ^^^^^                                                                                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/elastalert/alerters/iris.py", line 67,                                                                                                                         in make_iocs_records', "    record['ioc_value'] = lookup_es_key(matches[0], record['ioc_value'])", '                                                                                                                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/elastalert                                                                                                                        /util.py", line 165, in lookup_es_key', '    value_dict, value_key = _find_es_dict_by_key(lookup_dict, term)', '                                                                                                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/ela                                                                                                                        stalert/util.py", line 88, in _find_es_dict_by_key', '    term = term.removesuffix(string_multi_field_name)', '                                                                                                                                   ^^^^^^^^^^^^^^^^^', "AttributeError: 'NoneType' object has no attribute 'removesuffix'"], 'data': {'rule': 'Test                                                                                                                         Alert'}}

elastalert_error - {'message': "Uncaught exception running rule Test Alert: 'NoneType' object has no attribute 'remov                                                                                                                        esuffix'", 'traceback': ['Traceback (most recent call last):', '  File "/usr/local/lib/python3.12/site-packages/elast                                                                                                                        alert/elastalert.py", line 1324, in alert', '    return self.send_alert(matches, rule, alert_time=alert_time, retried                                                                                                                        =retried)', '           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/                                                                                                                        lib/python3.12/site-packages/elastalert/elastalert.py", line 1409, in send_alert', '    alert.alert(matches)', '  Fil                                                                                                                        e "/usr/local/lib/python3.12/site-packages/elastalert/alerters/iris.py", line 138, in alert', '    alert_data = self.                                                                                                                        make_alert(matches)', '                 ^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/e                                                                                                                        lastalert/alerters/iris.py", line 96, in make_alert', '    iocs = self.make_iocs_records(matches)', '           ^^^^^                                                                                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/elastalert/alerters/iris.py", line 67,                                                                                                                         in make_iocs_records', "    record['ioc_value'] = lookup_es_key(matches[0], record['ioc_value'])", '                                                                                                                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/elastalert                                                                                                                        /util.py", line 165, in lookup_es_key', '    value_dict, value_key = _find_es_dict_by_key(lookup_dict, term)', '                                                                                                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/ela                                                                                                                        stalert/util.py", line 88, in _find_es_dict_by_key', '    term = term.removesuffix(string_multi_field_name)', '                                                                                                                                   ^^^^^^^^^^^^^^^^^', "AttributeError: 'NoneType' object has no attribute 'removesuffix'"], 'data': {'rule': 'Test                                                                                                                         Alert'}}

elastalert_error - {'message': "Uncaught exception running rule Test Alert: 'NoneType' object has no attribute 'remov                                                                                                                        esuffix'", 'traceback': ['Traceback (most recent call last):', '  File "/usr/local/lib/python3.12/site-packages/elast                                                                                                                        alert/elastalert.py", line 1324, in alert', '    return self.send_alert(matches, rule, alert_time=alert_time, retried                                                                                                                        =retried)', '           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/                                                                                                                        lib/python3.12/site-packages/elastalert/elastalert.py", line 1409, in send_alert', '    alert.alert(matches)', '  Fil                                                                                                                        e "/usr/local/lib/python3.12/site-packages/elastalert/alerters/iris.py", line 138, in alert', '    alert_data = self.                                                                                                                        make_alert(matches)', '                 ^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/e                                                                                                                        lastalert/alerters/iris.py", line 96, in make_alert', '    iocs = self.make_iocs_records(matches)', '           ^^^^^                                                                                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/elastalert/alerters/iris.py", line 67,                                                                                                                         in make_iocs_records', "    record['ioc_value'] = lookup_es_key(matches[0], record['ioc_value'])", '                                                                                                                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/elastalert                                                                                                                        /util.py", line 165, in lookup_es_key', '    value_dict, value_key = _find_es_dict_by_key(lookup_dict, term)', '                                                                                                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', '  File "/usr/local/lib/python3.12/site-packages/ela                                                                                                                        stalert/util.py", line 88, in _find_es_dict_by_key', '    term = term.removesuffix(string_multi_field_name)', '                                                                                                                                   ^^^^^^^^^^^^^^^^^', "AttributeError: 'NoneType' object has no attribute 'removesuffix'"], 'data': {'rule': 'Test                                                                                                                         Alert'}}

In this example there is only one match and no error occurs, the alert is generated correctly.

es_host: *********************************************
es_port: *********************************************
alert:
- debug
description: Test Rule 2
filter:
- query_string:
    query: (data.type:utm AND data.subtype:ips AND data.severity:medium)
index: *********************************************
name: Test Alert
priority: 3
realert:
  minutes: 0
type: any
alert:
- "iris"

iris_host: *********************************************
iris_api_token: *********************************************
iris_customer_id: 2
iris_description: 'Test alert from ElastAlert2'
iris_alert_note: 'Alert triggered by opened session'
iris_alert_tags: 'test, login, ssh'
iris_iocs:

  - ioc_value: data.srcip
    ioc_description: source ip address
    ioc_tlp_id: 1
    ioc_type_id: 79
    ioc_tags: ip-src

In this example there is more than one hit and the same error is generated.

es_host: *********************************************
es_port: *********************************************
alert:
- debug
description: Test Rule 3
filter:
- query_string:
    query: (data.type:utm AND data.subtype:ips AND data.severity:critical)
index: *********************************************
name: Test Alert
priority: 3
realert:
  minutes: 0
type: any
alert:
- "iris"

iris_host: *********************************************
iris_api_token: *********************************************
iris_customer_id: 2
iris_description: 'Test alert from ElastAlert2'
iris_alert_note: 'Alert triggered by opened session'
iris_alert_tags: 'test, login, ssh'
iris_iocs:

  - ioc_value: data.srcip
    ioc_description: source ip address
    ioc_tlp_id: 1
    ioc_type_id: 79
    ioc_tags: ip-src

This happens when the following command is used: elastalert-test-alert name-of-file.yaml --alert

jertel commented 4 months ago

Thanks for reporting this @rober-fuji. I reviewed the IRIS alerter and see a problem.

@malinkinsa, in the IRIS PR you submitted last year, there's a bug where the IOC fetcher loop is overwriting the rule configuration, causing subsequent alerts to throw errors and fail to alert. Specifically, this line:

https://github.com/jertel/elastalert2/blob/23aab845c421411b1cc07f27b61659a0a78c831c/elastalert/alerters/iris.py#L67

is fetching a value from the matched document, and then storing that looked up value over the top of the original lookup key.

Given this config:

iris_iocs:
  - ioc_value: data.srcip
     ...

If that fetched value wasn't found in the document then a None is returned, and now the rule configuration looks like this:

iris_iocs:
  - ioc_value: 
    ...

Notice how ioc_value no longer has a lookup key. Now all subsequent IRIS alerts will fail since ElastAlert 2 currently does not allow None (aka null) lookup terms.

I think the code should be using a deep clone of the IOC object and modifying/appending that, rather than using the original rule config.

CC: @gregorywychowaniec-zt, since you recently made a change in this area and may have some input or time to help prepare a fix.

malinkinsa commented 3 months ago

Unfortunately, I haven't watched it yet. I'll try to look closer to the middle of the month :(

jertel commented 3 months ago

Unfortunately, I haven't watched it yet. I'll try to look closer to the middle of the month :(

Any update on this?

malinkinsa commented 3 months ago

Unfortunately, I still haven't had the time to address this issue. :(

gregorywychowaniec-zt commented 3 months ago

Same for me, I'm not on this topic at the moment. I will reopen this topic on my side in a few weeks, so if it was not fixed at that time, I will keep an eye on it.

gregorywychowaniec-zt commented 4 weeks ago

Hello, I will restart IRIS project soon so I will look for this issue in the next few weeks

jertel commented 2 weeks ago

Thanks you @bvirgilioamnh for taking the time to fix this issue, and for the several other IRIS alerter improvements. Your efforts are appreciated!