# This script is used to contain a list of hostnames found in Crowdstrike
# Fill in the API credentials authorised to use the Crowdstrike API
# Requires to install PSFalcon module with the command <Install-Module -Name PSFalcon -Scope CurrentUser>
$creduser = read-host "CS User ID: "
$credpass = read-host "CS User Password: "
#Request Falcon Token from the API key
Request-FalconToken -ClientID $creduser -ClientSecret $credpass -Cloud eu-1
$import_csv = read-host "Hosts Input CSV: "
$date_exec = (Get-Date).tostring("dd-MM-yyyy_hh-mm-ss")
$export_csv = $import_csv+"_"+$date_exec+".csv"
$workstationInfo = @()
Write-Host ("Import CSV.")
$W_List = Import-Csv -Path $import_csv
Write-Host ("Query CS API.")
foreach ($workstationl in $W_List) {
$workstation = $workstationl.workstation
$HostID=Get-FalconHost -Filter "hostname:['$workstation']" -Detailed
#Write-Host ($HostID)
if ($HostID -ne $null){
$tag=(Get-FalconHost -Filter "hostname:['$workstation']" | Get-FalconSensorTag)
$tag2=$tag.tags
#Write-Host ($workstation+","+$HostID.Status+","+$HostID.product_type_desc+","+$HostID.serial_number+","+$tag2)
$workstationInfo += [PSCustomObject]@{
id=$HostID.device_id
hostname=$workstation
domain=$HostID.machine_domain
ou=$HostID.ou
local_ip=$HostID.local_ip
external_ip=$HostID.external_ip
cs_version=$HostID.agent_version
status=$HostID.status
last_seen=$HostID.last_seen
os=$HostID.os_product_name
entity=$tag2
serial=$HostID.serial_number
last_login=$HostID.last_login_user
}
}
}
Write-Host "Export CSV."
$workstationInfo | Export-Csv -NoTypeInformation -Path $export_csv -delimiter ',' -Encoding UTF8 -Force;
Write-Host "View exported CSV."
Import-Csv $export_csv | Out-GridView
# STEP 01 | download anaconda | https://www.anaconda.com/download/
# STEP 02 | install required python libs
pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org crowdstrike-falconpy
# STEP 03 | set %PATH%
$pipPath = $env:LocalAppData + "\Packages\" + (ls "$env:LocalAppData\Packages\PythonSoftwareFoundation.Python.3.12_*").name
$env:PATH += ";$pipPath\LocalCache\local-packages\Python312\Scripts"
$env:FALCON_CLIENT_ID = read-host "FALCON_CLIENT_ID: "
$env:FALCON_CLIENT_SECRET = read-host "FALCON_CLIENT_SECRET: "
# advanced
2023-11-13T23:45:22.000
# 60 DAYS DETECTION BACKLOG FOR A COMPUTER
ExternalApiType=Event_DetectionSummaryEvent ComputerName=
#
# 60 DAYS DETECTION BACKLOG FOR COMPUTERS SCOPE
ExternalApiType=Event_DetectionSummaryEvent
| where like (ComputerName,”UK%”)
earliest=-7d event_platform=win event_simpleName=SensorHeartbeat ComputerName=
| fields timestamp aid ComputerName ConfigBuild
| stats first(timestamp) AS firstSeen by aid, ComputerName, ConfigBuild
| eval firstSeen=firstSeen/1000
| convert ctime(firstSeen)
| stats values(firstSeen) values(ConfigBuild) by aid, ComputerName
| sort + ComputerName
event_simpleName=ProcessRollup2 AND FileName="bcdedit.exe"
| where like(ComputerName,"DC%")
| table aid, ComputerName, ParentBaseFileName, ImageFileName, CommandLine
event_simpleName=ProcessRollup2 AND FileName="msedge.exe"
| WHERE like(ComputerName,"DC%") AND like(CommandLine,"%msedge.exe%network.mojom.NetworkService%")
| table aid, ComputerName, ParentBaseFileName, ImageFileName, CommandLine
event_simpleName=ProcessRollup2 "lsass.exe"
| table _time, ComputerName, ContextBaseFileName, DomainName, CNAMERecords, RemoteAddressIP4, RPort
ComputerName= event_simpleName="PeFileWritten" FileName IN ("*.exe*")
| table _time, event_simpleName, SHA256HashData,FileName,FilePath,OriginalFilename
| sort - _time
# FilePath and FileName randomized
# Pattern found from the commandline detected / blocked
ComputerName= sourcetype=ImageHashV6-v02
| where like (ImageFileName,"%\ProgramData\%Driver%")
| table _time, MD5HashData, FileName, FilePath
Wallpaper.ps1
| where isnotnull (DetectId)
| table _time, UserName, DetectName, CommandLine
ComputerName= event_simpleName="NewScriptWritten" FileName IN ("*.ps*")
| table _time, event_simpleName, SHA256HashData,FileName,FilePath,OriginalFilename
| sort - _time
ComputerName=
| stats count by FileName, FilePath, ParentBaseFileName
NOT ActiveDirectory* NOT IdpDcPerf* event_simpleName=ProcessRollup2 ComputerName=
| stats count by FileName, FilePath, ParentBaseFileName
event_simpleName=ProcessRollup2 "svchost.exe"
| table _time, ComputerName, ParentBaseFileName, ImageFileName, CommandLine
| sort - _time
ComputerName= Utilman ImageFileName!="*conhost.exe"
| search NOT event_simpleName IN (PeVersionInfo, ClassifiedModuleLoad, ImageHash)
| table _time event_simpleName ParentBaseFileName ImageFileName CommandLine RegObjectName RegValueName TargetFileName RemoteAddressIP4
| sort 0 –_time
ComputerName= event_simpleName=ProcessRollup2 AND( FileName="msedge.exe" OR FileName="chrome.exe" OR FileName="firefox.exe")
| table aid, ComputerName, ParentBaseFileName, ImageFileName, CommandLine
| stats count by ParentBaseFileName
ComputerName= sourcetype="ExecutableDeleted*"
| table _time, TargetFileName
# INITIAL ACCESS / ONE TARGET / Files downloaded from the Internet
#
# Useful for: the Zone identifier stores whether the file was downloaded from the internet.
# Type 3 Zone Identifiers show the URL the file was downloaded from.
#
ComputerName= event_simpleName=MotwWritten ZoneIdentifier_decimal=3
| table _time event_simpleName FileName Zone* HostUrl ReferrerUrl
# INITIAL ACCESS (ia) / ON MANY ASSETS (bulk) / File downloaded (pdf, word, tar, zip, etc.)
#
# Description: Useful to determine the scope targeted that may require further investigations.
# For a file related to a phishing campain, if the client (used for the download) is a web browser, should have an ADS with Zone.identifier = 3. If the client (used for the download) is the “outlook heavy client”, it remains to check.
#
# Event simple name for file: PngFileWritten, PdfFileWritten RtfFileWritten MSXlsxFileWritten MSDocxFileWritten
# RarFileWritten SevenZipFileWritten TarFileWritten ZipFileWritten NewExecutableWritten PeFileWritten
#
FileName= event_simpleName=PdfFileWritten
| rename ContextTimeStamp_decimal as writtenTime
| eval fileSizeMB=round(((Size_decimal/1024)/1024),2)
| table ComputerName FileName FilePath writtenTime fileSizeMB
| convert ctime(writtenTime)
ComputerName= event_platform=win event_simpleName=UserLogon
| eval LogonType = case(LogonType_decimal==2 , "Interactive, ex: typing user name and password on Windows logon prompt", LogonType_decimal==3, "Network;access from the network", LogonType_decimal==4, "Batch,processes executing on behalf of a user; ex : scheduled task", LogonType_decimal==5, "Service; service configured to log on as a user started by the Service Control Manage.",LogonType_decimal==7, "Workstation Unlocked", LogonType_decimal==8, "Network_ClearText; ex : IIS", LogonType_decimal==9, "New_Credentials", LogonType_decimal==10, "RemoteInteractive; remote connection using Terminal Services or Remote Desktop",LogonType_decimal==11, "Cached Interactive ; network credentials stored locally used, not DC", LogonType_decimal==12, "Cached Remote Interactive", LogonType_decimal==13, "Cached Unlock")
| table _time ComputerName UserName ClientComputerName LogonDomain RemoteAddressIP4 LogonType_decimal LogonType
| sort - _time
event_platform=lin event_simpleName=CriticalEnvironmentVariableChanged, EnvironmentVariableName IN (SSH_CONNECTION, USER)
| eventstats list(EnvironmentVariableName) as EnvironmentVariableName,list(EnvironmentVariableValue) as EnvironmentVariableValue by aid, ContextProcessId_decimal
| eval tempData=mvzip(EnvironmentVariableName,EnvironmentVariableValue,":")
| rex field=tempData "SSH_CONNECTION\:((?<clientIP>\d+\.\d+\.\d+\.\d+)\s+(?<rPort>\d+)\s+(?<serverIP>\d+\.\d+\.\d+\.\d+)\s+(?<lPort>\d+))"
| rex field=tempData "USER\:(?<userName>.*)"
| where isnotnull(clientIP)
| search NOT clientIP IN (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.1)
| iplocation clientIP
| lookup local=true aid_master aid OUTPUT Version as osVersion, Country as sshServerCountry
| fillnull City, Country, Region value="-"
| table _time aid ComputerName sshServerCountry osVersion serverIP lPort userName clientIP rPort City Region Country
| where isnotnull(userName)
| sort +ComputerName, +_time
| search NOT clientIP IN (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.1)
(RPort=5938 OR RPort=5939) event_simpleName=NetworkConnectIP4
| where cidrmatch("192.168.110.0/24",LocalIP) AND like(ComputerName,"DC%")
| table _time, ComputerName, LPort, LocalIP, RemoteIP, RPort
| sort _time
RPort=445 event_simpleName=NetworkConnectIP4
| where cidrmatch("192.168.110.0/24",LocalIP) AND like(ComputerName,"DC%")
| table _time, ComputerName, LPort, LocalIP, RemoteIP, RPort
| sort _time
ComputerName= event_simpleName=NetworkConnectIP4
| where not (cidrmatch("192.168.0.0/16",RemoteIP) OR cidrmatch("172.16.0.0/12",RemoteIP) OR cidrmatch("10.0.0.0/8",RemoteIP) OR cidrmatch("224.0.0.0/4",RemoteIP))
| table _time, LPort, LocalIP, RemoteIP, RPort
ComputerName= event_simpleName=DnsRequest*
| table _time, CNAMERecords, DomaineName, IP4Records
ComputerName= sourcetype="DnsRequest*"
| where not like(DomainName,"%in-addr.arpa")
| dedup DomainName
| table DomainName
event_simpleName=networkConnectIP4 NOT ContextBaseFileName IN ("Ntrtscan.exe", "ACCS FTP.exe", "CSFalcon*", "rpcbind") RemoteAddressIP4 IN ("10.*", "172.*", "192.168.*")
| where RPort < 1024
| eval mitre=Tactic."/".Technique
| stats dc(RPort) as number_rport values(RPort) as remote_port_list values(mitre) by ContextBaseFileName
| where number_rport > 5
index=main ComputerName=XXXXXXXXXX *smb*
| eval real_time=strftime(_time,"%Y-%m-%dT%H:%M:%S.%Q")
| eval conn=event_simpleName. " -> " .real_time
| stats values(UserName) values(ClientComputerName) values(conn) by SmbShareName
ComputerName= (index=main sourcetype=UserAccountAddedToGroup* event_platform=win event_simpleName=UserAccountAddedToGroup) OR (index=main sourcetype=ProcessRollup2* event_platform=win event_simpleName=ProcessRollup2)
| eval falconPID=coalesce(TargetProcessId_decimal, RpcClientProcessId_decimal)
| rename UserName as responsibleUserName
| rename UserSid_readable as responsibleUserSID
| eval GroupRid_dec=tonumber(ltrim(tostring(GroupRid), "0"), 16)
| eval UserRid_dec=tonumber(ltrim(tostring(UserRid), "0"), 16)
| eval UserSid_readable=DomainSid. "-" .UserRid_dec
| lookup local=true userinfo.csv UserSid_readable OUTPUT UserName
| lookup local=true grouprid_wingroup.csv GroupRid_dec OUTPUT WinGroup
| fillnull value="-" UserName responsibleUserName
| stats dc(event_simpleName) as eventCount, values(ProcessStartTime_decimal) as processStartTime, values(FileName) as responsibleFile, values(CommandLine) as responsibleCmdLine, values(responsibleUserSID) as responsibleUserSID, values(responsibleUserName) as responsibleUserName, values(WinGroup) as windowsGroupName, values(GroupRid_dec) as windowsGroupRID, values(UserName) as addedUserName, values(UserSid_readable) as addedUserSID by aid, falconPID
| where eventCount>1
| eval ProcExplorer=case(falconPID!="","https://falcon.us-2.crowdstrike.com/investigate/process-explorer/" .aid. "/" . falconPID)
| convert ctime(processStartTime)
| table processStartTime, aid, responsibleUserSID, responsibleUserName, responsibleFile, responsibleCmdLine, addedUserSID, addedUserName, windowsGroupRID, windowsGroupName, ProcExplorer
event_platform=win event_simpleName=ScheduledTask*
| table ContextTimeStamp_decimal ComputerName UserName event_simpleName TaskAuthor Task*
| convert ctime(ContextTimeStamp_decimal)
event_simpleName=RegGeneric* ComputerName=
| table _time, ComputerName, event_simpleName, RegObjectName, RegValueName, RegStringValue
| sort - _time
############################
# CROWDSTRIKE FALCON
# get commands run by scheduled tasks
cat scheduled_tasks.json | jq -r '.result[] | select(.Scheduled_Task_State=="Enabled") | .Task_To_Run'
# get
# count the scheduled tasks enabled
cat scheduled_tasks.json | jq -c '.result[] | select(.Scheduled_Task_State=="Enabled")' | wc -l
# get IOC DOMAINS
cat detections.json | jq -r '.result."DnsRequests{}.DomainName"' | sed '/^\[$/d' | sed '/^\]$/d' | sed '/^null$/d' | tr -d \" | tr -d , | sed 's/^[[:space:]]*//g' > ioc_doms.txt
cut -f2,3 -d. ioc_doms.txt | sort -u > ioc_top_doms.txt
# get IOC PUBLIC IPs
cat detections.json | jq -r '.result."NetworkAccesses{}.RemoteAddress"' | sed '/^\[$/d' | sed '/^\]$/d' | sed '/^null$/d' | tr -d \" | tr -d , | sed 's/^[[:space:]]*//g' | sort -u > ioc_ip.txt
# get IOC MD5 hashes
cat detections.json | jq -r '.result.MD5String,.result.IOCValue' | sort -u > ioc_md5sums.txt
# cat detections.json | jq -r '.result.MD5String' | sed '/^\[$/d' | sed '/^\]$/d' | sed '/^null$/d' | tr -d \" | tr -d , | sed 's/^[[:space:]]*//g' | sort -u > ioc_md5sums.txt
# get IOC Malware Filenames
cat detections.json | jq -r '.result.MD5String,.result.AssociatedFiles' | sort -u > ioc_filenames.txt
# get IOC Documents Accessed Filenames
cat detections.json | jq -r '.result.MD5String,.result."DocumentsAccessed{}.FileName"'
cat detections.json | jq -r '.result.MD5String,.result."DocumentsAccessed{}.FileName"' | grep '.*".*' | cut -d\" -f2 | sort -u > ioc_docs_accessed.txt
# get IOC Documents Accessed Paths
cat detections.json | jq -r '.result.MD5String,.result."DocumentsAccessed{}.FilePath"'
cat detections.json | jq -r '.result.MD5String,.result."DocumentsAccessed{}.FilePath"' | grep '.*".*' | cut -d\" -f2 | sort -u > ioc_docs_paths.txt
# get IOC Executable Written Filenames
cat detections.json | jq -r '.result.MD5String,.result."ExecutablesWritten{}.FileName"'
cat detections.json | jq -r '.result.MD5String,.result."ExecutablesWritten{}.FileName"' | grep '.*".*' | cut -d\" -f2 | sort -u > ioc_exes_written.txt
# get IOC Executable Written Paths
cat detections.json | jq -r '.result.MD5String,.result."ExecutablesWritten{}.FilePath"'
cat detections.json | jq -r '.result.MD5String,.result."ExecutablesWritten{}.FilePath"' | grep '.*".*' | cut -d\" -f2 | sort -u > ioc_exes_paths.txt