Private/ConvertTo-PrivSigmaYaml.ps1
<#
.SYNOPSIS sigmadb - convert sigma rule from database to yaml (private function) .DESCRIPTION Private function for converting sigma rule from sigmadb to yaml with the custom exceptions .EXAMPLE PS C:\> ConvertTo-PrivSigmaYaml -Rule $rule -Database $db Converts the selected rule from the defined database to a yaml file .INPUTS Rule: DataRow from SQL query Database: SigmaDB class object .OUTPUTS YAML file .NOTES Author: ncrqnt Date: 08.09.2021 PowerShell: 7.1.4 Changelog: 1.1.0 22.09.2021 ncrqnt Removed file_path and replaced with Rules path in config file 1.0.1 16.09.2021 ncrqnt Removed support for multiple documents 1.0.0 08.09.2021 ncrqnt Initial creation #> #Requires -Module 'SimplySql' #Requires -Module 'powershell-yaml' function ConvertTo-PrivSigmaYaml { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.Data.DataRow]$Rule, [Parameter(Mandatory = $true)] [SigmaDB]$Database, [Parameter(Mandatory = $true)] [PSCustomObject]$Config ) begin { $db = $Database # check for db connection if (-not $db.Test()) { Write-Error -Message "No database connection found" return } } process { # Get exceptions $exceptions = $db.Query("SELECT * FROM exception WHERE rule_id = @id", @{ id = $Rule.id }) # Get file data $yaml = Get-Content "$($Config.Folders.Rules)\$($Rule.file_name)" -Raw -Encoding utf8 $dict = $yaml | ConvertFrom-Yaml -Ordered # Transform case if ($Config.CaseSensitivity.Enabled) { $selections = $dict.detection.Keys | Where-Object { $_ -notin ('condition', 'timeframe') } $type_orderedDict = [System.Collections.Specialized.OrderedDictionary] $type_genericList = [System.Collections.Generic.List`1[[System.Object, System.Private.CoreLib, Version = 5.0.0.0, Culture = neutral, PublicKeyToken = 7cec85d7bea7798e]]] foreach ($selection in $selections) { if ($null -ne $dict.detection.$selection.Keys) { $keys = $dict.detection.$selection.Keys.Clone() } if ($dict.detection.$selection -is $type_orderedDict) { # Selection is a ordered dictionary ('AND' / unique field names) foreach ($key in $keys) { $field = $key -replace '\|.*','' if ($Config.CaseSensitivity.AllFields -or ($field -in $Config.CaseSensitivity.Fields)) { if ($Config.CaseSensitivity.Mode -eq 'uppercase') { $newCase = $dict.detection.$selection.$key.ToUpper() } else { $newCase = $dict.detection.$selection.$key.ToLower() } $dict.detection.$selection.$key = $newCase } } } elseif ($dict.detection.$selection -is $type_genericList) { # Selection is a generic list ('OR' / duplicate field names possible) foreach ($item in $dict.detection.$selection) { $index = $dict.detection.$selection.IndexOf($item) if ($item -is $type_orderedDict) { $keys = $item.Keys.Clone() foreach ($key in $keys) { $field = $key -replace '\|.*','' if ($Config.CaseSensitivity.AllFields -or ($field -in $Config.CaseSensitivity.Fields)) { if ($Config.CaseSensitivity.Mode -eq 'uppercase') { $newCase = $dict.detection.$selection[$index].$key.ToUpper() } else { $newCase = $dict.detection.$selection[$index].$key.ToLower() } $dict.detection.$selection[$index].$key = $newCase } } } } } } <# if ($dict.detection.$selection.Count -gt 1) { # Array Write-Verbose $selection $index = $dict.detection.$selection.IndexOf($item) $newCase = $item[0].ToLower() $dict.detection.$selection[$index][0] = $newCase } else { # single item $newCase = $item[0].ToLower() $dict.detection.$selection[0] = $newCase } #> <# $key = $field -replace '\|.*', '' $index = $dict.detection.$selection.IndexOf($item) if ($Config.CaseSensitivity.AllFields -or ($key -in $Config.CaseSensitivity.Fields)) { if ($dict.detection.$selection.Count -gt 1) { if ($Config.CaseSensitivity.Mode -eq 'uppercase') { $newCase = $dict.detection.$selection[$index][$field].ToUpper() } else { $newCase = $dict.detection.$selection[$index][$field].ToLower() } $dict.detection.$selection[$index][$field] = $newCase } else { if ($Config.CaseSensitivity.Mode -eq 'uppercase') { $newCase = $dict.detection.$selection[$index].ToUpper() } else { $newCase = $dict.detection.$selection[$index].ToLower() } $dict.detection.$selection[$index] = $newCase } } #> } # Add exceptions to yaml if ($exceptions.Count -gt 0) { $yaml = (Add-PrivSigmaException -RuleDict $dict -ExceptionList $exceptions) | ConvertTo-Yaml } else { $yaml = $dict | ConvertTo-Yaml } # quote hex numbers (workaround) if ($yaml -match '(0x)((\w|\d)*)') { $yaml = $yaml -replace '(0x)((\w|\d)*)', "'`$1`$2'" } return $yaml } end { # nothing to do } } |