Formatting Scripts - Threat Intel Management Guide - 6.9 - Cortex XSOAR - Cortex - Security Operations

Cortex XSOAR Threat Intel Management Guide

Product
Cortex XSOAR
Version
6.9
Creation date
2022-09-29
Last date published
2024-03-05
End_of_Life
EoL
Category
Threat Intel Management Guide
Abstract

Formatting scripts validate input and modify how indicators display.

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 XSOAR 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 XSOAR. 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 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 to SettingsOBJECTS SETUPIndicatorsTypes.

  2. Select the indicator type, click Edit.

  3. Select the desired formatting script.

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

Note

Formatting scripts for out-of-the-box indicator types are system level, which 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 reverts to content settings (empty).

Out-of-the-Box Formatting Script Examples

In the Automation page, there are a number of 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-input.png
Formatting Script Outputs

The indicators appear as a human readable format in Cortex XSOAR. 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.

Output Code Examples

Single-value result:

demisto.results([{
            "Type": entryTypes["note"],
            "ContentsFormat": formats["json"],
            "Contents": [format(indicator)],
            "EntryContext": {"Domain": format(indicator)}
        }])

Multiple-value results:

entries_list = []
    for indicator in argToList(demisto.args().get('input', ‘’)):
        input_entry = {
            "Type": entryTypes["note"],
            "ContentsFormat": formats["json"],
            "Contents": [format(indicator)],
            "EntryContext": {"Domain": format(indicator)}
        }
        if input_entry.get("Contents") == [""]:
            input_entry['Contents'] = []
        entries_list.append(input_entry)
    if entries_list:
        demisto.results(entries_list)
    else:
        # Return empty string so it wouldn't create an empty indicator.
        demisto.results('')

For more information about code conventions, see https://xsoar.pan.dev/docs/integrations/code-conventions#return_results.

Complete Formatting Script Example

In the following example, a prefix will be removed from the indicators.

def formatIndicator(indicator):
    return indicator.removeprefix('/')
    
# argToList returns the argument as is if it's already a list so no need to check here
the_input = argToList(demisto.args().get('input'))
entries_list = []
# Otherwise assumes it's already an array
for item in the_input:
    input_entry = {
        "Type": entryTypes["note"],
        "ContentsFormat": formats["json"],
        "Contents": [formatIndicator(item)],
        "EntryContext": {"Domain": item}
    }
    if input_entry.get("Contents") == ['']:
        input_entry['Contents'] = []
    entries_list.append(input_entry)
if entries_list:
    demisto.results(entries_list)
else:
    # Return empty string so it wouldn't create an empty domain indicator.
    demisto.results('')