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 diff --git a/tools/sigma/backends/powershell.py b/tools/sigma/backends/powershell.py index a5dd7a3f5..28333dbab 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 @@ -38,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: @@ -54,24 +59,16 @@ class PowerShellBackend(SingleTextQueryBackend): 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 { ... - - """ - 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 %s | where {" % self.logname return "Get-WinEvent | where {" def generateAfter(self, parsed): + if self.csv: + return " | ConvertTo-CSV -NoTypeInformation" return "" def generateNode(self, node): @@ -112,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" 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: