modules/Devolutions.CIEM.Graph/Public/Get-CIEMAttackPath.ps1
|
function ConvertFromCIEMAttackPathRow { [CmdletBinding()] param( [Parameter(Mandatory)] [object]$Row ) $ErrorActionPreference = 'Stop' $attackPath = [CIEMAttackPath]::new() $attackPath.Id = [string]$Row.id $attackPath.RuleId = [string]$Row.rule_id $attackPath.PatternId = [string]$Row.rule_id $attackPath.PatternName = [string]$Row.pattern_name $attackPath.Severity = [string]$Row.severity $attackPath.Category = [string]$Row.category $attackPath.Remediation = [string]$Row.remediation $attackPath.RemediationScriptPath = [string]$Row.remediation_script_path $attackPath.PsuScriptName = [string]$Row.psu_script_name $attackPath.PathChain = [string]$Row.path_chain $attackPath.EvaluatedAt = [string]$Row.evaluated_at $attackPath.Path = @($Row.path_json | ConvertFrom-Json -ErrorAction Stop) $attackPath.Edges = @($Row.edges_json | ConvertFrom-Json -ErrorAction Stop) $attackPath } function GetCIEMStoredAttackPath { [CmdletBinding()] [OutputType('CIEMAttackPath[]')] param( [Parameter()] [string]$Id, [Parameter()] [string]$PatternId, [Parameter()] [ValidateSet('critical', 'high', 'medium', 'low')] [string]$Severity ) $ErrorActionPreference = 'Stop' $query = @" SELECT ap.id, ap.rule_id, ap.pattern_name, ap.severity, ap.category, ap.remediation, ap.psu_script_name, ap.path_json, ap.edges_json, ap.path_chain, ap.evaluated_at, r.remediation_script_path FROM attack_paths ap JOIN attack_path_rules r ON r.id = ap.rule_id "@ $conditions = @() $parameters = @{} if ($Id) { $conditions += 'ap.id = @id' $parameters.id = $Id } if ($PatternId) { $conditions += 'ap.rule_id = @pattern_id' $parameters.pattern_id = $PatternId } if ($Severity) { $conditions += 'ap.severity = @severity' $parameters.severity = $Severity } if ($conditions.Count -gt 0) { $query += "`nWHERE " + ($conditions -join ' AND ') } $query += "`nORDER BY ap.severity, ap.pattern_name, ap.id" $rows = @(Invoke-CIEMQuery -Query $query -Parameters $parameters) @(foreach ($row in $rows) { ConvertFromCIEMAttackPathRow -Row $row }) } function TestCIEMAttackPathContainsPrincipal { [CmdletBinding()] param( [Parameter(Mandatory)] [CIEMAttackPath]$AttackPath, [Parameter(Mandatory)] [string]$PrincipalId ) $ErrorActionPreference = 'Stop' $nodeIds = @($AttackPath.Path | ForEach-Object { [string]$_.id }) $nodeIds -contains $PrincipalId } function Get-CIEMAttackPath { [CmdletBinding()] [OutputType('CIEMAttackPath')] param( [Parameter()] [string]$PatternId, [Parameter()] [ValidateSet('critical', 'high', 'medium', 'low')] [string]$Severity, [Parameter()] [string]$PrincipalId ) $ErrorActionPreference = 'Stop' $storedParams = @{} if ($PatternId) { $storedParams.PatternId = $PatternId } if ($Severity) { $storedParams.Severity = $Severity } $findings = @(GetCIEMStoredAttackPath @storedParams) if ($PrincipalId) { $findings = @($findings | Where-Object { TestCIEMAttackPathContainsPrincipal -AttackPath $_ -PrincipalId $PrincipalId }) } @($findings) } |