Public/container-security.ps1
function Get-FalconContainerAssessment { <# .SYNOPSIS Retrieve Falcon container image assessment reports .DESCRIPTION Requires 'Falcon Container Image: Write'. .PARAMETER Registry Container registry .PARAMETER Repository Container repository .PARAMETER Tag Container tag .LINK https://github.com/crowdstrike/psfalcon/wiki/Get-FalconContainerAssessment #> [CmdletBinding(DefaultParameterSetName='/reports:get',SupportsShouldProcess)] param( [Parameter(ParameterSetName='/reports:get',Mandatory,Position=1)] [string]$Registry, [Parameter(ParameterSetName='/reports:get',Mandatory,Position=2)] [string]$Repository, [Parameter(ParameterSetName='/reports:get',Mandatory,Position=3)] [string]$Tag ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ Query = @('registry','repository','tag') } HostUrl = Get-ContainerUrl } } process { $Request = Invoke-Falcon @Param -Inputs $PSBoundParameters try { $Request | ConvertFrom-Json } catch { $Request } } } function Get-FalconContainerSensor { <# .SYNOPSIS Retrieve the most recent Falcon container sensor build tags .DESCRIPTION Requires 'Falcon Container Image: Read'. .PARAMETER LatestUrl Create a URL using the most recent build tag .LINK https://github.com/crowdstrike/psfalcon/wiki/Get-FalconContainerSensor #> [CmdletBinding(DefaultParameterSetName='/v2/{sensortype}/{region}/release/falcon-sensor/tags/list:get', SupportsShouldProcess)] param( [switch]$LatestUrl ) process { if (!$Script:Falcon.Registry -or $Script:Falcon.Registry.Expiration -lt (Get-Date).AddSeconds(60)) { Request-FalconRegistryCredential } $Param = @{ Endpoint = $PSCmdlet.ParameterSetName -replace '{sensortype}', $Script:Falcon.Registry.SensorType -replace '{region}',$Script:Falcon.Registry.Region Header = @{ Authorization = "Bearer $($Script:Falcon.Registry.Token)" } HostUrl = Get-ContainerUrl -Registry } $Request = Invoke-Falcon @Param -Inputs $PSBoundParameters $Result = try { $Request | ConvertFrom-Json } catch { $Request } if ($LatestUrl) { ($Param.HostUrl -replace 'https://',$null),$Script:Falcon.Registry.SensorType, $Script:Falcon.Registry.Region,'release',"falcon-sensor:$($Result.tags[-1])" -join '/' } else { $Result } } } function Remove-FalconContainerImage { <# .SYNOPSIS Remove a Falcon container image .DESCRIPTION Requires 'Falcon Container Image: Write'. .PARAMETER Id Container image identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconContainerImage #> [CmdletBinding(DefaultParameterSetName='/images/{id}:delete',SupportsShouldProcess)] param( [Parameter(ParameterSetName='/images/{id}:delete',Mandatory,ValueFromPipelineByPropertyName, ValueFromPipeline,Position=1)] [object]$Id ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name; HostUrl = Get-ContainerUrl }} process { $PSBoundParameters.Id = switch ($PSBoundParameters.Id) { { $_.ImageInfo.id } { $_.ImageInfo.id } { $_ -is [string] } { $_ } } if ($PSBoundParameters.Id -notmatch '^[A-Fa-f0-9]{64}$') { throw "'$($PSBoundParameters.Id)' is not a valid image identifier." } else { $Endpoint = $PSCmdlet.ParameterSetName -replace '{id}',$PSBoundParameters.Id [void]$PSBoundParameters.Remove('Id') Invoke-Falcon @Param -Endpoint $Endpoint -Inputs $PSBoundParameters } } } function Remove-FalconRegistryCredential { <# .SYNOPSIS Remove your cached Falcon container registry access token and credential information from the module .LINK https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconRegistryCredential #> [CmdletBinding(SupportsShouldProcess)] param() process { if ($Script:Falcon.Registry) { [void]$Script:Falcon.Remove('Registry') }} } function Request-FalconRegistryCredential { <# .SYNOPSIS Request your Falcon container registry username, password and access token .DESCRIPTION If successful, you token and username are cached for re-use as you use Falcon container security related commands. If an active access token is due to expire in less than 15 seconds, a new token will automatically be requested. Requires 'Falcon Container Image: Read' and 'Sensor Download: Read'. .PARAMETER SensorType Container sensor type, used to determine container registry .LINK https://github.com/crowdstrike/psfalcon/wiki/Request-FalconRegistryCredential #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory,Position=1)] [ValidateSet('falcon-sensor','falcon-container',IgnoreCase=$false)] [string]$SensorType ) process { [System.Collections.Hashtable]$Credential = @{} $Credential['Username'] = if ($Script:Falcon.Registry.Username) { $Script:Falcon.Registry.Username } else { try { @(Get-FalconCcid -EA 0).foreach{ 'fc',$_.Split('-')[0].ToLower() -join '-' } } catch { throw "Failed to retrieve registry username. Verify 'Sensor Download: Read' permission." } } $Credential['Password'] = if ($Script:Falcon.Registry.Password) { $Script:Falcon.Registry.Password } else { try { (Invoke-Falcon -Endpoint ( '/container-security/entities/image-registry-credentials/v1:get')).Token } catch { throw "Failed to retrieve registry password. Verify 'Falcon Container Image: Read' permission." } } if ($Credential.Username -and $Credential.Password) { $Param = @{ Endpoint = "/v2/token?=$($Credential.Username):get" Header = @{ Authorization = "Basic $([System.Convert]::ToBase64String( [System.Text.Encoding]::ASCII.GetBytes("$($Credential.Username):$( $Credential.Password)")))" } Format = @{ Query = @('scope','service') } HostUrl = Get-ContainerUrl -Registry } [string]$Region = switch -Regex ($Script:Falcon.Hostname) { 'eu-1' { 'eu-1' } 'laggar\.gcw' { 'us-gov-1' } 'us-2' { 'us-2' } default { 'us-1' } } $PSBoundParameters['scope'] = 'repository:',"/$Region/release/",':pull' -join $PSBoundParameters.SensorType $PSBoundParameters['service'] = 'registry.crowdstrike.com' [void]$PSBoundParameters.Remove('SensorType') $Request = Invoke-Falcon @Param -Inputs $PSBoundParameters if ($Request) { $Script:Falcon['Registry'] = @{ Username = $Credential.Username Password = $Credential.Password Region = $Region SensorType = $SensorType Token = $Request.token Expiration = (Get-Date).AddSeconds($Request.expires_in) } } } } } function Show-FalconRegistryCredential { <# .SYNOPSIS Display Falcon container registry credential information .LINK https://github.com/crowdstrike/psfalcon/wiki/Show-FalconRegistryCredential #> [CmdletBinding()] param() process { if ($Script:Falcon.Registry) { [string]$PullToken = if ($Script:Falcon.Registry.Username -and $Script:Falcon.Registry.Password) { [string]$BaseAuth = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$( $Script:Falcon.Registry.Username):$($Script:Falcon.Registry.Password)")) [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$([PSCustomObject]@{ auths = @{ 'registry.crowdstrike.com' = @{ auth = $BaseAuth }}} | ConvertTo-Json -Depth 4)")) } [PSCustomObject]@{ Token = if ($Script:Falcon.Registry.Token -and $Script:Falcon.Registry.Expiration -gt (Get-Date).AddSeconds(60)) { $true } else { $false } Username = $Script:Falcon.Registry.Username Password = $Script:Falcon.Registry.Password Region = $Script:Falcon.Registry.Region SensorType = $Script:Falcon.Registry.SensorType PullToken = $PullToken } } else { Write-Error "No registry credential available. Try 'Request-FalconRegistryCredential'." } } } |