Falcon Crowdsrike est l'un des antivirus next generation (EDR) les plus en vue et les plus performants du marché. Le script ci-dessous propose un exemple de requetage de l'API de Crowdstrike via l'utilisation du module Powershell PSFalcon (https://www.powershellgallery.com/packages/PSFalcon)
L'acces et l'utilisation de l'Api Crowdstrike requiert bien sur un abonnement Crowdstrike (https://www.crowdstrike.com/)
Le script utilisant pour l'acces a l'API, une clé d'encryptage (AES.key), un fichier contenant le SecID (SecID.txt), et un fichier contenant la passphrase (pass.txt), il est necessaire de recreer ces éléments avec le contexte de l'abonnement auquel on se connecte (SecID).
Le script interroge l'API pour recuperer des éléments tel que les hotes, les comportements (Behaviors), les detections, les incidents.
QueryCrowdstrike.ps1 (11,62 kb)
##############################################
### QUERY CROWDSTRIKE WITH PSFALCON MODULE ###
##############################################
<#
.SYNOPSIS
INTERROGATION D'UN TENANT FALCON CROWDSTRIKE VIA L'UTILISATION DU MODULE POWERSHELL PSFALCON
NB: LES DONNEES SONT EXTRAITES SOUS FORME D'UN FICHIERS CSV
.PARAMETER
ClientID : Client ID crowdstrike
Pass : Password du compte d'acces a l'API
ExportFolder : Dossier d'export du fichier CSV
LogFolder : Chemin du dossier où creer le log du script
.EXAMPLE
.\QueryCrowdstrike.ps1 -CloudUrl "https://api.eu-1.crowdstrike.com" -ClientID <clientid> -Pass <pass> -ExportFolder ./ -LogFolder ./
#>
[CmdletBinding()]
param(
[Parameter(Mandatory,HelpMessage="Cloud URL")]
$CloudUrl,
[Parameter(HelpMessage="Client ID crowdstrike")]
$ClientID,
[Parameter(HelpMessage="Password du compte d'acces a l'API")]
$Pass,
[Parameter(Mandatory,HelpMessage="Dossier d'export du fichier CSV")]
[string]$ExportFolder="./CSV",
[Parameter(Mandatory,HelpMessage="Chemin du dossier où creer le log du script")]
[string]$LogFolder="./",
[Parameter(Mandatory,HelpMessage="Chemin de la clé utilisée pour l'encryption du CID et de la passphrase")]
$KeyFile = "D:\MyFolder\CROWDSTRIKE\AES.key",
[Parameter(Mandatory,HelpMessage="Chemin du fichier contenant le SecID du client")]
$SecIDFile = "D:\MyFolder\CROWDSTRIKE\SecID.txt",
[Parameter(Mandatory,HelpMessage="Chemin du fichier contenant la passphrase")]
$PassFile = "D:\MyFolder\CROWDSTRIKE\Pass.txt"
)
# TO RENEW KEY FILE USED FOR CLIENT ID AND PASSPHRASE ENCRYPTION
<#
# Generate Key File
$Key = New-Object Byte[] 16 # You can use 16, 24, or 32 for AES
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | out-file $KeyFile
#>
# TO RENEW SECID ENCRYPTION, EXECUTE THE CODE BETWEEN <# #>
<#
# Create secure string object
$SecIDFile = "D:\MyFolder\CROWDSTRIKE\SecID.txt"
$Key = Get-Content $KeyFile
$SecID = read-host -Prompt "Enter client SecID" -AsSecureString
$SecID | ConvertFrom-SecureString -key $Key | Out-File $SecIDFile
#>
# TO RENEW PASSPHRASE ENCRYPTION, EXECUTE THE CODE BETWEEN <# #>
<#
# Create secure string object
$PassFile = "D:\MyFolder\CROWDSTRIKE\Pass.txt"
$Key = Get-Content $KeyFile
$Pass = read-host -Prompt "Enter client PassPhrase" -AsSecureString
$Pass | ConvertFrom-SecureString -key $Key | Out-File $PassFile
#>
# OTHER VARIABLES
# Script Name
$ScriptName = "QueryCrowdstrike.ps1"
# LogName = ScriptName without extension
$Log = $ScriptName.Split('.')[0]
# FUNCTIONS
function Write-Log
{
<#
.SYNOPSIS
This function creates or appends a line to a log file.
.PARAMETER Message
The message parameter is the log message you'd like to record to the log file.
.EXAMPLE
PS C:\> Write-Log -Message 'Value1'
This example shows how to call the Write-Log function with named parameters.
#>
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]$Message,
[Parameter(Mandatory)]
[string]$LogPath,
[Parameter(Mandatory)]
[string]$LogName
)
try
{
$DateTime = Get-Date -Format ‘MM-dd-yy HH:mm:ss’
Add-Content -Value "$DateTime - $Message" -Path "$LogPath\$LogName.log"
}
catch
{
Write-Error $_.Exception.Message
}
}
# Requis si l'import du module echoue en en renvoyant plusieurs messages 'Unable to find [System.Net.Http.(...)*]'
Add-Type -AssemblyName System.Net.Http
# Import Module
Import-Module -Name D:\MyFolder\CROWDSTRIKE\Powershell_Module\psfalcon-master\PSFalcon.psm1
$Key = Get-Content $KeyFile
# Get file content and Decrypt ClientID
$ClientID = Get-Content $SecIDFile | ConvertTo-SecureString -Key $key
$ClientID = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($ClientID))
# Get file content and Decrypt Pass
$Pass = Get-Content $PassFile | ConvertTo-SecureString -Key $key
$Pass = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Pass))
# Query for Falcon Token
try
{
Request-FalconToken -ClientId $ClientID -ClientSecret $Pass -Hostname $CloudUrl
}
catch
{
$Message = "Error during Request-FalconToken - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
# Test if Test-FalconToken return True
if ($(Test-FalconToken).token -eq $true)
{
$Message = "Token is valid - OK"
write-host -F Green $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
}
Else
{
$Message = "Problem with Token - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
# GET DATA
#region Falcon Hosts
# Get Falcon Hosts (exemple option -filter: –Filter "hostname:'SRV'")
try
{
$FalconHosts = Get-FalconHost -All -Detailed
#$FalconHosts | select hostname,os_version,agent_version,status | ft -AutoSize
}
catch
{
$Message = "Problem during Get-FalconHost - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
# Convert To CSV
try
{
$FalconHostsCSV = $($FalconHosts | select `
hostname,
os_version,
platform_name,
status,
agent_version,
config_id_base,
config_id_build,
@{Name='First_Seen';Expression={[datetime]::ParseExact($_.first_seen.Replace('T','').Replace('Z',''),'yyyy-MM-ddHH:mm:ss',$null)}},
@{Name='Last_Seen';Expression={[datetime]::ParseExact($_.last_seen.Replace('T','').Replace('Z',''),'yyyy-MM-ddHH:mm:ss',$null)}},
reduced_functionality_mode | ConvertTo-Csv -Delimiter ',' -NoTypeInformation).Replace('"','')
# Display CSV File
$FalconHostsCSV
}
catch
{
$Message = "Error during convert to CSV file for FalconHosts - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
# Export CSV
try
{
$FalconHostsCSV | Out-File -FilePath "$ExportFolder`/FalconHosts.csv" -Force
}
catch
{
$Message = "Error during export of CSV file for FalconHosts - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
#endregion Falcon Hosts
#region Falcon Detection
#Get-FalconDetection
write-host "FALCON DETECTION EVENTS" -B White -f Blue
try
{
$FalconDetection = Get-FalconDetection -Detailed -All
$FalconDetection | sort created_timestamp -Descending
}
catch
{
$Message = "Error during Get-FalconDetection - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
# Convert To CSV
try
{
$FalconDetectionCSV = $($FalconDetection | select `
detection_id,
@{Name='Detection_Creation_Date';Expression={[datetime]::ParseExact($_[0].created_timestamp.split('.')[0].Replace('T',''),'yyyy-MM-ddHH:mm:ss',$null)}},
@{Name='HostName';Expression={$_.device.hostname}},
@{Name='HostIP';Expression={$_.device.local_ip}},
@{Name='DeviceID';Expression={$_.device.device_id}},
@{Name='BehaviorID';Expression={$_.Behaviors.Behavior_id}},
@{Name='Behavior_FileName';Expression={$_.Behaviors.filename}},
@{Name='Behavior_FilePath';Expression={$_.Behaviors.filepath}},
@{Name='Behavior_cmdline';Expression={$_.Behaviors.cmdline}},
status,
max_severity_displayname,
email_sent | ConvertTo-Csv -Delimiter ',' -NoTypeInformation).Replace('"','')
}
catch
{
$Message = "Error during convert to CSV file for FalconDetection - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
# Export CSV
try
{
$FalconDetectionCSV | Out-File -FilePath "$ExportFolder`/FalconDetection.csv"
}
catch
{
$Message = "Error during export of CSV file for FalconDetection - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
#endregion Falcon Detection
#region Falcon Behavior
# Get-FalconBehavior (NB: Transform TimeStamp to more readable format with [datetime]::ParseExact)
write-host "FALCON BEHAVIOR EVENTS" -B White -f Blue
try
{
$FalconBehavior = Get-FalconBehavior | foreach {Get-FalconBehavior -Ids $_} | Select -property behavior_id,display_name,objective,@{Name='BehaviorDate';Expression={[datetime]::ParseExact($_.timestamp.Replace('T','').replace('Z',''),'yyyy-MM-ddHH:mm:ss',$null)}},cmdline,filepath,user_name,incident_id,tactic_id,tactic,technique_id,technique | sort BehaviorDate -Descending
$FalconBehavior
}
catch
{
$Message = "Error during Get-FalconBehavior - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
# Convert To CSV
try
{
$FalconBehaviorCSV = $($FalconBehavior | select BehaviorDate,cmdline,filepath,user_name | ConvertTo-Csv -Delimiter ';' -NoTypeInformation).Replace('"','')
}
catch
{
$Message = "Error during convert to CSV file for FalconBehavior - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
# Export CSV
try
{
$FalconBehaviorCSV | Out-File -FilePath "$ExportFolder`/FalconBehavior.csv"
}
catch
{
$Message = "Error during export of CSV file for FalconBehavior - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
#endregion Falcon Behavior
#region Falcon Incident
write-host "FALCON INCIDENTS EVENTS" -B White -f Blue
try
{
$FalconIncidents= Get-FalconIncident -Detailed -All
$FalconIncidents | sort created -Descending
}
catch
{
$Message = "Error during Get-FalconIncident - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
# Convert To CSV
try
{
$FalconIncidentsCSV = $($FalconIncidents | select `
incident_id,
@{Name='Creation_Date';Expression={[datetime]::ParseExact($_.created.Replace('T','').Replace('Z',''),'yyyy-MM-ddHH:mm:ss',$null)}},
state,
email_state | ConvertTo-Csv -Delimiter ',' -NoTypeInformation).Replace('"','')
}
catch
{
$Message = "Error during convert to CSV file for FalconIncident - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
# Export CSV
try
{
$FalconIncidentsCSV | Out-File -FilePath "$ExportFolder`/FalconIncidents.csv"
}
catch
{
$Message = "Error during export of CSV file for FalconIncidents - END OF SCRIPT"
write-host -F Red $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
EXIT 1
}
#endregion Falcon Incident