From 4b85a34b34060e18e495e6010b08fb9d52885894 Mon Sep 17 00:00:00 2001 From: Michael H Date: Sat, 6 Oct 2018 20:08:20 -0500 Subject: [PATCH 1/6] Added CSV option to powershell backend --- tools/sigma/backends/powershell.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/sigma/backends/powershell.py b/tools/sigma/backends/powershell.py index 7bb07d229..e1f39d53b 100644 --- a/tools/sigma/backends/powershell.py +++ b/tools/sigma/backends/powershell.py @@ -23,6 +23,9 @@ class PowerShellBackend(SingleTextQueryBackend): """Converts Sigma rule into PowerShell event log cmdlets.""" identifier = "powershell" active = True + options = ( + ("csv", False, "Return the results in CSV format instead of Powershell objects", None), + ) reEscape = re.compile('("|\\\\(?![*?])|\+)') reClear = None @@ -72,6 +75,8 @@ class PowerShellBackend(SingleTextQueryBackend): return "Get-WinEvent | where {" def generateAfter(self, parsed): + if self.csv: + return " | ConvertTo-CSV -NoTypeInformation" return "" def generateNode(self, node): From bbb67fbba43421b7ae78c68012d6f30d073db89a Mon Sep 17 00:00:00 2001 From: Michael H Date: Sun, 7 Oct 2018 10:11:47 -0500 Subject: [PATCH 2/6] Adding support for reading sigma rule from stdin in sigmac --- tools/sigmac | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/sigmac b/tools/sigmac index 911504b78..0d8e0a02d 100755 --- a/tools/sigmac +++ b/tools/sigmac @@ -54,6 +54,9 @@ def alliter(path): yield sub def get_inputs(paths, recursive): + if paths == ['-']: + return [sys.stdin] + if recursive: return list(itertools.chain.from_iterable([list(alliter(pathlib.Path(p))) for p in paths])) else: @@ -91,7 +94,7 @@ argparser.add_argument("--defer-abort", "-d", action="store_true", help="Don't a argparser.add_argument("--ignore-backend-errors", "-I", action="store_true", help="Only return error codes for parse errors and ignore errors for rules that cause backend errors. Useful, when you want to get as much queries as possible.") argparser.add_argument("--verbose", "-v", action="store_true", help="Be verbose") argparser.add_argument("--debug", "-D", action="store_true", help="Debugging output") -argparser.add_argument("inputs", nargs="*", help="Sigma input files") +argparser.add_argument("inputs", nargs="*", help="Sigma input files ('-' for stdin)") cmdargs = argparser.parse_args() if cmdargs.debug: @@ -146,7 +149,10 @@ error = 0 for sigmafile in get_inputs(cmdargs.inputs, cmdargs.recurse): print_verbose("* Processing Sigma input %s" % (sigmafile)) try: - f = sigmafile.open(encoding='utf-8') + if cmdargs.inputs == ['-']: + f = sigmafile + else: + f = sigmafile.open(encoding='utf-8') parser = SigmaCollectionParser(f, sigmaconfig, rulefilter) results = parser.generate(backend) for result in results: From 7e184f01c607d214f674b85a46404a2bbd28ce3b Mon Sep 17 00:00:00 2001 From: Michael H Date: Sat, 13 Oct 2018 19:53:39 -0500 Subject: [PATCH 3/6] Removing invalid fieldmapping --- tools/config/powershell-windows-all.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/config/powershell-windows-all.yml b/tools/config/powershell-windows-all.yml index b0b4f04de..8464ade07 100644 --- a/tools/config/powershell-windows-all.yml +++ b/tools/config/powershell-windows-all.yml @@ -60,7 +60,3 @@ logsources: service: ntlm conditions: LogName: 'Microsoft-Windows-NTLM/Operational' -fieldmappings: - EventID: ID - AccountName: Name - AuthenticationPackageName: Authentifizierungspaket From 9f48265eb149315470b1c6acb9faea1bc12aa794 Mon Sep 17 00:00:00 2001 From: Michael H Date: Sat, 13 Oct 2018 20:09:54 -0500 Subject: [PATCH 4/6] Adding re.sub for LogName that accounts for expression grouping --- tools/sigma/backends/powershell.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/sigma/backends/powershell.py b/tools/sigma/backends/powershell.py index 783ee8ac1..61a947e3c 100644 --- a/tools/sigma/backends/powershell.py +++ b/tools/sigma/backends/powershell.py @@ -68,7 +68,11 @@ class PowerShellBackend(SingleTextQueryBackend): Search for "| where { $_.LogName -eq "Security" -and" and replace with "-LogName "Security" | where { ... """ + # First attempt result = re.sub("\| where {\$_\.LogName -eq \"(.*?)\" -and ","-LogName \"\g<1>\" | where { ",result) + + # Second attempt (accounts for sub-expression) + result = re.sub("\| where {\(\$_\.LogName -eq \"(.*?)\" -and ","-LogName \"\g<1>\" | where {(",result) return result def generateBefore(self, parsed): From 38ec257f7e82690fce68b301220ffdfaf7afecb9 Mon Sep 17 00:00:00 2001 From: Michael H Date: Sat, 13 Oct 2018 20:18:57 -0500 Subject: [PATCH 5/6] Re-doing LogName formatting --- tools/sigma/backends/powershell.py | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/tools/sigma/backends/powershell.py b/tools/sigma/backends/powershell.py index 61a947e3c..99fa0db6d 100644 --- a/tools/sigma/backends/powershell.py +++ b/tools/sigma/backends/powershell.py @@ -41,6 +41,8 @@ class PowerShellBackend(SingleTextQueryBackend): mapExpression = "$_.%s -eq %s" mapListsSpecialHandling = True + logname = None + def generate(self, sigmaparser): """Method is called for each sigma rule and receives the parsed rule (SigmaParser)""" for parsed in sigmaparser.condparsed: @@ -56,26 +58,12 @@ class PowerShellBackend(SingleTextQueryBackend): result += query if after is not None: result += after - - # TODO fix dirty hack for logname due to performance impact when using the default query - """ - Convert From - PS> Get-WinEvent | where { $_.LogName -eq "Security" -and ($_.ID -eq "4624" .. - - into the following - PS> Get-WinEvent -LogName "Security" | where { ($_.ID -eq "4624" ... - - Search for "| where { $_.LogName -eq "Security" -and" and replace with "-LogName "Security" | where { ... - - """ - # First attempt - result = re.sub("\| where {\$_\.LogName -eq \"(.*?)\" -and ","-LogName \"\g<1>\" | where { ",result) - - # Second attempt (accounts for sub-expression) - result = re.sub("\| where {\(\$_\.LogName -eq \"(.*?)\" -and ","-LogName \"\g<1>\" | where {(",result) + return result def generateBefore(self, parsed): + if self.logname: + return "Get-WinEvent -LogName {} | where {".format(self.logname) return "Get-WinEvent | where {" def generateAfter(self, parsed): @@ -121,9 +109,7 @@ class PowerShellBackend(SingleTextQueryBackend): key, value = node if self.mapListsSpecialHandling == False and type(value) in (str, int, list) or self.mapListsSpecialHandling == True and type(value) in (str, int): if key in ("LogName","source"): - if key == "source": - key = "LogName" - return self.mapExpression % (key, self.generateValueNode(value, True)) + self.logname = value elif key in ("ID", "EventID"): if key == "EventID": key = "ID" From 5b33713ef8696156024ac41401ec1a011e35fb3f Mon Sep 17 00:00:00 2001 From: Michael H Date: Sat, 13 Oct 2018 20:21:37 -0500 Subject: [PATCH 6/6] Quick fix for string formatting bug --- tools/sigma/backends/powershell.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/sigma/backends/powershell.py b/tools/sigma/backends/powershell.py index 99fa0db6d..28333dbab 100644 --- a/tools/sigma/backends/powershell.py +++ b/tools/sigma/backends/powershell.py @@ -58,12 +58,12 @@ class PowerShellBackend(SingleTextQueryBackend): result += query if after is not None: result += after - + return result def generateBefore(self, parsed): if self.logname: - return "Get-WinEvent -LogName {} | where {".format(self.logname) + return "Get-WinEvent -LogName %s | where {" % self.logname return "Get-WinEvent | where {" def generateAfter(self, parsed):