AlphaSOC Network Behavior Analytics

Retrieve alerts from the AlphaSOC Analytics Engine.

Analytics & SIEM · AlphaSOC Network Behavior Analytics

Details

IDAlphaSOC Network Behavior Analytics
ProviderAlphaSOC
CategoryAnalytics & SIEM
From Version5.0.0
Supported ModulesAgentix XSIAM

README

Overview


Use the AlphaSOC Network Behavior Analysis integration to instantly retrieve alerts from the AlphaSOC Analytics Engine (either from the cloud or an on-premise instance).

Network telemetry is sent to AlphaSOC (primarily DNS and IP events) from Network Behavior Analytics for Splunk, Network Flight Recorder, or direct API integrations, processed, and alerts generated. AlphaSOC is able to flag infected hosts, policy violations, anomalies, and threats requiring attention.

 

The AlphaSOC Analytics Engine is free to evaluate without restriction for 30 days and you can instantly create an API key within Network Flight Recorder or our Splunk apps to evaluate and use the service.

 

Configure the AlphaSOC Network Behavior Analysis Integration on Cortex XSOAR


  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for AlphaSOC Network Behavior Analysis.
  3. Click Add instance to create and configure a new integration instance.
    • Name: a textual name for the integration instance.
    • AlphaSOC Analysis Engine URL: efaults to cloud.
    • AlphaSOC Analysis API Key:your AlphaSOC API key.
  4. Click Test to validate the API key and connection.

 

Tune the Integration


Within the settings, the Ignore events below severity field defaults to 3 and is used to filter the content that you are loading into Cortex XSOAR from AlphaSOC. The severity values we use are as follows:

  • 5 (critical)
  • 4 (high)
  • 3 (medium)
  • 2 (low)
  • 1 (informational).

Critical and high severity alerts include C2 callbacks, ransomware, cryptomining, DNS tunneling, port scanning, DGA traffic, and phishing traffic.

Medium severity alerts have lower fidelity and include beaconing to a suspicious domain, ICMP tunneling, and policy violations, for example, P2P activity, third-party VPN use, potentially unwanted programs or browser extensions present. We recommend leaving this field set to 3, but if you only want to load high-fidelity / high-confidence details of infected hosts into Cortex XSOAR, you can set this to 4.

The Include policy violations field defaults to true and can be set to false if you wish to suppress alerting of items that indicate poor hygiene within the environment, such as potentially unwanted programs (PUPs), unwanted browser extensions, P2P applications (such as BitTorrent), third-party VPN utilities, and remote access software, for example TeamViewer and GoToMyPC.

 

Test the Integration


When you have telemetry flowing into the AlphaSOC Analytics Engine and the Cortex XSOAR integration configured, you can synthesize malicious traffic and generate alerts for threats including C2 callbacks, DNS tunneling, DGA traffic, and port scanning using our open source Network Flight Simulator utility.

The utility is available for both Windows and Linux, and will generate malicious traffic that in-turn will create incidents within Cortex XSOAR. If you click into the Incidents view, you can review the list.

Configuration parameters

  • server — AlphaSOC Analytics Engine URL (required)
  • APIKey — AlphaSOC API Key (required)
  • severity — Ignore events below severity (required)
  • policy — Include policy violations
  • proxy — Use system proxy settings
  • insecure — Trust any certificate (not secure)
  • isFetch — Fetch incidents
  • incidentType — Incident type
  • incidentFetchInterval — Incidents Fetch Interval

Commands (0)

This integration defines no commands.

var API_PATH_ALERTS = '/v1/alerts';

var SERVER = params.server.replace(/[\/]+$/, '');
var API_KEY = params.APIKey;

var INSECURE = params.insecure;
var PROXY = params.proxy;

var INCLUDE_POLICY = params.policy;
var SEVERITY = params.severity;

function sendRequest(requestUrl) {
    logInfo('Sending HTTP request to: ' + requestUrl);

    var response = http(
        requestUrl,
        {
            Method: 'GET',
            Headers: {
                Authorization: ['Basic ' + btoa(API_KEY + ':')],
                Accept: ['application/json']
            }
        },
        INSECURE,
        PROXY
    );

    var errorString = validateRequestResponse(requestUrl, response);
    if (errorString) {
        throw errorString;
    }

    try {
        return JSON.parse(response.Body);
    } catch (err) {
        throw 'Failed to parse JSON response: ' + response.Body;
    }
};

function validateRequestResponse(requestUrl, response) {
    if (!response) {
        return 'Error: Unexpected HTTP response\n\nRequest URL: ' + requestUrl;
    } else if (response.StatusCode < 200 || response.StatusCode >= 300) {
        var errorString = '';

        if (response.StatusCode === 401 || response.StatusCode === 403) {
            errorString = 'Error: Invalid API key\n';
        } else if (response.StatusCode === 429) {
            errorString = 'Error: Too many requests\n';
        }

        try {
            var body = JSON.parse(response.Body);
            if (body && body.message) {
                errorString += '\nMessage: ' + JSON.stringify(body.message);
            }
        } catch (err) {
            errorString += '\nCould not parse response body';
        }

        errorString += '\nRequest URL: ' + requestUrl + '\nStatus code: ' + response.StatusCode;
        return errorString;
    }

    return null;
}

function createAlertsURL(follow) {
    var severity = getSeverityThereshold();
    return SERVER + API_PATH_ALERTS + '?follow=' + follow + '&threats=all&minSeverity=' + severity;
}

function parseFollow() {
    var lastRun = getLastRun();
    return lastRun && lastRun.follow ? lastRun.follow : '0';
}

function saveFollow(follow) {
    if (follow) {
        setLastRun({ follow: follow });
    }
}

function testGetAlerts() {
    var response = sendRequest(createAlertsURL('0'));
    return response && response.alerts ? true : false;
}

function getAlerts(follow) {
    var response = sendRequest(createAlertsURL(follow));

    return {
        follow: response.follow,
        content: response.alerts,
        threats: response.threats
    }
}

function appendIncidentsFromAlert(incidents, alert, threats) {
    if (!threats || !alert || !alert.threats) {
        logInfo('Invalid alert format or empty threats definition');
        return;
    }

    var occurredTs = getOccurredTs(alert);
    for (var i = 0; i < alert.threats.length; i++) {
        var threatId = alert.threats[i];

        var threat = threats[threatId];
        if (!threat) {
            logInfo('Error: Invalid alert content. Definition for threat "' + threatId + '" not found');
            continue;
        }

        if (inScope(threat.severity, threat.policy)) {
            alert.policy = threat.policy === true ? true : false;

            incidents.push({
                'name': threat.title,
                'occurred': occurredTs,
                'severity': convertSeverity(threat.severity),
                'labels': getLabels(alert),
                'rawJSON': JSON.stringify(alert)
            });
        }
    }
}

function getOccurredTs(alert) {
    try {
        return alert.event.ts;
    } catch (exc) {
        return null;
    }
}

function getLabels(alert) {
    var labels = [];
    if (!alert) {
        return labels;
    }

    if (alert.eventType) {
        labels.push(createLabelEntry('eventType', alert.eventType));
    }

    if (alert.policy !== undefined && alert.policy !== null) {
        labels.push(createLabelEntry('policy', alert.policy));
    }

    if (alert.event) {
        var eventKeys = Object.keys(alert.event);
        for (var i = 0; i < eventKeys.length; i++) {
            var eventKey = eventKeys[i];
            if (eventKey !== 'ts') {
                labels.push(createLabelEntry(eventKey, alert.event[eventKey]));
            }
        }
    }

    if (alert.wisdom) {
        var wisdomKeys = Object.keys(alert.wisdom);
        for (var i = 0; i < wisdomKeys.length; i++) {
            var wisdomKey = wisdomKeys[i];
            labels.push(createLabelEntry('wisdom.' + wisdomKey, alert.wisdom[wisdomKey]));
        }
    }

    return labels;
}

function createLabelEntry(key, value) {
    return { 'type': key, 'value': String(value) };
}

function inScope(severity, policy) {
    var severityThereshold = getSeverityThereshold();
    if (!severity || severity < severityThereshold) {
        return false;
    }

    if (policy === true && !INCLUDE_POLICY) {
        return false;
    }

    return true;
}

function convertSeverity(severity) {
    var demistoSeverity = 0;

    try {
        demistoSeverity = severity === 1 ? .5 : severity - 1;
    } catch (exc) {
        demistoSeverity = 0;
    }

    return demistoSeverity < 0 || demistoSeverity > 4 ? 0 : demistoSeverity;
}

function getSeverityThereshold() {
    try {
        var severity = parseInt(SEVERITY);
    } catch (exc) {
        var severity = NaN;
    }

    if (isNaN(severity) || severity > 5) {
        throw 'Error: Invalid severity parameter. Please provide a number in range 0-5.';
    }

    return severity < 0 ? 0 : severity;
}

switch (command) {
    case 'test-module':
        try {
            getSeverityThereshold();
            return testGetAlerts() === true ? 'ok' : 'not ok';
        } catch (exc) {
            return String(exc);
        }
    case 'fetch-incidents':
        var follow = parseFollow();
        var alerts = getAlerts(follow);

        var incidents = [];
        if (alerts && alerts.content) {
            for (var i = 0; i < alerts.content.length; i++) {
                appendIncidentsFromAlert(incidents, alerts.content[i], alerts.threats);
            }
        }

        saveFollow(alerts.follow);
        return JSON.stringify(incidents);
}