-
-
Save SadProcessor/849bf38e936b9166193a3f54da09b396 to your computer and use it in GitHub Desktop.
ATTCK with Sub-Techniques - BETA
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################## ATTCKnowledge | |
<# | |
# SRC | |
$Ent='https://raw.githubusercontent.com/mitre-attack/attack-website/feature/subtechniques-2.1/data/stix/enterprise-attack.json' | |
#StillToDoWhenIHaveSomeTime | |
$Pre='https://raw.githubusercontent.com/mitre/cti/master/pre-attack/pre-attack.json' | |
$Mob='https://raw.githubusercontent.com/mitre/cti/master/mobile-attack/mobile-attack.json' | |
#> | |
################################################ | |
######################################## Objects | |
$Banner = @(' | |
======================= | |
=== ATTCKnowledge === | |
=== , , === | |
=== _#_ {0,0} _#_ === | |
=== |A| /)_) |A| === | |
=== |T| /"\ |T| === | |
=== |T| / @ \ |T| === | |
=== |&| /=====\ |&| === | |
=== |C|/=======\|C| === | |
=== |K|=========|K| === | |
======================= | |
== SadProcessor 2020 == | |
======================= | |
') | |
#region Objects | |
## Knowledge Obj | |
if(-Not$ATTCK.Technique){$ATTCK = New-Object PSCustomObject -Property @{ | |
# POST | |
Tactic = @() | |
Technique = @() | |
Group = @() | |
Software = @() | |
Relationship = @() <# No Class #> | |
}} | |
## POST | |
# Tactic Class | |
class ATTCKTactic{ | |
[string]$Name | |
[string]$Description | |
[string[]]$Type | |
[string]$ID | |
[string]$Wiki | |
[PScustomObject]$Reference | |
[datetime]$Created | |
[datetime]$Modified | |
[string[]]$Contributor | |
[string]$STIX | |
} | |
Update-TypeData -TypeName ATTCKTactic -DefaultDisplayPropertySet ID,Name,Description -Force | |
## Technique Class | |
class ATTCKTechnique{ | |
[string]$Name | |
[string[]]$Tactic | |
[string]$Description | |
[string[]]$Platform | |
[string[]]$Permission | |
[string[]]$Bypass | |
[string[]]$EffectivePerm | |
[string]$Network | |
[string]$Remote | |
[string]$Prereq | |
[String]$Detection | |
[string]$Mitigation | |
[string[]]$DataSource | |
[string]$ID | |
[PSCustomObject]$Parent | |
[PSCustomObject[]]$Sub | |
[string]$Wiki | |
[PSCustomObject]$Reference | |
[DateTime]$Created | |
[DateTime]$Modified | |
[string[]]$Contributor | |
[string]$STIX | |
} | |
Update-TypeData -TypeName ATTCKTechnique -DefaultDisplayPropertySet ID,Name,Tactic,Description,Mitigation -Force | |
# Software Class | |
class ATTCKSoftware{ | |
[String]$Name | |
[String]$Description | |
[String]$Type | |
[String[]]$Alias | |
[String]$ID | |
[String]$Wiki | |
[PSCustomObject]$Reference | |
[DateTime]$Created | |
[DateTime]$Modified | |
[string[]]$Contributor | |
[String]$STIX | |
} | |
Update-TypeData -TypeName ATTCKSoftware -DefaultDisplayPropertySet ID,Name,Type,Description -Force | |
# Group Class | |
class ATTCKGroup{ | |
[string]$Name | |
[string]$Description | |
[string[]]$Alias | |
[string]$ID | |
[string]$Wiki | |
[PScustomObject]$Reference | |
[datetime]$Created | |
[datetime]$Modified | |
[string[]]$Contributor | |
[string]$STIX | |
} | |
Update-TypeData -TypeName ATTCKGroup -DefaultDisplayPropertySet ID,Name,Alias,Description -Force | |
#endregion | |
#region Common | |
################################################ | |
################################## [Helper] DynP | |
<# Helper Dynamic Params #> | |
function DynP{ | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory=1)][String]$Name, | |
[Parameter(Mandatory=1)][string]$Type, | |
[Parameter(Mandatory=0)][bool]$Mandat=0, | |
[Parameter(Mandatory=0)][int]$Pos=$Null, | |
[Parameter(Mandatory=0)][bool]$Pipe=0, | |
[Parameter(Mandatory=0)][bool]$PipeProp=0, | |
[Parameter(Mandatory=0)]$VSet=$Null | |
) | |
# Create Attribute Obj | |
$Attrb = New-Object Management.Automation.ParameterAttribute | |
$Attrb.Mandatory=$Mandat | |
$Attrb.ValueFromPipeline=$Pipe | |
$Attrb.ValueFromPipelineByPropertyName=$PipeProp | |
if($Pos -ne $null){$Attrb.Position=$Pos} | |
# Create AttributeCollection | |
$Cllct = New-Object Collections.ObjectModel.Collection[System.Attribute] | |
# Add Attribute Obj to Collection | |
$Cllct.Add($Attrb) | |
if($VSet -ne $Null){ | |
# Create ValidateSet & add to collection | |
$VldSt=New-Object Management.Automation.ValidateSetAttribute($VSet) | |
$Cllct.Add($VldSt) | |
} | |
# Create Runtine DynParam | |
$DynP = New-Object Management.Automation.RuntimeDefinedParameter("$Name",$($Type-as[type]),$Cllct) | |
# Return DynParam | |
Return $DynP | |
} | |
#End | |
################################################ | |
###################################### Knowledge | |
<# | |
.Synopsis | |
ATT&CK Knowledge | |
.DESCRIPTION | |
## Action | |
- Display ATT&CK cmdlets | |
- Open ATT&Ck wiki in browser | |
- Sync Knowledge object from Mitre/cti Github repo | |
## Syntax | |
ATTCKnowledge [-Online] | |
ATTCKnowledge [-Sync] [-Verbose] | |
See examples for details | |
PS> Help ATTCKKnowledge -Example | |
## Info | |
Using -Sync fetches a single json data object | |
from the Mitre cti github repo. | |
Data is formated and stored in memory for session. | |
.EXAMPLE | |
ATTCKnowledge | |
Display available cmdlets | |
.EXAMPLE | |
ATTCKnowledge -Online | |
Open ATT&CK in browser | |
.EXAMPLE | |
ATTCKnowledge -Sync [-Verbose] | |
Fetch ATT&CK Knowledge object from github | |
#> | |
function Invoke-ATTCKnowledge{ | |
[Alias('ATTCKnowledge')] | |
[CmdletBinding(DefaultParametersetName='View',HelpURI='https://attack.mitre.org/wiki/Main_Page')] | |
Param( | |
[Parameter(Mandatory=0,ParameterSetName='View')][Switch]$Online, | |
[Parameter(Mandatory=1,ParameterSetName='Sync')][Switch]$Sync | |
) | |
## If Sync | |
if($PSCmdlet.ParameterSetName -eq 'Sync'){ | |
# Banner | |
Write-Host "$Banner" -ForegroundColor Cyan | |
################################################ POST | |
# Get ATTCKnowledge Json obj from Github | |
Write-Verbose "[+] Importing ATT&CK Knowledge..." | |
$url = 'https://raw.githubusercontent.com/mitre/cti/subtechniques/enterprise-attack/enterprise-attack.json' | |
if($PSVersionTable.PSEdition -eq 'Desktop'){ | |
[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12 | |
$Json = irm $url -Verbose:$false | |
} | |
if($PSVersionTable.PSEdition -eq 'Core'){ | |
$Json = curl -s $url | ConvertFrom-Json | |
} | |
# Stop if not found | |
if(-Not$Json.Objects.count){ | |
Write-Warning '[!] No Object Found' | |
Return | |
} | |
# Tactic Obj Collection | |
Write-Verbose "[+] Formating Tactic Objects..." | |
$ATTCK.Tactic = $Json.Objects | where type -eq x-mitre-tactic |%{ | |
[ATTCKTactic]@{ | |
Name = $_.name | |
Description = $_.description | |
Type = $_.type | |
ID =($_.external_references |? source_name -eq mitre-attack).external_id | |
Wiki =($_.external_references |? source_name -eq mitre-attack).url | |
Reference = $_.external_references |? source_name -ne mitre-attack | |
Created = $_.created | |
Modified = $_.modified | |
STIX = $_.id | |
}} | |
# Technique Obj Collection | |
Write-Verbose "[+] Formating Technique Objects..." | |
$TacList = $Json.Objects | Where type -eq course-of-action | |
$ATTCK.Technique = $Json.Objects | Where type -eq attack-pattern |%{ | |
$TechName = $_.name | |
[ATTCKTechnique]@{ | |
Name = $TechName | |
Tactic = $_.kill_chain_phases.phase_name | |
Description = $_.description | |
Platform = $_.x_mitre_platforms | |
Permission = $_.x_mitre_permissions_required | |
Bypass = $_.x_mitre_defense_bypassed | |
EffectivePerm=$_.x_mitre_effective_permissions | |
Network = $_.x_mitre_network_requirements | |
Remote = $_.x_mitre_remote_support | |
Prereq = $_.x_mitre_system_requirements | |
Detection = $(try{($_.description | sls -pattern '((Detection:)(?ms)(.*)(Platform))').matches.Groups[3].value.trim()}Catch{}) | |
Mitigation = ($TacList | Where name -match $TechName).description | |
DataSource = $_.x_mitre_data_sources | |
ID =($_.external_references |? source_name -eq mitre-attack).external_id | |
Parent = $Null | |
Sub = @() | |
Wiki =($_.external_references |? source_name -eq mitre-attack).url | |
Reference = $_.external_references |? source_name -ne mitre-attack | |
Created = $_.created | |
Modified = $_.modified | |
Contributor = $_.x_mitre_contributors | |
STIX = $_.id | |
}} | |
## Remove "Old" ones [No Tactic/Description] | |
$Attck.Technique = $Attck.Technique | ? Description | |
## Add Parent/Sub | |
Foreach($Tech in $Attck.Technique){ | |
if($tech.Id -like "*.*"){$Tech.Parent=@($Attck.technique |? {$_.id -eq $tech.Id.split('.')[0]}|select Id,Name)} | |
else{$Tech.Sub=($attck.Technique|? id -match "^$($tech.id)\.")|Select Id,Name|sort id} | |
} | |
# Group Obj Collection | |
Write-Verbose "[+] Formating Group Objects..." | |
$ATTCK.Group = $Json.Objects | Where type -eq intrusion-set |%{ | |
[ATTCKGroup]@{ | |
Name = $_.name | |
Description = $_.description | |
Alias = $_.aliases | |
ID =($_.external_references |? source_name -eq mitre-attack).external_id | |
Wiki =($_.external_references |? source_name -eq mitre-attack).url | |
Reference = $_.external_references |? source_name -ne mitre-attack | |
Created = $_.created | |
Modified = $_.modified | |
Contributor = $_.x_mitre_contributors | |
STIX = $_.id | |
}} | |
# Software Obj Collection | |
Write-Verbose "[+] Formating Software Objects..." | |
$ATTCK.Software = $Json.Objects | Where {$_.type -eq 'tool' -OR $_.type -eq 'malware'} |%{ | |
[ATTCKSoftware]@{ | |
Name = $_.name | |
Description = $_.description | |
Type = $_.type | |
Alias = $_.x_mitre_aliases | |
ID =($_.external_references |? source_name -eq mitre-attack).external_id | |
Wiki =($_.external_references |? source_name -eq mitre-attack).url | |
Reference = $_.external_references |? source_name -ne mitre-attack | |
Created = $_.created | |
Modified = $_.modified | |
Contributor = $_.x_mitre_contributors | |
STIX = $_.id | |
}} | |
# Relationship Obj Collection | |
Write-Verbose "[+] Formating Relationship Objects..." | |
$ATTCK.Relationship = $Json.Objects | Where type -eq 'relationship' |%{ | |
[PSCustomObject]@{ | |
Source=$_.source_ref | |
Edge =$_.relationship_type | |
Target=$_.target_ref | |
Description=$_.Description | |
Reference = $_.external_references | |
}} | |
Write-Verbose "[+] Done." | |
} | |
## If View | |
Else{ | |
# If Online | |
if($Online){start-Process "https://attack.mitre.org/wiki/Technique_Matrix"} | |
# Else Cmdlet Memo | |
else{ | |
$Banner | |
[PSCustomObject]@{Cmdlet='Invoke-ATTCKnowledge';Alias='' ;Help='Help ATTCKnowledge' } | |
[PSCustomObject]@{Cmdlet='Get-ATTCKTechnique' ;Alias='ATTCK' ;Help='Help ATTCK-Technique'} | |
[PSCustomObject]@{Cmdlet='Get-ATTCKTactic' ;Alias='ATTCK-Tactic' ;Help='Help ATTCK-Tactic' } | |
[PSCustomObject]@{Cmdlet='Get-ATTCKGroup' ;Alias='ATTCK-Group' ;Help='Help ATTCK-Group' } | |
[PSCustomObject]@{Cmdlet='Get-ATTCKSoftware' ;Alias='ATTCK-Software' ;Help='Help ATTCK-Software' } | |
[PSCustomObject]@{Cmdlet='Get-ATTCKUsage' ;Alias='ATTCK-Usage' ;Help='Help ATTCK-Usage' } | |
}}} | |
#########End | |
#endregion | |
#region POST | |
################################################ | |
###################################### Technique | |
<# | |
.Synopsis | |
ATT&CK Techniques | |
.DESCRIPTION | |
## Action | |
- List all Techniques | |
- View Technique(s) by name | |
- View Technique(s) by ID | |
- Open ATT&Ck wiki in browser | |
- Filter Technique by Tactic/Platform/Context | |
- Search Keyword in description | |
## Syntax | |
ATTCKTechnique [-Online] | |
ATTCKTechnique [-name] [-Value] <tab> [-Online] [-Reference] | |
ATTCKTechnique -ID [-Value] <tab> [-Online] [-Reference] | |
ATTCKTechnique -Filter [[-Tactic] <tab>] [[-Platform] <tab>] [[-Permission] <tab>] | |
ATTCKTechnique -Description [-Match] <input> | |
See examples for details | |
PS> Help ATTCKTechnique -Example | |
.EXAMPLE | |
ATTCKTechnique | |
List all available techniques | |
Use |Where or |select to filter objects | |
Object Properties tab-complete after pipeline :) | |
.EXAMPLE | |
ATTCKTechnique AppleScript | |
View Technique by name | |
Accepts multiple coma separated values | |
Technique names tab-complete | |
Add -online -> open wiki in browser | |
Add -reference -> view reference | |
Add -reference -online -> open reference in Browser | |
.EXAMPLE | |
ATTCKTechnique -ID T1001 | |
View Technique by Mitre ID | |
Accepts multiple coma separated values | |
Technique IDs tab-complete | |
Add -online -> open wiki in browser | |
Add -reference -> view reference | |
Add -reference -online -> open reference in Browser | |
.EXAMPLE | |
ATTCKTechnique -Description 'Subtee' | |
View Techniques where desciption match 'Subtee' | |
.EXAMPLE | |
ATTCKTechnique -Filter lateral-movement macOS root | |
List macOS lateral mvt techniques that require root | |
Can filter on Tactic/Platform/Permission | |
(positional in this order or named params) | |
All tab-completes | |
#> | |
function Get-ATTCKTechnique{ | |
[CmdletBinding(DefaultParameterSetName='Name',HelpURI='https://attack.mitre.org/wiki/All_Techniques')] | |
[OutputType([ATTCKTechnique])] | |
[Alias('ATTCK-Technique','ATTCK')] | |
Param( | |
# Select by Name | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Name, | |
# Select by ID | |
[Parameter(Mandatory=1,ParameterSetName='ID')][Switch]$ID, | |
# Apply Filters | |
[Parameter(Mandatory=1,ParameterSetName='Filter')][Alias('x')][Switch]$Filter, | |
# Match Description | |
[Parameter(Mandatory=1,ParameterSetName='Description')][Switch]$Description, | |
# Include Sub-Technique | |
[Parameter(Mandatory=0,ParameterSetName='ID')] | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Sub, | |
# View Reference | |
[Parameter(Mandatory=0,ParameterSetName='ID')] | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Reference, | |
# View Online | |
[Parameter(Mandatory=0,ParameterSetName='ID')] | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Online | |
) | |
DynamicParam{ | |
## DynDico | |
$Dico = New-Object Management.Automation.RuntimeDefinedParameterDictionary | |
# If Fitler | |
if($PSCmdlet.ParameterSetName -eq 'Filter'){ | |
# Prep DynP | |
$DynTact = DynP -Name 'Tactic' -Type 'String[]' -Pos 0 -VSet @($Attck.Technique.Tactic|sort -unique) | |
$DynPlat = DynP -Name 'Platform' -Type 'String[]' -Pos 1 -VSet @($Attck.Technique.Platform|sort -unique) | |
$DynPerm = DynP -Name 'Permission' -Type 'String[]' -Pos 2 -VSet @($Attck.Technique.Permission|sort -unique) | |
# DynP to Dico | |
$Dico.Add('Tactic',$DynTact) | |
$Dico.Add('Platform',$DynPlat) | |
$Dico.Add('Permission',$DynPerm) | |
} | |
# If Description | |
Elseif($PSCmdlet.ParameterSetName -eq 'Description'){ | |
$DynDesc = DynP -Name 'Match' -Type 'string' -mandat 1 -Pos 0 | |
$Dico.Add('Match',$DynDesc) | |
} | |
# Else | |
else{# If ID | |
if($PSCmdlet.ParameterSetName -eq 'ID'){ | |
$DynID = DynP -Name 'Value' -Type 'String[]' -Mandat 1 -Pos 0 -VSet @($Attck.Technique.ID) | |
$Dico.Add('Value',$DynID) | |
} | |
# If Name | |
if($PSCmdlet.ParameterSetName -eq 'Name'){ | |
$DynName = DynP -Name 'Value' -Type 'String[]' -Mandat 0 -Pos 0 -VSet @($Attck.Technique.Name) | |
$Dico.Add('Value',$DynName) | |
}} | |
## Return Dico | |
Return $Dico | |
} | |
Process{ | |
## Get Techniques | |
$Result = $Attck.Technique | |
# Apply Filters | |
if($PSCmdlet.ParameterSetName -eq 'Filter'){ | |
if($PSBoundParameters.Tactic){$Result = $Result | ? tactic -match "$($PSBoundParameters.Tactic-join'|')"} | |
if($PSBoundParameters.Platform){$Result = $Result | ? Platform -match "$($PSBoundParameters.Platform-join'|')"} | |
if($PSBoundParameters.Permission){$Result = $Result | ? Permission -match "$($PSBoundParameters.Permission-join'|')"} | |
} | |
# Match in Description | |
if($PScmdlet.ParameterSetName -eq 'Description'){$DynDesc.value | |
$Result = $Result | ? Description -match $DynDesc.value | |
} | |
# Or - Select by ID | |
if($PSCmdlet.ParameterSetName -eq 'ID'){ | |
if($DynID.IsSet){ | |
$Result = @() | |
$DynID.value|%{$Result += $Attck.Technique | ? ID -eq $_} | |
$Url = $Result.Wiki | |
if($Reference){$Result=$Result.Reference;$Url = $Result.Url} | |
}} | |
# Or - Select by Name | |
if($PSCmdlet.ParameterSetName -eq 'Name'){ | |
if($DynName.IsSet){ | |
$Result = @() | |
$DynName.value|%{$Result += $Attck.Technique | ? Name -eq $_} | |
$Url = $Result.Wiki | |
if($Reference){$Result=$Result.Reference;$Url = $Result.Url} | |
}} | |
# If Subs | |
if($Sub){ | |
$All=@() | |
Foreach($R in $result){$All+=$Attck.Technique|? id -match "^$($R.id.split('.')[0])"} | |
$Result = $all | |
} | |
## Output | |
# If Online > Open URL | |
if($Online){ | |
if(-Not$DynName.IsSet){$url='https://attack.mitre.org/wiki/All_Techniques'} | |
$Url|%{try{Start-Process $_}catch{}} | |
} | |
# Else Return Result | |
else{Return $result} | |
}} | |
#####End | |
################################################ | |
########################################## Group | |
<# | |
.Synopsis | |
ATT&CK Groups | |
.DESCRIPTION | |
## Action | |
- List all Groups | |
- View Group(s) by name | |
- View Group(s) by ID | |
- Open ATT&Ck wiki in browser | |
- Match keyword in Group description | |
## Syntax | |
ATTCK-Group [-Online] | |
ATTCK-Group [-name] [-Value] <tab> [-Online] [-Reference] | |
ATTCK-Group -ID [-Value] <tab> [-Online] [-Reference] | |
ATTCK-Group -Description [-Match] <input> | |
See examples for details | |
PS> Help ATTCK-Group -Example | |
.EXAMPLE | |
ATTCKGroup | |
List all available Groups | |
Use |Where or |select to filter objects | |
Object Properties tab-complete after pipeline :) | |
.EXAMPLE | |
ATTCK-Group admin@338 | |
View Group by name/alias | |
Accepts multiple coma separated values | |
Group names tab-complete | |
Add -Online -> open wiki in browser | |
Add -Reference -> view reference | |
Add -Reference -Online -> open reference in Browser | |
.EXAMPLE | |
ATTCK-Group -ID G0023 | Select Description | |
View Group by Mitre ID | |
Accepts multiple coma separated values | |
Group IDs tab-complete | |
Add -Online -> open wiki in browser | |
Add -Reference -> view reference | |
Add -Reference -Online -> open reference in Browser | |
.EXAMPLE | |
ATTCKGroup -Description "china|chinese" | select name,alias | |
View Groups attributed to China | |
#> | |
function Get-ATTCKGroup{ | |
[CmdletBinding(DefaultParameterSetName='Name',HelpURI='https://attack.mitre.org/wiki/Groups')] | |
[OutputType([ATTCKGroup])] | |
[Alias('ATTCK-Group')] | |
Param( | |
# Select by Name | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Name, | |
# Select by ID | |
[Parameter(Mandatory=1,ParameterSetName='ID')][Switch]$ID, | |
# Match Description | |
[Parameter(Mandatory=1,ParameterSetName='Description')][Switch]$Description, | |
# View Reference | |
[Parameter(Mandatory=0,ParameterSetName='ID')] | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Reference, | |
# View Online | |
[Parameter(Mandatory=0,ParameterSetName='ID')] | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Online | |
) | |
DynamicParam{ | |
## DynDico | |
$Dico = New-Object Management.Automation.RuntimeDefinedParameterDictionary | |
# If ID | |
if($PSCmdlet.ParameterSetName -eq 'ID'){ | |
$DynID = DynP -Name 'Value' -Type 'String[]' -Mandat 1 -Pos 0 -VSet @($Attck.Group.ID | sort) | |
$Dico.Add('Value',$DynID) | |
} | |
# If Name | |
if($PSCmdlet.ParameterSetName -eq 'Name'){ | |
$DynName = DynP -Name 'Value' -Type 'String[]' -Mandat 0 -Pos 0 -VSet @($attck.group.alias | sort -unique) | |
$Dico.Add('Value',$DynName) | |
} | |
# If ID | |
if($PSCmdlet.ParameterSetName -eq 'Description'){ | |
$DynDesc = DynP -Name 'match' -Type 'String' -Mandat 1 -Pos 0 | |
$Dico.Add('match',$DynDesc) | |
} | |
## Return Dico | |
Return $Dico | |
} | |
Process{ | |
## Get Groups | |
$Result = $Attck.Group | |
# Select by ID | |
if($PSCmdlet.ParameterSetName -eq 'ID'){ | |
$Result = @() | |
$DynID.value|%{$Result += $Attck.Group | ? ID -eq $_} | |
$Url = $Result.Wiki | |
if($Reference){$Result=$Result.Group ;$Url = $Result.Url} | |
} | |
# Or - Select by Name | |
if($PSCmdlet.ParameterSetName -eq 'Name' -AND $DynName.IsSet){ | |
$Result = @() | |
$DynName.value|%{$Result += $Attck.Group | ? Alias -Contains $_} | |
$Url = $Result.Wiki | |
if($Reference){$Result=$Result.Reference;$Url = $Result.Url} | |
} | |
# Or - Match in Description | |
if($PSCmdlet.ParameterSetName -eq 'Description'){ | |
$Result = $Result | ? Description -match $DynDesc.Value | |
} | |
## Output | |
# If Online > Open URL | |
if($Online){ | |
if(-Not$DynName.IsSet){$url='https://attack.mitre.org/wiki/Groups'} | |
$Url|%{try{Start-Process $_}catch{}} | |
} | |
# Else Return Result | |
else{Return $result} | |
}} | |
#####End | |
################################################ | |
####################################### Software | |
<# | |
.Synopsis | |
ATT&CK Software | |
.DESCRIPTION | |
## Action | |
- List all Software | |
- View Software by name | |
- View Software by ID | |
- Open ATT&Ck wiki in browser | |
- Filter Software by type (tool vs Malware) | |
- Match keyword in Software description | |
## Syntax | |
ATTCKSoftware [-Online] | |
ATTCKSoftware [-name] [-Value] <tab> [-Online] [-Reference] | |
ATTCKSoftware -ID [-Value] <tab> [-Online] [-Reference] | |
ATTCKSoftware -Filter [-Type] <tab> | |
ATTCKSoftware -Description [-match] <input> | |
See examples for details | |
PS> Help ATTCKSoftware -Example | |
.EXAMPLE | |
ATTCKSoftware | |
List all available software | |
Use |Where or |select to filter objects | |
Object Properties tab-complete after pipeline :) | |
.EXAMPLE | |
ATTCKSoftware CozyCar | |
View Technique by name | |
Accepts multiple coma separated values | |
Technique names tab-complete | |
Add -online -> open wiki in browser | |
Add -reference -> view reference | |
Add -reference -online -> open reference in Browser | |
.EXAMPLE | |
ATTCKSoftware -ID S0021 | |
View Software by Mitre ID | |
Accepts multiple coma separated values | |
Software IDs tab-complete | |
Add -online -> open wiki in browser | |
Add -reference -> view reference | |
Add -reference -online -> open reference in Browser | |
.EXAMPLE | |
ATTCKSoftware -Filter malware | |
List all software of type malware (vs. tool) | |
.EXAMPLE | |
ATTCKSoftware -Description worm | Select Name,Alias,Description | |
Return software matching 'worm' in description | |
#> | |
function Get-ATTCKSoftware{ | |
[CmdletBinding(DefaultParameterSetName='Name',HelpURI='https://attack.mitre.org/wiki/Software')] | |
[OutputType([ATTCKSoftware])] | |
[Alias('ATTCK-Software')] | |
Param( | |
# Select by Name | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Name, | |
# Select by ID | |
[Parameter(Mandatory=1,ParameterSetName='ID')][Switch]$ID, | |
# Apply Filters | |
[Parameter(Mandatory=1,ParameterSetName='Filter')][Alias('x')][Switch]$Filter, | |
# Apply Filters | |
[Parameter(Mandatory=1,ParameterSetName='Description')][Switch]$Description, | |
# View Reference | |
[Parameter(Mandatory=0,ParameterSetName='ID')] | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Reference, | |
# View Online | |
[Parameter(Mandatory=0,ParameterSetName='ID')] | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Online | |
) | |
DynamicParam{ | |
## DynDico | |
$Dico = New-Object Management.Automation.RuntimeDefinedParameterDictionary | |
# If Fitler Type | |
if($PSCmdlet.ParameterSetName -eq 'Filter'){ | |
# Prep DynP | |
$DynType = DynP -Name 'Type' -Type 'String' -Mandat 1 -Pos 0 -VSet @($Attck.Software.Type|sort -unique) | |
$Dico.Add('Type',$DynType) | |
} | |
if($PSCmdlet.ParameterSetName -eq 'Description'){ | |
# Prep DynP | |
$DynDesc = DynP -Name 'Match' -Type 'String' -Mandat 1 -Pos 0 | |
$Dico.Add('Match',$DynDesc) | |
} | |
# If Select Name | |
if($PSCmdlet.ParameterSetName -eq 'ID'){ | |
$DynID = DynP -Name 'Value' -Type 'String[]' -Mandat 1 -Pos 0 -VSet @($Attck.Software.ID) | |
$Dico.Add('Value',$DynID) | |
} | |
# If Name | |
if($PSCmdlet.ParameterSetName -eq 'Name'){ | |
$DynName = DynP -Name 'Value' -Type 'String[]' -Mandat 0 -Pos 0 -VSet @($Attck.Software.Name) | |
$Dico.Add('Value',$DynName) | |
} | |
## Return Dico | |
Return $Dico | |
} | |
Process{ | |
## Get Techniques | |
$Result = $Attck.Software | |
# Filter by Type | |
if($PSCmdlet.ParameterSetName -eq 'Filter'){ | |
$Result = $Result | ? Type -eq $DynType.Value | |
} | |
# Match Description | |
if($PSCmdlet.ParameterSetName -eq 'Description'){ | |
$Result = $Result | ? Description -match $DynDesc.Value | |
} | |
# Or - Select by ID | |
if($PSCmdlet.ParameterSetName -eq 'ID'){ | |
if($DynID.IsSet){ | |
$Result = @() | |
$DynID.value|%{$Result += $Attck.Software | ? ID -eq $_} | |
$Url = $Result.Wiki | |
if($Reference){$Result=$Result.Reference;$Url = $Result.Url} | |
}} | |
# Or - Select by Name | |
if($PSCmdlet.ParameterSetName -eq 'Name'){ | |
if($DynName.IsSet){ | |
$Result = @() | |
$DynName.value|%{$Result += $Attck.Software | ? Name -eq $_} | |
$Url = $Result.Wiki | |
if($Reference){$Result=$Result.Reference;$Url = $Result.Url} | |
}} | |
## Output | |
# If Online > Open URL | |
if($Online){ | |
if(-Not$DynName.IsSet){'https://attack.mitre.org/wiki/Software'} | |
$Url|%{try{Start-Process $_}catch{}} | |
} | |
# Else Return Result | |
else{Return $result} | |
}} | |
#####End | |
################################################ | |
######################################### Tactic | |
<# | |
.Synopsis | |
ATT&CK Tactics | |
.DESCRIPTION | |
## Action | |
- List all Tactics | |
- View Tactic(s) by name | |
- View Tactic(s) by ID | |
- Open ATT&Ck wiki in browser | |
## Syntax | |
ATTCK-Tactic [-Online] | |
ATTCK-Tactic [-name] [-Value] <tab> [-Online] [-Reference] | |
ATTCK-Tactic -ID [-Value] <tab> [-Online] [-Reference] | |
See examples for details | |
PS> Help ATTCK-Tactic -Example | |
.EXAMPLE | |
ATTCK-Tactic | |
List all available Groups | |
Use |Where or |select to filter objects | |
Object Properties tab-complete after pipeline :) | |
.EXAMPLE | |
ATTCK-Tactic impact | |
View Tactic by name | |
Accepts multiple coma separated values | |
Tactic names tab-complete | |
Add -Online -> open wiki in browser | |
Add -Reference -> view reference | |
Add -Reference -Online -> open reference in Browser | |
.EXAMPLE | |
ATTCK-Tactic -ID TA0001 | Select Description | |
View Group by Mitre ID | |
Accepts multiple coma separated values | |
Tactic IDs tab-complete | |
Add -Online -> open wiki in browser | |
Add -Reference -> view reference | |
Add -Reference -Online -> open reference in Browser | |
#> | |
function Get-ATTCKTactic{ | |
[CmdletBinding(DefaultParameterSetName='Name',HelpURI='https://attack.mitre.org/tactics/enterprise/')] | |
[OutputType([ATTCKTactic])] | |
[Alias('ATTCK-Tactic')] | |
Param( | |
# Select by Name | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Name, | |
# Select by ID | |
[Parameter(Mandatory=1,ParameterSetName='ID')][Switch]$ID, | |
# View Reference | |
[Parameter(Mandatory=0,ParameterSetName='ID')] | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Reference, | |
# View Online | |
[Parameter(Mandatory=0,ParameterSetName='ID')] | |
[Parameter(Mandatory=0,ParameterSetName='Name')][Switch]$Online | |
) | |
DynamicParam{ | |
## DynDico | |
$Dico = New-Object Management.Automation.RuntimeDefinedParameterDictionary | |
# If ID | |
if($PSCmdlet.ParameterSetName -eq 'ID'){ | |
$DynID = DynP -Name 'Value' -Type 'String[]' -Mandat 1 -Pos 0 -VSet @($Attck.Tactic.ID | sort -Unique) | |
$Dico.Add('Value',$DynID) | |
} | |
# If Name | |
if($PSCmdlet.ParameterSetName -eq 'Name'){ | |
$DynName = DynP -Name 'Value' -Type 'String[]' -Mandat 0 -Pos 0 -VSet @($attck.Tactic.name | sort -unique) | |
$Dico.Add('Value',$DynName) | |
} | |
## Return Dico | |
Return $Dico | |
} | |
Process{ | |
## Get Groups | |
$Result = $Attck.Tactic | |
# Select by ID | |
if($PSCmdlet.ParameterSetName -eq 'ID'){ | |
$Result = @() | |
$DynID.value|%{$Result += $Attck.Tactic | ? ID -eq $_} | |
$Url = $Result.Wiki | |
if($Reference){$Result=$Result.Tactic ;$Url = $Result.Url} | |
} | |
# Or - Select by Name | |
if($PSCmdlet.ParameterSetName -eq 'Name' -AND $DynName.IsSet){ | |
$Result = @() | |
$DynName.value|%{$Result += $Attck.Tactic | ? name -eq $_} | |
$Url = $Result.Wiki | |
if($Reference){$Result=$Result.Reference;$Url = $Result.Url} | |
} | |
## Output | |
# If Online > Open URL | |
if($Online){ | |
if(-Not$DynName.IsSet){$url='https://attack.mitre.org/tactics/enterprise/'} | |
$Url|%{try{Start-Process $_}catch{}} | |
} | |
# Else Return Result | |
else{Return $result} | |
}} | |
#####End | |
# ATTCK-Usage -Map Group_Using_Technique -Name <name> | |
# ATTCK-Usage -Map Group_Using_Software -Name <name> | |
# ATTCK-Usage -Map Software_Using_Technique -Name <name> | |
# ATTCK-Usage -Map Software_UsedBy_Group -Name <name> | |
# ATTCK-Usage -Map Technique_UsedBy_Group -Name <name> | |
# ATTCK-Usage -Map Technique_Usedby_Software -Name <name> | |
Function Get-ATTCKUsage{ | |
[Alias('ATTCK-Usage','Map')] | |
Param( | |
[ValidateSet('Group_Using_Technique','Group_Using_Software','Software_Using_Technique','Software_UsedBy_Group','Technique_UsedBy_Group','Technique_Usedby_Software')] | |
[Parameter(Mandatory=1,Position=0)][String]$Map | |
) | |
DynamicParam{ | |
# Switch ValidateSet | |
Switch($Map){ | |
'Group_Using_Technique' {$VSet=$attck.Technique.name|Sort -unique} | |
'Group_Using_Software' {$VSet=$attck.Software.alias|Sort -unique} | |
'Software_Using_Technique' {$VSet=$attck.Technique.name|Sort -unique} | |
'Software_UsedBy_Group' {$VSet=$attck.Group.alias |Sort -unique} | |
'Technique_UsedBy_Group' {$VSet=$attck.Group.alias |Sort -unique} | |
'Technique_Usedby_Software'{$VSet=$attck.Software.alias|Sort -unique} | |
} | |
# Dico | |
$Dico = New-Object Management.Automation.RuntimeDefinedParameterDictionary | |
# DynPs | |
$DynName = DynP -Name 'Name' -Type 'String' -Mandat 1 -Pos 1 -VSet $Vset | |
$DynDesc = DynP -Name 'Describe' -type 'Switch' -Mandat 0 -Pos 2 | |
# Return | |
$Dico.Add('Name',$DynName) | |
$dico.Add('Describe',$DynDesc) | |
Return $Dico | |
} | |
Process{ | |
$InType = $Map.split('_')[2] | |
$EdgeDir = $Map.split('_')[1] | |
$OutType = $Map.split('_')[0] | |
if($InType -eq 'Technique'){$Prop='name'}else{$Prop='alias'} | |
#if($OutType -match "ID$"){$Prop='ID'; $OutType=$outype-replace"(ID$)",''} | |
# InputObj name to STIX | |
$Search = $ATTCK.$InType | Where $Prop -eq $DynName.Value | |
# RelationShip direction | |
If($EdgeDir -eq 'Using'){$a='Target';$B='Source'}Else{$a='Source';$b='Target'} | |
# For each edge matching Search stix | |
Foreach($Rel in ($ATTCK.Relationship | Where $a -eq $Search.stix | Where Edge -eq uses)){ | |
$SearchSTIX=$Rel.$b | |
if($Rel.description){$Desc = $rel.description}else{$desc=$null} | |
# Return OutputObj by STIX | |
$Found = $ATTCK.$OutType | where {$_.stix -eq $SearchSTIX} | |
if($edgeDir -eq "UsedBy"){$Src=$Search.Name;$tgt=$Found.Name}else{$Src=$Found.Name;$tgt=$Search.Name} | |
if($DynDesc.value -AND $Found.Name){ | |
Return [PSCustomObject]@{ | |
Source = $Search.Name | |
Edge = 'Uses' | |
Target = $Found.Name | |
Description= $Desc | |
Reference = $Rel.reference | |
}} | |
else{Return $Found} | |
}}} | |
#########End | |
#Load | |
if(-Not$Attck.Tactic.count){ATTCKnowledge -Sync -Verbose} | |
#endregion | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment