Formatting Script - Administrator Guide - Cortex XSIAM - Cortex - Security Operations

Cortex XSIAM Administrator Guide

Product
Cortex XSIAM
Creation date
2024-02-26
Last date published
2024-04-16
Category
Administrator Guide
Abstract

Add a formatting script to an indicator type using OOTB examples or by specifying your own the script input and output.

A formatting script has the following main functions:

  • Validating the input (for example, checking that the Top Level Domain (TLD) is valid).

  • Modifying how the indicator appears in Cortex such as the War Room, Reports, etc.

After indicators are extracted according to the defined regex, the defined regex finds the indicator value and the formatting script modifies the string value, so it can be used in Cortex XSIAM. For example the IP indicator uses the UnEscapeIPs formatting script, which removes any defanged characters from an IP address, such as 127[.]0[.]0[.]1 to 127.0.0.1. In the Alert War Room, you can click on the IP address to view the extracted IP address. This extracted indicator using the formatting script is added to the Threat Intel database.

To apply a formatting script to an indicator type: .

  1. Go toSettingsConfigurationsObject SetupIndicatorsTypes.

  2. Select the indicator type, and click Edit.

  3. Select the desired formatting script.

    Formatting scripts must have the indicator-format tag applied to appear in the list.

Note

Formatting scripts for out-of-the-box indicator types are system level. This means that the formatting scripts for these indicator types are not configurable. To create a formatting script for an out-of-the-box indicator type, you need to disable the existing indicator type and create a new (custom) indicator type. If you configured a formatting script before this change and updated your content, this configuration will revert to content settings (empty).

Out-of-the-box Formatting Script Examples

In the Scripts page, there several out-of-the-box formatting scripts, including:

  • UnEscapeIPs

  • ExtractDomainAndFQDNFromUrlAndEmail

    This script is used by the Domain indicator, extracts domains and FQDN from URLs and emails. It removes prefixes such as proofpoint or safelinks, removes escaped URLs, and extracts the FQDN, etc.

  • ExtractEmailV2

CLI Execution Examples
  • !UnEscapeIPs input=127.0.0[.]1

  • !UnEscapeIPs input=127.0.0[.]1,8.8.8[.]8

  • !UnEscapeIPs input=${contextdata.indicators} (where the key contextdata.indicators in the context object, is an array)

Formatting Script Input

The formatting script requires a single input argument named input that accepts a single indicator value or an array of indicator values. The input argument should be an array to accept multiple inputs and return an entry-result per input.

Argument

Description

input

Accepts a string or array of strings representing the indicator value(s) to be formatted. Will be accessed within the script using demisto.args().get(‘input’, []).

In the script settings, the Is Array checkbox must be checked (see screenshot below).The script code must be able to handle a single indicator value (as string), multiple indicator values in CSV format (as string) and an array of single indicator values (array).

formatting-8-input.png
Formatting Script Outputs

The indicators appear as a human readable format in Cortex XSIAM. The output should be an array of formatted indicators or an array of entry results (an entry result per indicator to be created). The entry result per input can be a JSON array to create multiple indicators. If the entry result is an empty string, it is ignored and no indicator is created.

Use the return_results function to generate the script output. For more information, see https://xsoar.pan.dev/docs/integrations/code-conventions#return_results.

Output Code Examples

Single-value result:

results = CommandResults(
    outputs_prefix='VirusTotal.IP',
    outputs_key_field='Address',
    outputs={
        'Address': '8.8.8.8',
        'ASN': 12345
    }
)
return_results(results)

Multiple-value results:

results = [
    CommandResults(
        outputs_prefix='VirusTotal.IP',
        outputs_key_field='Address',
        outputs={
            'Address': '8.8.8.8',
            'ASN': 12345
        }
    ), 
    CommandResults(
        outputs_prefix='VirusTotal.IP',
        outputs_key_field='Address',
        outputs={
            'Address': '1.1.1.1',
            'ASN': 67890
        }
    )]
return_results(results)

Complete Formatting Script Example

In the following example, the RemoveEmpty script removes empty items, entries, or nodes from an array.

// pack version: 1.2.30
const EMPTY_TOKENS = argToList(args.empty_values);

function toBoolean(value) {
    if (typeof(value) === 'string') {
        if (['yes', 'true'].indexOf(value.toLowerCase()) != -1) {
            return true;
        } else if (['no', 'false'].indexOf(value.toLowerCase()) != -1) {
            return false;
        }
        throw 'Argument does not contain a valid boolean-like value';
    }
    return value ? true : false;
}

function isObject(o) {
    return o instanceof Object && !(o instanceof Array);
}

function isEmpty(v) {
    return (v === undefined) ||
           (v === null) ||
           (typeof(v) == 'string' && (!v || EMPTY_TOKENS.indexOf(v) !== -1)) ||
           (Array.isArray(v) && v.filter(x => !isEmpty(x)).length === 0) ||
           (isObject(v) && Object.keys(v).length === 0);
}

function removeEmptyProperties(obj) {
    Object.keys(obj).forEach(k => {
        var ov = obj[k];
        if (isObject(ov)) {
            removeEmptyProperties(ov);
        } else if (Array.isArray(ov)) {
            ov.forEach(av => isObject(av) && removeEmptyProperties(av));
            obj[k] = ov.filter(x => !isEmpty(x));
        }
        if (isEmpty(ov)) {
            delete obj[k];
        }
    });
}

var vals = Array.isArray(args.value) ? args.value : [args.value];

if (toBoolean(args.remove_keys)) {
    vals.forEach(v => isObject(v) && removeEmptyProperties(v));
}
return vals.filter(x => !isEmpty(x));