Using Powershell to extract the Detections information from the Datalake

PowerShell script connecting to the Central API to collect all relevant detections (risk level > 6) from the xdr_ti_data table. The output is displayed in table format on the console, and we also create a CSV export of the information.

---------------------

By using or accessing the Software below, you agree to be bound by the terms of the Sophos End User License Agreement.

CentralAPI_XDR_Detections_Notification.ps1

<#
	Description: Check whether relevant detections (Risk Level > 6) are within Sophos Central
    Results are displayed in the console and exported to a CSV files
    Note: If you want to access all risk levels you should add the column detection_item to the console / CSV output
    
#>


cls
Write-Host("=================================================================")
Write-Host("Sophos Central XDR Detection Notification")
Write-Host("=================================================================`n")
Write-Host("This scripts automatically checks the Sophos Central Data Lake for relevant detections (Risk Level > 6) within your environment.`nIf detections are present, the scripts creates an output to the console and to a CSV file.`nUse this script as a starting point to add other functionality, e.g. sending notifications via E-mail.`n")
# Check if Central API Credentials have been stored, if not then prompt the user to add them
if ((Test-Path $env:userprofile\sophos_central_admin.json) -eq $false){
	# Prompt for Credentials
    Write-Host("=================================================================")
    Write-Host("Sophos Central API Authentication:")
    Write-Host("=================================================================")
	$clientId = Read-Host "Please Enter your Client ID"
	$clientSecret = Read-Host "Please Enter your Client Secret" -AsSecureString | ConvertFrom-SecureString

	# Out to JSON Config File
	ConvertTo-Json $ClientID, $ClientSecret | Out-File $env:userprofile\sophos_central_admin.json -Force
}

# Read Credentials from JSON Config File
$credentials = Get-Content $env:userprofile\sophos_central_admin.json | ConvertFrom-Json
$clientId = $credentials[0]
$clientSecret = $credentials[1] | ConvertTo-SecureString


# Create PSCredential Object for Credentials
$SecureCredentials = New-Object System.Management.Automation.PSCredential -ArgumentList $clientId , $clientSecret

#Write-Host("[API] Authenticate to Sophos Central...")

# SOPHOS OAuth URL
$TokenURI = "https://id.sophos.com/api/v2/oauth2/token"

# TokenRequestBody for oAuth2
$TokenRequestBody = @{
	"grant_type" = "client_credentials";
	"client_id" = $SecureCredentials.GetNetworkCredential().Username;
	"client_secret" = $SecureCredentials.GetNetworkCredential().Password;
	"scope" = "token";
}
$TokenRequestHeaders = @{
	"content-type" = "application/x-www-form-urlencoded";
}

# Set TLS Version
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# Post Request to SOPHOS OAuth2 token:
$APIAuthResult = (Invoke-RestMethod -Method Post -Uri $TokenURI -Body $TokenRequestBody -Headers $TokenRequestHeaders -ErrorAction SilentlyContinue -ErrorVariable ScriptError)

# If there's an error requesting the token, say so, display the error, and break:
if ($ScriptError) {
	Write-Output "FAILED - Unable to retreive SOPHOS API Authentication Token - $($ScriptError)"
	Break
}

# Set the Token for use later on:
$script:Token = $APIAuthResult.access_token

#Write-Host("[API] Get tenant details...")

# SOPHOS Whoami URI:
$WhoamiURI = "https://api.central.sophos.com/whoami/v1"

# SOPHOS Whoami Headers:
$WhoamiRequestHeaders = @{
	"Content-Type" = "application/json";
	"Authorization" = "Bearer $script:Token";
}

# Get Request SOPHOS Whoami Details:
$APIWhoamiResult = (Invoke-RestMethod -Method Get -Uri $WhoamiURI -Headers $WhoamiRequestHeaders -ErrorAction SilentlyContinue -ErrorVariable ScriptError)

# Set TenantID and ApiHost for use later on:
$script:ApiTenantId = $APIWhoamiResult.id
$script:ApiHost = $APIWhoamiResult.apiHosts.dataRegion	

# SOPHOS XDR API Headers:
$XDRAPIHeaders = @{
	"Authorization" = "Bearer $script:Token";
	"X-Tenant-ID" = "$script:ApiTenantId";
    "Content-Type" = "application/json";
}


if ($apihost -ne $null){

        
    ###################################################################################################################################
    # Check if detections are available in Sophos Central with Risk Level larger than 6
    ###################################################################################################################################
    Write-Host("`n=================================================================")
    Write-Host("[Data Lake] Check for detections with Risk Level > 6:")
    Write-Host("=================================================================")
    $vulnerableDevices = @()

    $XDR_Response = (Invoke-RestMethod -Method POST -Uri $script:ApiHost"/xdr-query/v1/queries/runs" -Headers $XDRAPIHeaders -Body '{ "adHocQuery": { "template": "SELECT ioc_detection_weight RISK, meta_hostname, ioc_detection_attack, ioc_detection_description, sophos_pid, detection_item, name, cmdline, calendar_time, username FROM xdr_ti_data WHERE ioc_detection_weight > 6 ORDER BY ioc_detection_weight DESC"
    }}')
                


    While ($XDR_Response.status -ne "finished") {
        start-sleep -s 1
        $XDR_Response = (Invoke-RestMethod -Method Get -Uri $script:ApiHost"/xdr-query/v1/queries/runs/$($XDR_Response.id)" -Headers $XDRAPIHeaders -ErrorAction SilentlyContinue -ErrorVariable ScriptError)   
    }

    if ($XDR_Response.result -eq "succeeded") {
        $XDR_Response = (Invoke-RestMethod -Method Get -Uri $script:ApiHost"/xdr-query/v1/queries/runs/$($XDR_Response.id)/results?maxSize=1000" -Headers $XDRAPIHeaders -ErrorAction SilentlyContinue -ErrorVariable ScriptError)   

        # Display results in the console
        $XDR_Response.items | Format-Table -Property RISK, meta_hostname, ioc_detection_attack, sophos_pid, name, calendar_time, username, cmdline
        # Store detections in a CSV file
        $XDR_Response.items | Export-Csv -Path $env:userprofile\detections.csv
    } else {
        Write-Output ("Request failed!")
        Write-Output ($XDR_Response)
    }

}