diff --git a/docs/query-guide/functions.rst b/docs/query-guide/functions.rst index c1b7f81..3b9ad08 100644 --- a/docs/query-guide/functions.rst +++ b/docs/query-guide/functions.rst @@ -123,6 +123,12 @@ math, string manipulation or more sophisticated expressions to be expressed. Returns the length of a string or array. +.. 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. @@ -156,6 +162,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``. @@ -168,6 +180,12 @@ math, string manipulation or more sophisticated expressions to be expressed. Returns true if ``b`` is a substring of ``a`` +.. function:: strip(s) + + :param: s: The string that will be stripped + + 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``. 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 bdfe27e..aa26512 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' @@ -1296,7 +1322,7 @@ case_insensitive = true query = ''' process where process_name == original_file_name and 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]] @@ -1304,7 +1330,7 @@ case_insensitive = true query = ''' process where original_file_name == process_name and 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]] @@ -1828,4 +1854,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 diff --git a/eql/functions.py b/eql/functions.py index 664c3a3..fc9030a 100644 --- a/eql/functions.py +++ b/eql/functions.py @@ -435,6 +435,26 @@ def run(cls, array): return len(array) +@register +class LeftStrip(FunctionSignature): + """Strip leading whitespace from a string.""" + + name = "lstrip" + argument_types = [TypeHint.String] + return_value = TypeHint.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): """Perform regular expression matching on a string.""" @@ -523,6 +543,26 @@ def run(cls, x, y): return x * y +@register +class RightStrip(FunctionSignature): + """Strip trailing whitespace from a string.""" + + name = "rstrip" + argument_types = [TypeHint.String] + return_value = TypeHint.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(DynamicFunctionSignature): """Evaluate an expression and suppress exceptions.""" @@ -563,6 +603,26 @@ def run(cls, source, substring): return False +@register +class Strip(FunctionSignature): + """Strip leading & trailing whitespace from a string.""" + + name = "strip" + argument_types = [TypeHint.String] + return_value = TypeHint.String + minimum_args = 1 + + @classmethod + def run(cls, source): + """Strip whitespace from source.""" + if not is_string(source): + return None + + stripped = source.strip() + + return stripped + + @register class Substring(FunctionSignature): """Extract a substring."""