Airgap scans with the API in PowerShell

Use of the scripts requires authentication by following this process.

In case the TLS certificate of the Cyberwatch server cannot be recognized by the machine running this script, it is necessary to execute the following code snippet before those snippets:

add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

Scans Airgap Scripts + Usage

  1. Retrieve the Scans Airgap download script and the Upload script, fill in the $API_URL and $CREDENTIALS variables.

  2. After executing the download script, a scripts folder is created that contains the scripts to generate results.

  3. To execute the scripts, you must move the scripts folder itself to the asset you want to analyze and run the run script. To avoid any risk of executing an undesirable script, take the folder itself, not just its contents.
    Linux: bash ./run.sh > result.txt
    PowerShell: .\run.ps1 | Out-File -Encoding ASCII -FilePath result.txt\

    This will create an result.txt file with the result. Then move result.txt to the uploads folder on the system with the Upload script.

  4. Send the script results present in the uploads folder with the Upload script.

Download script for Scans Airgap

Display the script source code
# -------------------------------------
# CONFIGURATION
# Please check and complete these items
# -------------------------------------

$API_URL = ""
$CREDENTIALS = "access_key:secret_key"

# -------------------------
# RUN
# -------------------------

Write-Output "-------------------------------------------"
Write-Output "Cyberwatch - Get Airgap scripts"
Write-Output "-------------------------------------------"

$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($CREDENTIALS))

Function FetchImporterScripts
{
<#
.SYNOPSIS
        Example script to fetch Importer scanning scripts
#>


Write-Output "-------------------------------------------"
Write-Output "Cyberwatch - Fetch scanning scripts for Importer"
Write-Output "-------------------------------------------"

Write-Output "Would you like to download scripts attachments like .cab file? (Default is Yes)"
    $Readhost = Read-Host " ( y / n ) "
    Switch ($ReadHost)
     {
       Y {Write-Output "Yes, download attachments"; $DownloadAttachments=$true}
       N {Write-Output "No, skip attachments"; $DownloadAttachments=$false}
       Default {Write-Output "Default, download attachments"; $DownloadAttachments=$true}
     }

  # Test the client connection
  Write-Output "INFO: Checking API connection and credentials..."
  try {
    $response = Invoke-WebRequest -URI $API_URL/api/v3/ping -Method Get -Headers @{
      "Accept"      = "application/json; charset=utf-8"
      Authorization = "Basic $encodedCreds"
    }

    $response.Content
  }
  catch {
    Write-Output "ERROR: Connection failed. Please check the following error message : '$_'"
    Return
  }


# Clean old files
Write-Output "INFO: Cleaning old files..."
Remove-Item -LiteralPath ".\scripts" -Force -Recurse -ErrorAction Ignore
Write-Output "INFO: Done."

# Create the base folders
New-Item -path ".\scripts" -Force -ItemType Directory | Out-Null
New-Item -path ".\uploads" -Force -ItemType Directory | Out-Null

# Fetch available scanning scripts from the API
Write-Output "INFO: Fetching available scanning scripts..."

# Fetch available scanning scripts from the API
Write-Output "INFO: Fetching available scanning scripts..."
$response = Invoke-RestMethod -URI "$API_URL/api/v2/cbw_scans/scripts" -Method Get -Headers @{
"Accept"      = "application/json; charset=utf-8"
Authorization = "Basic $encodedCreds"
}

Write-Output $response


# Fetch content of each scripts and attachments
$response | ForEach-Object{
    Write-Output "INFO: Fetching content for $($_.Type) ..."
    $id = ($_.id)
    $scanning_script = Invoke-RestMethod -URI "$API_URL/api/v2/cbw_scans/scripts/$id" -Method Get -Headers @{
        "Accept"      = "application/json; charset=utf-8"
        Authorization = "Basic $encodedCreds"
        }

        Write-Output $scanning_script
    
    $scanning_script_path = ".\"+$scanning_script.type.ToLower().replace("::", "\")

    if ($scanning_script.type -like '*Linux*') {
        $scanning_script_path = $scanning_script_path + '.sh'

    } elseif ($scanning_script.type -like '*Windows*') {
        $scanning_script_path = $scanning_script_path + '.ps1'
    }

    $scanning_script.contents | New-Item -path $scanning_script_path -Force -ItemType File | Out-Null

    if($scanning_script.attachment -And $DownloadAttachments) {
        $attachment_name  = ($scanning_script.attachment -split '/')[-1]
        $path = $scanning_script_path.SubString(0, $scanning_script_path.LastIndexOf('\')) + '\' + $attachment_name
        Invoke-WebRequest -Uri $scanning_script.attachment -OutFile $path
    }

    Write-Output "INFO: Script saved at $($(Resolve-Path -Path $scanning_script_path).Path)."
}

$SH_EXECUTE_SCRIPT = '#!/bin/bash
set -eu

readonly DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"

# Define priority scripts
declare -a priority_scripts=("infoscript.sh" "dockerimagesscansscript.sh")

# Execute priority scripts first
for script in "${priority_scripts[@]}"; do
    script_path="$DIR/$script"
    if [[ -f "$script_path" ]]; then
        chmod +x "$script_path"
        >&2 printf "Executing %s..." "$script_path"
        ( "$script_path" || >&2 echo "Error" ; ) && >&2 echo "Done"
    fi
done

# Execute all other scripts
for script in $(find "$DIR" -name "*.sh" -not -name "run.sh" -not -name "infoscript.sh" -not -name "dockerimagesscansscript.sh"); do
    chmod +x "$script"
    >&2 printf "Executing %s..." "$script"
    ( "$script" || >&2 echo "Error" ; ) && >&2 echo "Done"
done
'

$SH_EXECUTE_SCRIPT | New-Item -path ".\scripts\docker\run.sh" -Force -ItemType File | Out-Null
$SH_EXECUTE_SCRIPT | New-Item -path ".\scripts\linux\run.sh" -Force -ItemType File | Out-Null

$PS1_EXECUTE_SCRIPT = '
$ScriptDir = Split-Path $MyInvocation.MyCommand.Path

# Execute priority script first
$priorityScript = "$ScriptDir\InfoScript.ps1"
if (Test-Path $priorityScript) {
    & $priorityScript
}

# Execute all other scripts
$scripts = Get-ChildItem -Path $ScriptDir -Filter "*.ps1" | Where-Object { $_.Name -ne "run.ps1" -and $_.Name -ne "InfoScript.ps1" }

foreach ($script in $scripts) {
    & "$ScriptDir\$script"
}
'

$PS1_EXECUTE_SCRIPT | New-Item -path ".\scripts\windows\run.ps1" -Force -ItemType File | Out-Null

Write-Output "---------------------------------------------------------------------"
Write-Output "Script completed!"
Write-Output "To continue, please now:"
Write-Output "1) Run the fetched scripts on the targeted systems"
Write-Output "2) Put the result.txt in the 'upload' folder"
Write-Output "3) Run the 'upload' script"
Write-Output "---------------------------------------------------------------------"
  
}

Upload script for Scans Airgap

Display the script source code
# -------------------------------------
# CONFIGURATION
# Please check and complete these items
# -------------------------------------

$API_URL = ""
$CREDENTIALS = "access_key:secret_key"

# -------------------------
# RUN
# -------------------------

Write-Output "-------------------------------------------"
Write-Output "Cyberwatch - Send results for analysis"
Write-Output "-------------------------------------------"

$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($CREDENTIALS))


Function SendResultsImporter
{
<#
.SYNOPSIS
        Script to send Importer scanning scripts results
#>

# Test the client connection
try {
    $response = Invoke-WebRequest -URI $API_URL/api/v3/ping -Method Get -Headers @{
        "Accept"      = "application/json; charset=utf-8"
        Authorization = "Basic $encodedCreds"
    }

    $response.Content
}
catch {
    Write-Output "ERROR: Connection failed. Please check the following error message : '$_'"
    Return
}

# Load results and send them to Cyberwatch
Write-Output "INFO: Searching for available results..."
$available_results = Get-ChildItem -Recurse -File -Path ".\uploads"
Write-Output "INFO: Done. Found $($available_results.count) results to be processed and sent for analysis."

$available_results | ForEach-Object {
    Write-Output "INFO: Reading $($_.FullName) content..."
    $content = [IO.File]::ReadAllText($_.FullName)
    Write-Output "INFO: Sending $($_.FullName) content to the API..."
    $body_content = @{ output = $content } | ConvertTo-Json
    Write-Output $body_content
    $response = Invoke-WebRequest -URI $API_URL/api/v2/cbw_scans/scripts -Method POST -Body $body_content -Headers @{
        "Accept"      = "application/json; charset=utf-8"
        "Content-Type" = "application/json"
        Authorization = "Basic $encodedCreds"
    }
    Write-Output "INFO: Done."
}

Write-Output "---------------------------------------------------------------------"
Write-Output "Script completed!"
Write-Output "Your scans are now being processed by your Cyberwatch nodes."
Write-Output "Please log on $API_URL to see the results."
Write-Output "---------------------------------------------------------------------"

}

SendResultsImporter