From 196173f068139594ec8477eff4ab214ff82ef3e0 Mon Sep 17 00:00:00 2001 From: Gilman Date: Wed, 4 Sep 2019 15:41:12 -0400 Subject: [PATCH 1/7] Adding strip function to remove leading and trailing whitespace from strings --- docs/query-guide/functions.rst | 8 ++++++++ eql/functions.py | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/docs/query-guide/functions.rst b/docs/query-guide/functions.rst index 3903d4c..5cc43b2 100644 --- a/docs/query-guide/functions.rst +++ b/docs/query-guide/functions.rst @@ -102,6 +102,14 @@ math, string manipulation or more sophisticated expressions to be expressed. Returns true if ``b`` is a substring of ``a`` +.. function:: strip(s[, leading, trailing]) + + :param: s: The string that will be stripped + :param: leading: strip whitespace from the beginning of ``s``. Default is ``True``. + :param: trailing: strip whitespace from the end of ``s``. Default is ``True``. + + Returns a string with whitespace removed from the beginning and end of input string ``s``. + .. function:: subtract(x, y) Returns ``x - y`` diff --git a/eql/functions.py b/eql/functions.py index 6083fc9..0e0cc7a 100644 --- a/eql/functions.py +++ b/eql/functions.py @@ -319,6 +319,29 @@ def run(cls, source, substring): return substring.lower() in source.lower() return False +@register +class Strip(FunctionSignature): + """Strip leading & trailing whitespace from a string.""" + + name = "strip" + argument_types = [STRING, BOOLEAN, BOOLEAN] + return_value = STRING + minimum_args = 1 + + @classmethod + def run(cls, source, leading=True, trailing=True): + """Strip whitespace from source.""" + + if not is_string(source): + return None + + stripped = source + if leading: + stripped = stripped.lstrip() + if trailing: + stripped = stripped.rstrip() + + return stripped @register class Substring(FunctionSignature): From 2adb5a0f01498e7d2550b040a26edc234dda96fd Mon Sep 17 00:00:00 2001 From: ch200025 Date: Mon, 13 Jan 2020 08:57:39 -0500 Subject: [PATCH 2/7] Broke lstrip() and rstrip() out into separate functions per https://github.com/endgameinc/eql/pull/4#discussion_r328202485 --- eql/functions.py | 48 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/eql/functions.py b/eql/functions.py index 372e563..c4e32cd 100644 --- a/eql/functions.py +++ b/eql/functions.py @@ -439,6 +439,25 @@ def run(cls, array): return len(array) return 0 +@register +class LeftStrip(FunctionSignature): + """Strip leading whitespace from a string.""" + + name = "lstrip" + argument_types = [STRING] + return_value = STRING + minimum_args = 1 + + @classmethod + def run(cls, source): + """Strip whitespace from source.""" + + if not is_string(source): + return None + + stripped = source.lstrip() + + return stripped @register class Match(FunctionSignature): @@ -517,6 +536,25 @@ def run(cls, x, y): if is_number(x) and is_number(y): return x * y +@register +class RightStrip(FunctionSignature): + """Strip trailing whitespace from a string.""" + + name = "rstrip" + argument_types = [STRING] + return_value = STRING + minimum_args = 1 + + @classmethod + def run(cls, source): + """Strip whitespace from source.""" + + if not is_string(source): + return None + + stripped = source.rstrip() + + return stripped @register class Safe(FunctionSignature): @@ -562,22 +600,18 @@ class Strip(FunctionSignature): """Strip leading & trailing whitespace from a string.""" name = "strip" - argument_types = [STRING, BOOLEAN, BOOLEAN] + argument_types = [STRING] return_value = STRING minimum_args = 1 @classmethod - def run(cls, source, leading=True, trailing=True): + def run(cls, source): """Strip whitespace from source.""" if not is_string(source): return None - stripped = source - if leading: - stripped = stripped.lstrip() - if trailing: - stripped = stripped.rstrip() + stripped = source.strip() return stripped From 8bfc83776f287ba8787cdf4d88d504480c613ecc Mon Sep 17 00:00:00 2001 From: ch200025 Date: Mon, 13 Jan 2020 09:06:02 -0500 Subject: [PATCH 3/7] Fixed linter warnings in fuctions.py --- eql/functions.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/eql/functions.py b/eql/functions.py index c4e32cd..628d8cb 100644 --- a/eql/functions.py +++ b/eql/functions.py @@ -439,6 +439,7 @@ def run(cls, array): return len(array) return 0 + @register class LeftStrip(FunctionSignature): """Strip leading whitespace from a string.""" @@ -451,7 +452,6 @@ class LeftStrip(FunctionSignature): @classmethod def run(cls, source): """Strip whitespace from source.""" - if not is_string(source): return None @@ -459,6 +459,7 @@ def run(cls, source): return stripped + @register class Match(FunctionSignature): """Perform regular expression matching on a string.""" @@ -536,6 +537,7 @@ def run(cls, x, y): if is_number(x) and is_number(y): return x * y + @register class RightStrip(FunctionSignature): """Strip trailing whitespace from a string.""" @@ -548,7 +550,6 @@ class RightStrip(FunctionSignature): @classmethod def run(cls, source): """Strip whitespace from source.""" - if not is_string(source): return None @@ -556,6 +557,7 @@ def run(cls, source): return stripped + @register class Safe(FunctionSignature): """Evaluate an expression and suppress exceptions.""" @@ -595,10 +597,11 @@ def run(cls, source, substring): return substring.lower() in source.lower() return False + @register class Strip(FunctionSignature): """Strip leading & trailing whitespace from a string.""" - + name = "strip" argument_types = [STRING] return_value = STRING @@ -607,7 +610,6 @@ class Strip(FunctionSignature): @classmethod def run(cls, source): """Strip whitespace from source.""" - if not is_string(source): return None @@ -615,6 +617,7 @@ def run(cls, source): return stripped + @register class Substring(FunctionSignature): """Extract a substring.""" From eca2846bafd739ce56a5bd33c1a322dbd7153b75 Mon Sep 17 00:00:00 2001 From: ch200025 Date: Mon, 13 Jan 2020 09:27:24 -0500 Subject: [PATCH 4/7] Adding tests for strip(), lstrip(), and rstrip() --- eql/etc/test_data.json | 23 +++++++++++++++++++++++ eql/etc/test_queries.toml | 32 +++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/eql/etc/test_data.json b/eql/etc/test_data.json index 4a08e7f..75118c8 100644 --- a/eql/etc/test_data.json +++ b/eql/etc/test_data.json @@ -2076,5 +2076,28 @@ "unique_pid": 99999, "user_domain": "vagrant", "user_name": "vagrant" + }, + { + "authentication_id": 854482244, + "command_line": " C:\\Windows\\system32\\net group administrators \"findme2\" ", + "event_subtype_full": "creation_event", + "event_type": "process", + "event_type_full": "process_event", + "md5": "3b6928bc39e5530cead1e99269e7b1ee", + "opcode": 1, + "original_file_name": "net1.exe", + "parent_process_name": "net.exe", + "parent_process_path": "C:\\Windows\\System32\\net.exe", + "pid": 1392, + "ppid": 3608, + "process_name": "net1.exe", + "process_path": "C:\\Windows\\System32\\net1.exe", + "serial_event_id": 75306, + "subtype": "create", + "timestamp": 131605904083806370, + "unique_pid": 813840, + "unique_ppid": 750058, + "user_domain": "vagrant", + "user_name": "vagrant" } ] diff --git a/eql/etc/test_queries.toml b/eql/etc/test_queries.toml index e2ee95c..36230dd 100644 --- a/eql/etc/test_queries.toml +++ b/eql/etc/test_queries.toml @@ -18,6 +18,32 @@ expected_event_ids = [] expected_event_ids = [] query = 'process where missing_field != null' +[[queries]] +expected_event_ids = [3, 78, 80] +query = 'process where strip(process_name) == "smss.exe"' + +[[queries]] +expected_event_ids = [3, 78, 80] +query = 'process where lstrip(process_name) == "smss.exe"' + +[[queries]] +expected_event_ids = [3, 78, 80] +query = 'process where rstrip(process_name) == "smss.exe"' + +[[queries]] +expected_event_ids = [75306] +query = 'process where rstrip(command_line) == " C:\\Windows\\system32\\net group administrators \"findme2\""' + +[[queries]] +expected_event_ids = [75306] +query = 'process where strip(command_line) == "C:\\Windows\\system32\\net group administrators \"findme2\""' + +[[queries]] +expected_event_ids = [75306] +query = 'process where lstrip(command_line) == "C:\\Windows\\system32\\net group administrators \"findme2\" "' + + + [[queries]] expected_event_ids = [1, 2, 3, 4, 5] query = 'process where bad_field == null | head 5' @@ -882,7 +908,7 @@ query = ''' process where process_name == original_file_name | filter process_name='net*.exe' ''' -expected_event_ids = [97, 98] +expected_event_ids = [97, 98, 75306] note = "check that case insensitive comparisons are performed for fields." [[queries]] @@ -890,7 +916,7 @@ query = ''' process where original_file_name == process_name | filter length(original_file_name) > 0 ''' -expected_event_ids = [97, 98, 75273, 75303] +expected_event_ids = [97, 98, 75273, 75303, 75306] description = "check that case insensitive comparisons are performed for fields." [[queries]] @@ -1295,4 +1321,4 @@ process where length(between(process_name, 'g', 'e')) > 0 expected_event_ids = [] query = ''' process where length(between(process_name, 'g', 'z')) > 0 -''' +''' \ No newline at end of file From 77dd49a744c90524756b5318d371ac9f82a51144 Mon Sep 17 00:00:00 2001 From: ch200025 Date: Tue, 14 Jan 2020 09:55:30 -0500 Subject: [PATCH 5/7] Updated documentation to reflect strip, lstrip, and rstrip --- docs/query-guide/functions.rst | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/query-guide/functions.rst b/docs/query-guide/functions.rst index 2dd929f..bb5f675 100644 --- a/docs/query-guide/functions.rst +++ b/docs/query-guide/functions.rst @@ -120,6 +120,12 @@ math, string manipulation or more sophisticated expressions to be expressed. Returns the length of a string. Non-string values return 0. +.. function:: lstrip(s) + + :param: s: The string that will be stripped + + Returns a string with whitespace removed from the begining of input string ``s``. + .. function:: match(source, pattern [, ...]) Checks if multiple regular expressions are matched against a source string. @@ -153,6 +159,12 @@ math, string manipulation or more sophisticated expressions to be expressed. number("1337") // returns 1337 number("0xdeadbeef", 16) // 3735928559 +.. function:: rstrip(s) + + :param: s: The string that will be stripped + + Returns a string with whitespace removed from the end of input string ``s``. + .. function:: startsWith(x, y) Checks if the string ``x`` starts with the string ``y``. @@ -165,13 +177,12 @@ math, string manipulation or more sophisticated expressions to be expressed. Returns true if ``b`` is a substring of ``a`` -.. function:: strip(s[, leading, trailing]) +.. function:: strip(s) :param: s: The string that will be stripped - :param: leading: strip whitespace from the beginning of ``s``. Default is ``True``. - :param: trailing: strip whitespace from the end of ``s``. Default is ``True``. Returns a string with whitespace removed from the beginning and end of input string ``s``. + .. function:: substring(source [, start, end]) Extracts a substring between from another string between ``start`` and ``end``. From 22cf1b582dab1e1e4ea92e688ef0fb61446dfad4 Mon Sep 17 00:00:00 2001 From: Reid Gilman Date: Wed, 3 Feb 2021 10:35:33 -0500 Subject: [PATCH 6/7] final fix --- eql/functions.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/eql/functions.py b/eql/functions.py index b031c73..89ed3cb 100644 --- a/eql/functions.py +++ b/eql/functions.py @@ -440,8 +440,8 @@ class LeftStrip(FunctionSignature): """Strip leading whitespace from a string.""" name = "lstrip" - argument_types = [STRING] - return_value = STRING + argument_types = [TypeHint.String] + return_value = TypeHint.String minimum_args = 1 @classmethod @@ -548,8 +548,8 @@ class RightStrip(FunctionSignature): """Strip trailing whitespace from a string.""" name = "rstrip" - argument_types = [STRING] - return_value = STRING + argument_types = [TypeHint.String] + return_value = TypeHint.String minimum_args = 1 @classmethod @@ -608,8 +608,8 @@ class Strip(FunctionSignature): """Strip leading & trailing whitespace from a string.""" name = "strip" - argument_types = [STRING] - return_value = STRING + argument_types = [TypeHint.String] + return_value = TypeHint.String minimum_args = 1 @classmethod From 9d65fda3e313b58002bab0307b16ef458da58454 Mon Sep 17 00:00:00 2001 From: Reid Gilman <76319+reidgilman@users.noreply.github.com> Date: Wed, 3 Feb 2021 10:45:04 -0500 Subject: [PATCH 7/7] removed trailing whitespace --- eql/functions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eql/functions.py b/eql/functions.py index 89ed3cb..fc9030a 100644 --- a/eql/functions.py +++ b/eql/functions.py @@ -441,7 +441,7 @@ class LeftStrip(FunctionSignature): name = "lstrip" argument_types = [TypeHint.String] - return_value = TypeHint.String + return_value = TypeHint.String minimum_args = 1 @classmethod @@ -549,7 +549,7 @@ class RightStrip(FunctionSignature): name = "rstrip" argument_types = [TypeHint.String] - return_value = TypeHint.String + return_value = TypeHint.String minimum_args = 1 @classmethod @@ -609,7 +609,7 @@ class Strip(FunctionSignature): name = "strip" argument_types = [TypeHint.String] - return_value = TypeHint.String + return_value = TypeHint.String minimum_args = 1 @classmethod