GoogleChronicle.psm1
#Region './Public/Get-GCCustomers.ps1' 0 function Get-GCCustomers { param ( [Parameter(Mandatory = $true)] $Auth, [string]$CustomerCode, [ValidateSet('europe', 'europe-west3', 'europe-west2', 'asia-southeast1', 'australia-southeast1', 'me-west1', 'united-states', 'europe-west6')] [string]$Region = 'asia-southeast1', [switch]$Details ) $ts = Test-GCAuthToken -Auth $Auth if (($ts.valid -eq $true -and $ts.minutes -le 5)) { Write-Host "The auth token is near expirty. Please renew it." -ForegroundColor Yellow break } elseif ($ts.valid -eq $false) { Write-Host "Token has expired. Please renew it." break } $endpoint = "https://$Region-backstory.googleapis.com" # No trailing slash $GetHeader = @{ "Authorization" = "Bearer $($Auth.token)"; "Accept" = "application/json" } if ($Details) { if (!$CustomerCode) { Write-Host "Google Chronicle CustomerCode is required." -ForegroundColor Yellow break } $uri = "$endpoint/v1/partner/customer/getcustomer?customer_code=$CustomerCode" try { $data = Invoke-RestMethod -Method Get -Headers $GetHeader -Uri $uri return $data } catch { $err = $_.ErrorDetails.Message | ConvertFrom-Json return $err.error } } else { $uri = "$endpoint/v1/partner/customer/listcustomers" try { $data = Invoke-RestMethod -Method Get -Headers $GetHeader -Uri $uri return $data } catch { $err = $_.ErrorDetails.Message | ConvertFrom-Json return $err.error } } } #EndRegion './Public/Get-GCCustomers.ps1' 55 #Region './Public/Get-GCDataFeeds.ps1' 0 function Get-GCDataFeeds { param ( [Parameter(Mandatory = $true)] $Auth, [ValidateSet('europe', 'europe-west3', 'europe-west2', 'asia-southeast1', 'australia-southeast1', 'me-west1', 'united-states', 'europe-west6')] [string]$Region = 'asia-southeast1' ) $ts = Test-GCAuthToken -Auth $Auth if (($ts.valid -eq $true -and $ts.minutes -le 5)) { Write-Host "The auth token is near expirty. Please renew it." -ForegroundColor Yellow break } elseif ($ts.valid -eq $false) { Write-Host "Token has expired. Please renew it." break } $endpoint = "https://$Region-backstory.googleapis.com" # No trailing slash $GetHeader = @{ "Authorization" = "Bearer $($Auth.token)"; "Accept" = "application/json" } $uri = "$endpoint/v1/feeds" try { $data = Invoke-RestMethod -Method Get -Headers $GetHeader -Uri $uri } catch { $data = $_.ErrorDetails.Message | ConvertFrom-Json } return $data } #EndRegion './Public/Get-GCDataFeeds.ps1' 36 #Region './Public/Get-GCRules.ps1' 0 function Get-GCRules { param ( [Parameter(Mandatory = $true)] $Auth, [ValidateSet('europe', 'europe-west3', 'europe-west2', 'asia-southeast1', 'australia-southeast1', 'me-west1', 'united-states', 'europe-west6')] [string]$Region = 'asia-southeast1', [int32]$PageSize = 100 ) if ($PageSize -gt 1000) { Write-host "Page size must be less than 1,000" -ForegroundColor Yellow break } $ts = Test-GCAuthToken -Auth $Auth if (($ts.valid -eq $true -and $ts.minutes -le 5)) { Write-Host "The auth token is near expirty. Please renew it." -ForegroundColor Yellow break } elseif ($ts.valid -eq $false) { Write-Host "Token has expired. Please renew it." break } $endpoint = "https://$Region-backstory.googleapis.com" # No trailing slash $GetHeader = @{ "Authorization" = "Bearer $($Auth.token)"; "Accept" = "application/json" } $uri = "$endpoint/v2/detect/rules?page_size=$PageSize" $completed = $null $Data = @() while (-not $completed) { try { $reqdata = Invoke-RestMethod -Method Get -Headers $GetHeader -Uri $uri $data += $reqdata.rules if ($null -eq $reqdata.rules) { $completed = $true Write-Verbose "No results found." $data = @{ "Status" = "error"; "Comment" = "No detections found"; } } $pagetoken = $reqdata.nextPageToken if ($null -eq $pagetoken) { $completed = $true Write-Verbose "No further results found." } $uri = "$endpoint/v2/detect/rules?page_size=$PageSize&page_token=$pagetoken" } catch { $err = $_.ErrorDetails.Message | ConvertFrom-Json if ($err.error.status -eq "RESOURCE_EXHAUSTED") { Write-Verbose "API limit hit - sleeping for 60 seconds" Start-Sleep 60 } else { $completed = $true return $err break } } } return $data } #EndRegion './Public/Get-GCRules.ps1' 69 #Region './Public/New-GCAuthToken.ps1' 0 function New-GCAuthToken { param ( [Parameter(Mandatory = $true)] $CredFile, [switch] $Inline, [switch] $Ingestion ) $ExpirationSeconds = 3600 # 1 hour in seconds $basedomain = "googleapis.com" $oauth2endpoint = "https://oauth2.googleapis.com/token" if ($Inline) { $Auth = $CredFile | ConvertFrom-Json } else { $Auth = gc $CredFile | ConvertFrom-Json } if ($null -eq $Auth ){ Write-host "No auth file detected." break } $PrivateKeyPem = $auth.private_key $ServiceAccount = $auth.client_email if ($Ingestion) { $Scope = "https://www.googleapis.com/auth/malachite-ingestion" } else { $Scope = "https://www.googleapis.com/auth/chronicle-backstory" } # Convert PEM to RSAParameters and then import $RSACryptoServiceProvider = New-Object System.Security.Cryptography.RSACryptoServiceProvider $RSAPrivateKey = [System.Security.Cryptography.RSA]::Create() $RSAPrivateKey.ImportFromPem($PrivateKeyPem) $RSACryptoServiceProvider.ImportParameters($RSAPrivateKey.ExportParameters($true)) # Create JWT Header $JwtHeader = '{"alg":"RS256","typ":"JWT"}' $JwtHeaderBase64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($JwtHeader)) $JwtHeaderBase64UrlEncoded = $JwtHeaderBase64 -replace "/", "_" -replace "\+", "-" -replace "=", "" # Create JWT claim $Now = (Get-Date).ToUniversalTime() $NowUnixTimestamp = [Math]::Floor([decimal](Get-Date -Date $Now -UFormat "%s")) $ExpirationUnixTimestamp = $NowUnixTimestamp + $ExpirationSeconds $JwtClaimSet = @" {"iss":"$ServiceAccount","scope":"$Scope","aud":"$oauth2endpoint","exp":$ExpirationUnixTimestamp,"iat":$NowUnixTimestamp} "@ $JwtClaimSetBase64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($JwtClaimSet)) $JwtClaimSetBase64UrlEncoded = $JwtClaimSetBase64 -replace "/", "_" -replace "\+", "-" -replace "=", "" # Sign the JWT $StringToSign = $JwtHeaderBase64UrlEncoded + "." + $JwtClaimSetBase64UrlEncoded $SHA256 = [System.Security.Cryptography.SHA256]::Create() $Hash = $SHA256.ComputeHash([Text.Encoding]::UTF8.GetBytes($StringToSign)) $SignatureBase64 = [Convert]::ToBase64String($RSACryptoServiceProvider.SignData([System.Text.Encoding]::UTF8.GetBytes($StringToSign), "SHA256")) $SignatureBase64UrlEncoded = $SignatureBase64 -replace "/", "_" -replace "\+", "-" -replace "=", "" # Get Access token from Google $Jwt = $JwtHeaderBase64UrlEncoded + "." + $JwtClaimSetBase64UrlEncoded + "." + $SignatureBase64UrlEncoded $Body = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=$Jwt" $AccessToken = Invoke-RestMethod -Method Post -Uri "$oauth2endpoint" -ContentType "application/x-www-form-urlencoded" -Body $Body $at = $AccessToken.access_token $tokendata = @{ "token" = "$at"; "expiry" = "$ExpirationUnixTimestamp"; "expires_in" = "$($AccessToken.expires_in)" } return $tokendata } #EndRegion './Public/New-GCAuthToken.ps1' 72 #Region './Public/New-GCCustomer.ps1' 0 function New-GCCustomer { param ( [Parameter(Mandatory = $true)] $Auth, [Parameter(Mandatory = $true)] [string] $CustomerCode, [Parameter(Mandatory = $true)] [ValidateSet('europe', 'europe-west3', 'europe-west2', 'asia-southeast1', 'australia-southeast1', 'me-west1', 'united-states', 'europe-west6')] [string]$Region, [Parameter(Mandatory = $true)] [string] $CustomerName ) $ts = Test-GCAuthToken -Auth $Auth if (($ts.valid -eq $true -and $ts.minutes -le 5)) { Write-Host "The auth token is near expirty. Please renew it." -ForegroundColor Yellow break } elseif ($ts.valid -eq $false) { Write-Host "Token has expired. Please renew it." break } $endpoint = "https://$Region-backstory.googleapis.com" # No trailing slash $PostHeader = @{ "Authorization" = "Bearer $($Auth.token)"; "Content-Type" = "application/json" } $uri = "$endpoint/v1/partner/customer/createcustomer" try { $Body = @{ "customer_name" = $CustomerName; "customer_code" = $CustomerCode; "customer_subdomains" = "$CustomerCode-$Region"; } | ConvertTo-Json Write-Host "This command can take upto 10 minutes to execute. Please be paitent." -ForegroundColor Yellow $data = Invoke-RestMethod -Method Post -Headers $PostHeader -Body $Body -Uri $uri -TimeoutSec 1200 return $data Write-Host "Customer $($data.response.customerCode) created." -ForegroundColor Green } catch { $err = $_.ErrorDetails.Message | ConvertFrom-Json return $err.error } } #EndRegion './Public/New-GCCustomer.ps1' 47 #Region './Public/New-GCRule.ps1' 0 function New-GCRule { param ( [Parameter(Mandatory = $true)] $Auth, [Parameter(Mandatory = $true)] $Content, [ValidateSet('europe', 'europe-west3', 'europe-west2', 'asia-southeast1', 'australia-southeast1', 'me-west1', 'united-states', 'europe-west6')] [string]$Region = 'asia-southeast1' ) $ts = Test-GCAuthToken -Auth $Auth if (($ts.valid -eq $true -and $ts.minutes -le 5)) { Write-Host "The auth token is near expirty. Please renew it." -ForegroundColor Yellow break } elseif ($ts.valid -eq $false) { Write-Host "Token has expired. Please renew it." break } $endpoint = "https://$Region-backstory.googleapis.com" # No trailing slash $PostHeader = @{ "Authorization" = "Bearer $($Auth.token)"; "Content-Type" = "application/json" } $DetectionBody = @{ "ruleText" = $Content } | Convertto-json $verifyuri = "$endpoint/v2/detect/rules:verifyRule" $newruleuri = "$endpoint/v2/detect/rules" try { $verify = Invoke-RestMethod -Method Post -Headers $PostHeader -Uri $verifyuri -Body $DetectionBody if ($verify.success -eq $true) { $newrule = Invoke-RestMethod -Method Post -Headers $PostHeader -Uri $newruleuri -Body $DetectionBody if ($newrule.compilationState -eq "SUCCEEDED") { $ruleid = $newrule.ruleId $status = @{ "Status" = $newrule.compilationState; "ruleName" = $newrule.ruleName; "RuleId" = $newrule.ruleId; } return $status } else { $status = @{ "Status" = "error"; "Error" = $newrule.compilationState; } return $status } } else { $status = @{ "Status" = "error"; "Error" = $verify.context; } return $status } } catch { $data = $_.ErrorDetails.Message | ConvertFrom-Json return $data } } #EndRegion './Public/New-GCRule.ps1' 69 #Region './Public/New-GCRuleVersion.ps1' 0 function New-GCRuleVersion { param ( [Parameter(Mandatory = $true)] $Auth, [Parameter(Mandatory = $true)] $Content, [ValidateSet('europe', 'europe-west3', 'europe-west2', 'asia-southeast1', 'australia-southeast1', 'me-west1', 'united-states', 'europe-west6')] [string]$Region = 'asia-southeast1', [Parameter(Mandatory = $true)] [string] $RuleId ) $ts = Test-GCAuthToken -Auth $Auth if (($ts.valid -eq $true -and $ts.minutes -le 5)) { Write-Host "The auth token is near expirty. Please renew it." -ForegroundColor Yellow break } elseif ($ts.valid -eq $false) { Write-Host "Token has expired. Please renew it." break } $endpoint = "https://$Region-backstory.googleapis.com" # No trailing slash $PostHeader = @{ "Authorization" = "Bearer $($Auth.token)"; "Content-Type" = "application/json" } $DetectionBody = @{ "ruleText" = $Content } | Convertto-json $verifyuri = "$endpoint/v2/detect/rules:verifyRule" $newruleuri = "$endpoint/v2/detect/rules/$($RuleId):createVersion" try { $verify = Invoke-RestMethod -Method Post -Headers $PostHeader -Uri $verifyuri -Body $DetectionBody if ($verify.success -eq $true) { $newrule = Invoke-RestMethod -Method Post -Headers $PostHeader -Uri $newruleuri -Body $DetectionBody if ($newrule.compilationState -eq "SUCCEEDED") { $ruleid = $newrule.ruleId $status = @{ "Status" = $newrule.compilationState; "ruleName" = $newrule.ruleName; "RuleId" = $newrule.ruleId; } return $status } else { $status = @{ "Status" = "error"; "Error" = $newrule.compilationState; } return $status } } else { $status = @{ "Status" = "error"; "Error" = $verify.context; } return $status } } catch { $data = $_.ErrorDetails.Message | ConvertFrom-Json return $data } } #EndRegion './Public/New-GCRuleVersion.ps1' 71 #Region './Public/Remove-GCRule.ps1' 0 function Remove-GCRule { param ( [Parameter(Mandatory = $true)] $Auth, [Parameter(Mandatory = $true)] $RuleId, [Parameter(Mandatory = $false)] [switch] $Recover, [ValidateSet('europe', 'europe-west3', 'europe-west2', 'asia-southeast1', 'australia-southeast1', 'me-west1', 'united-states', 'europe-west6')] [string]$Region = 'asia-southeast1' ) $ts = Test-GCAuthToken -Auth $Auth if (($ts.valid -eq $true -and $ts.minutes -le 5)) { Write-Host "The auth token is near expirty. Please renew it." -ForegroundColor Yellow break } elseif ($ts.valid -eq $false) { Write-Host "Token has expired. Please renew it." break } $endpoint = "https://$Region-backstory.googleapis.com" # No trailing slash $PostHeader = @{ "Authorization" = "Bearer $($Auth.token)"; "Content-Type" = "application/json" } if ($Recover) { $uri = "$endpoint/v2/detect/rules/$($RuleId):unarchive" } else { $uri = "$endpoint/v2/detect/rules/$($RuleId):archive" } try { $data = Invoke-RestMethod -Method Post -Headers $PostHeader -Uri $uri $status = @{ "Status" = "successful" "RuleId" = $RuleId } return $status } catch { $err = $_.ErrorDetails.Message | ConvertFrom-Json return $err.error } } #EndRegion './Public/Remove-GCRule.ps1' 50 #Region './Public/Set-GCRuleConfig.ps1' 0 function Set-GCRuleConfig { param ( [Parameter(Mandatory = $true)] $Auth, [Parameter(Mandatory = $true)] $RuleId, [Parameter(Mandatory = $false)] [switch] $EnableLiveRule, [Parameter(Mandatory = $false)] [switch] $DisableLiveRule, [Parameter(Mandatory = $false)] [switch] $EnableAlerting, [Parameter(Mandatory = $false)] [switch] $DisableAlerting, [ValidateSet('europe', 'europe-west3', 'europe-west2', 'asia-southeast1', 'australia-southeast1', 'me-west1', 'united-states', 'europe-west6')] [string]$Region = 'asia-southeast1' ) $ts = Test-GCAuthToken -Auth $Auth if (($ts.valid -eq $true -and $ts.minutes -le 5)) { Write-Host "The auth token is near expirty. Please renew it." -ForegroundColor Yellow break } elseif ($ts.valid -eq $false) { Write-Host "Token has expired. Please renew it." break } $endpoint = "https://$Region-backstory.googleapis.com" # No trailing slash $PostHeader = @{ "Authorization" = "Bearer $($Auth.token)"; "Content-Type" = "application/json" } $selectedSwitches = @($EnableLiveRule, $DisableLiveRule, $EnableAlerting, $DisableAlerting) | Where-Object { $_ } if ($selectedSwitches.Count -gt 1) { Write-Host "Select only 1 switch." -ForegroundColor Yellow } else { $action = switch ($selectedSwitches) { $EnableLiveRule { "enableLiveRule" } $DisableLiveRule { "disableLiveRule" } $EnableAlerting { "enableAlerting" } $DisableAlerting { "disableAlerting" } } if ($action) { $uri = "$endpoint/v2/detect/rules/$($RuleId):$action" } else { Write-Host "Invalid switch selected." -ForegroundColor Yellow break } } try { $data = Invoke-RestMethod -Method Post -Headers $PostHeader -Uri $uri $status = @{ "Status" = "Successful"; "RuleId" = "$RuleId"; "Action" = $action; } return $status } catch { $err = $_.ErrorDetails.Message | ConvertFrom-Json return $err } } #EndRegion './Public/Set-GCRuleConfig.ps1' 70 #Region './Public/Test-GCAuthToken.ps1' 0 function Test-GCAuthToken { param ( [Parameter(Mandatory = $true)] $Auth ) $TokenExpiryUtc = [System.DateTimeOffset]::FromUnixTimeSeconds($Auth.expiry).UtcDateTime $CurrentTimeUtc = Get-Date -AsUTC if ($CurrentTimeUtc -le $TokenExpiryUtc) { $timeRemaining = ($TokenExpiryUtc - $CurrentTimeUtc).TotalMinutes Write-Verbose "Token is still valid. Time remaining: $($timeRemaining) minutes" $data = @{ "Valid" = $true; "Minutes" = $timeRemaining; } } else { Write-Verbose "Token has expired. Please generate a new one." $data = @{ "Valid" = $false; "Minutes" = 0; } } return $data } #EndRegion './Public/Test-GCAuthToken.ps1' 26 #Region './Public/Update-GCRule.ps1' 0 function Update-GCRule { param ( [Parameter(Mandatory = $true)] $Auth, [Parameter(Mandatory = $true)] $Content, [Parameter(Mandatory = $true)] $RuleId, [ValidateSet('europe', 'europe-west3', 'europe-west2', 'asia-southeast1', 'australia-southeast1', 'me-west1', 'united-states', 'europe-west6')] [string]$Region = 'asia-southeast1' ) $ts = Test-GCAuthToken -Auth $Auth if (($ts.valid -eq $true -and $ts.minutes -le 5)) { Write-Host "The auth token is near expirty. Please renew it." -ForegroundColor Yellow break } elseif ($ts.valid -eq $false) { Write-Host "Token has expired. Please renew it." break } $endpoint = "https://$Region-backstory.googleapis.com" # No trailing slash $PostHeader = @{ "Authorization" = "Bearer $($Auth.token)"; "Content-Type" = "application/json" } $DetectionBody = @{ "ruleText" = $Content } | Convertto-json $verifyuri = "$endpoint/v2/detect/rules:verifyRule" $newruleuri = "$endpoint/v2/detect/rules/$($RuleId):createVersion" try { $verify = Invoke-RestMethod -Method Post -Headers $PostHeader -Uri $verifyuri -Body $DetectionBody if ($verify.success -eq $true) { $newrule = Invoke-RestMethod -Method Post -Headers $PostHeader -Uri $newruleuri -Body $DetectionBody if ($newrule.compilationState -eq "SUCCEEDED") { $ruleid = $newrule.ruleId $status = @{ "Status" = $newrule.compilationState; "ruleName" = $newrule.ruleName; "RuleId" = $newrule.ruleId; } return $status } else { $status = @{ "Status" = "error"; "Error" = $newrule.compilationState; } return $status } } else { $status = @{ "Status" = "error"; "Error" = $verify.context; } return $status } } catch { $err = $_.ErrorDetails.Message | ConvertFrom-Json return $err } } #EndRegion './Public/Update-GCRule.ps1' 71 |