Fortinet black logo

User Guide

Custom Windows CounterMeasures actions

24.2.0
Copy Link
Copy Doc ID af1daa65-c273-11ec-9fd1-fa163e15d75b:87128
Download PDF

Custom Windows CounterMeasures actions (FortiMonitor Agent)

You can create custom CounterMeasure actions for Windows using JSON or PowerShell. In most cases, a CounterMeasure created using JSON will be sufficient. For more advanced or complex use cases, you have the option to use PowerShell.

Here are some basic CounterMeasure actions that you can create using JSON:

  • Information gathering commands (Test-NetConnection –TraceRoute, Get-NetTCPConnection, etc.)

  • Restarting a service or server

  • Deleting files

Create CounterMeasure actions using JSON

To create custom Windows CounterMeasures using JSON, create a new JSON file in the C:\Program Files (x86)\FortimonitorAgent\cm_ps_plugins directory. The command provided in the `command` key-value will be executed when the CounterMeasure is triggered. The command's output (if any) will be returned and available in the FortiMonitor Control Panel. The following example shows a JSON CounterMeasure that returns the output of a Get-ChildItem command.

{
"name": "Detailed Dir List",
"textkey": "info.detailed_dir_list",
"description": "Returns a detailed list of the current directory",
"max_frequency": 60,
"max_runtime": null,
"author": "testing@fortinet.com",
"command": "Get-ChildItem -Path C:\\Test"
}

For more details, see Plugin-Configuration Properties. Keep in mind that the command will be run as the fm-agent user.

Create CounterMeasure actions using PowerShell

To create your own CounterMeasure:

  1. Create a new .ps1 file in the C:\Program Files (x86)\FortimonitorAgent\cm_ps_plugins directory. At a minimum, your CounterMeasure needs to implement two functions - Plugin-Configuration, which provides config and metadata about your CounterMeasure and Execute, which is the driver for your CounterMeasure.

  2. Check for syntax errors by running the script in the PowerShell ISE. If the syntax is correct, the execution should not generate any output or error message. If your CounterMeasure has syntax errors, it will not be added to the control panel.

  3. Rebuild your agent metadata via the instance's details page in the FortiMonitor control panel. Your custom plugin will then be available in the FortiMonitor control panel.

CustomCounterMeasure.ps1

function Plugin-Configuration {
$properties = @{}
#Required: a name for your custom CounterMeasure
$properties.add("name", "My Custom CounterMeasure")
#Required: a description of your custom CounterMeasure
$properties.add("description", "Returns the current dir list")
#Required: a distinct textkey for your custom CounterMeasure
$properties.add("textkey", "Fortimonitor.ListDirectoryCM")
#Required: the name of the CounterMeasure Author
$properties.add("author", "Fortimonitor.HeadDeveloper")
#Optional: The maximum frequency at which a CounterMeasure can run
$properties.add("max_frequency", "60")
# Required
return $properties
}
function Execute {
# The Metadata param will receive information about the incident the CM is responding to
param([hashtable]$metadata)
# Dictionary to to hold the returned CM payload - you can name this anything
$returndata = @{}
# Dictionary to hold each chunk of information you want to return - you can name this anything
$output = @{}
# Array to hold your 1..n dictionaries of output - you can name this anything
$output_list = New-Object System.Collections.ArrayList
# Required: either success or error. key must be return_code
$returndata.add("return_code", "success")
# Required: output type the data you are returning. either text or html. key must be format
$output.add("format", "text")
# Required: output content. key must be format
$output.add("output", "$(Get-ChildItem | Format-Table -Property Name, Length | Out-String)")
# add your output chunks to your array
$output_list.add($output);
# add your array to your top-level dictionary. key must be output
$returndata.add("output", $output_list)
# return your countermeasure data
return $returndata
}

Leveraging Incident Data

When the agent is notified that it should run a local CounterMeasure action, it receives metadata about the incident triggering the CounterMeasure. This metadata object is available to you in your code via the metadata parameter. For example, the below code just returns the incident metadata right back to FortiMonitor.

CounterMeasure return metadata

function Plugin-Configuration {

$properties = @{}

$properties.add("name", "Return mmeta")

$properties.add("description", "Returns the invoking incident's md")

$properties.add("textkey", "Fortimonitor.MetadataCM")

$properties.add("author", "Fortimonitor.HeadDeveloper")

return $properties

}

function Execute {

# The Metadata param will receive information about the incident the CM is responding to

param([hashtable]$metadata)

$returndata = @{}

$output = @{}

$output_list = New-Object System.Collections.ArrayList

$returndata.add("return_code", "success")

$output.add("format", "text")

$output.add("output", metadata)

$output_list.add($output);

$returndata.add("output", $output_list)

return $returndata

}

This is helpful as it allows you to take action based on certain criteria, such as which application or metrics triggered the incident. The payload scheme is included below. The hashtable properties are listed in the table below:

CounterMeasures incident metadata

Items in the incident metadata can be accessed from the $metadata variable.

Key

Description

$metadata.outage_id

The ID number of the associated incident.

$metadata.outage_alert_label

Alert label of the incident/anomaly.

$metadata.outage_timestamp

UTC timestamp of when the incident/clear occurred.

$metadata.outage_severity

The severity of the outage/anomaly, either "critical" or "warning".

$metadata.outage_reasons

The reason for the outage.

$metadata.server_id

The ID number of the server experiencing the incident/clear.

$metadata.server_server_key

The server key for the server.

$metadata.server_fqdn

The fully qualified domain name of the server experiencing the incident/clear.

$metadata.server_name

Name of the server experiencing the incident/clear.

$metadata.server_tags

The tags for the server.

$metadata.server_partner_server_id

The partner server ID for the server.

$metadata.metrics

Services experiencing the incident/clear or resources experiencing the anomaly/clear.

$metadata.metric_tags

The tags for all of the metrics involved in the outage.

$metadata.resource

For resource anomalies: resources experiencing the anomaly/clear.

$metadata.resource_item_type

The server resource item type.

$metadata.resource_name

The server resource name.

$metadata.resource_resource_option

if your metric utilizes an option, such as the mount point, NIC, or disk drive, it will be present here.

$metadata.services

For service incident: services experiencing the incident/clear.

Plugin-Configuration Properties

Parameters

Type

Description

Required

name

String

A human-readable name for the CounterMeasure, will be displayed in the control panel and alerts

Yes

author

String

Identifier of the author (recommended to be your email address)

Yes

textkey

String

Unique identifier for the CounterMeasure, should be lowercase letters, numbers, underscores, and periods. No spaces allowed

Yes

description

String

Description of the countermeasure, for display at the command line and in the FortiMonitor control panel

Yes

max_frequency

String

The shortest allowed time between two executions of this plugin, in seconds. If less than that time has elapsed, the second execution won't be performed. Leave set to None to disable frequency checks

No

Execute Properties

The Execute function returns a dictionary, which contains two things: the CounterMeasure execution status and an array of output items. You can name the returned dictionary whatever you like, but for clarity, we'll use the property name $returndata.

Parameter

Type

Description

Required

ReturnData["return_code"]

String

Execution status of the CounterMeasure - either success or error

Yes

ReturnData[outputs_list]

Array of Dictionaries

An array output chunks that you'd like returned for viewing in the FortiMonitor control panel

Yes

outputs_list["format"]

String

Either text or HTML

Yes

outputs_list["output"]

String

Output to be returned

Yes

Plugin Functions

Function

Parameters

Description

Required

Execution

none

Executes the countermeasure action

Yes

Plugin-Configuration

none

Returns CounterMeasure plugin configuration information

Yes


Custom Windows CounterMeasures actions (FortiMonitor Agent)

You can create custom CounterMeasure actions for Windows using JSON or PowerShell. In most cases, a CounterMeasure created using JSON will be sufficient. For more advanced or complex use cases, you have the option to use PowerShell.

Here are some basic CounterMeasure actions that you can create using JSON:

  • Information gathering commands (Test-NetConnection –TraceRoute, Get-NetTCPConnection, etc.)

  • Restarting a service or server

  • Deleting files

Create CounterMeasure actions using JSON

To create custom Windows CounterMeasures using JSON, create a new JSON file in the C:\Program Files (x86)\FortimonitorAgent\cm_ps_plugins directory. The command provided in the `command` key-value will be executed when the CounterMeasure is triggered. The command's output (if any) will be returned and available in the FortiMonitor Control Panel. The following example shows a JSON CounterMeasure that returns the output of a Get-ChildItem command.

{
"name": "Detailed Dir List",
"textkey": "info.detailed_dir_list",
"description": "Returns a detailed list of the current directory",
"max_frequency": 60,
"max_runtime": null,
"author": "testing@fortinet.com",
"command": "Get-ChildItem -Path C:\\Test"
}

For more details, see Plugin-Configuration Properties. Keep in mind that the command will be run as the fm-agent user.

Create CounterMeasure actions using PowerShell

To create your own CounterMeasure:

  1. Create a new .ps1 file in the C:\Program Files (x86)\FortimonitorAgent\cm_ps_plugins directory. At a minimum, your CounterMeasure needs to implement two functions - Plugin-Configuration, which provides config and metadata about your CounterMeasure and Execute, which is the driver for your CounterMeasure.

  2. Check for syntax errors by running the script in the PowerShell ISE. If the syntax is correct, the execution should not generate any output or error message. If your CounterMeasure has syntax errors, it will not be added to the control panel.

  3. Rebuild your agent metadata via the instance's details page in the FortiMonitor control panel. Your custom plugin will then be available in the FortiMonitor control panel.

CustomCounterMeasure.ps1

function Plugin-Configuration {
$properties = @{}
#Required: a name for your custom CounterMeasure
$properties.add("name", "My Custom CounterMeasure")
#Required: a description of your custom CounterMeasure
$properties.add("description", "Returns the current dir list")
#Required: a distinct textkey for your custom CounterMeasure
$properties.add("textkey", "Fortimonitor.ListDirectoryCM")
#Required: the name of the CounterMeasure Author
$properties.add("author", "Fortimonitor.HeadDeveloper")
#Optional: The maximum frequency at which a CounterMeasure can run
$properties.add("max_frequency", "60")
# Required
return $properties
}
function Execute {
# The Metadata param will receive information about the incident the CM is responding to
param([hashtable]$metadata)
# Dictionary to to hold the returned CM payload - you can name this anything
$returndata = @{}
# Dictionary to hold each chunk of information you want to return - you can name this anything
$output = @{}
# Array to hold your 1..n dictionaries of output - you can name this anything
$output_list = New-Object System.Collections.ArrayList
# Required: either success or error. key must be return_code
$returndata.add("return_code", "success")
# Required: output type the data you are returning. either text or html. key must be format
$output.add("format", "text")
# Required: output content. key must be format
$output.add("output", "$(Get-ChildItem | Format-Table -Property Name, Length | Out-String)")
# add your output chunks to your array
$output_list.add($output);
# add your array to your top-level dictionary. key must be output
$returndata.add("output", $output_list)
# return your countermeasure data
return $returndata
}

Leveraging Incident Data

When the agent is notified that it should run a local CounterMeasure action, it receives metadata about the incident triggering the CounterMeasure. This metadata object is available to you in your code via the metadata parameter. For example, the below code just returns the incident metadata right back to FortiMonitor.

CounterMeasure return metadata

function Plugin-Configuration {

$properties = @{}

$properties.add("name", "Return mmeta")

$properties.add("description", "Returns the invoking incident's md")

$properties.add("textkey", "Fortimonitor.MetadataCM")

$properties.add("author", "Fortimonitor.HeadDeveloper")

return $properties

}

function Execute {

# The Metadata param will receive information about the incident the CM is responding to

param([hashtable]$metadata)

$returndata = @{}

$output = @{}

$output_list = New-Object System.Collections.ArrayList

$returndata.add("return_code", "success")

$output.add("format", "text")

$output.add("output", metadata)

$output_list.add($output);

$returndata.add("output", $output_list)

return $returndata

}

This is helpful as it allows you to take action based on certain criteria, such as which application or metrics triggered the incident. The payload scheme is included below. The hashtable properties are listed in the table below:

CounterMeasures incident metadata

Items in the incident metadata can be accessed from the $metadata variable.

Key

Description

$metadata.outage_id

The ID number of the associated incident.

$metadata.outage_alert_label

Alert label of the incident/anomaly.

$metadata.outage_timestamp

UTC timestamp of when the incident/clear occurred.

$metadata.outage_severity

The severity of the outage/anomaly, either "critical" or "warning".

$metadata.outage_reasons

The reason for the outage.

$metadata.server_id

The ID number of the server experiencing the incident/clear.

$metadata.server_server_key

The server key for the server.

$metadata.server_fqdn

The fully qualified domain name of the server experiencing the incident/clear.

$metadata.server_name

Name of the server experiencing the incident/clear.

$metadata.server_tags

The tags for the server.

$metadata.server_partner_server_id

The partner server ID for the server.

$metadata.metrics

Services experiencing the incident/clear or resources experiencing the anomaly/clear.

$metadata.metric_tags

The tags for all of the metrics involved in the outage.

$metadata.resource

For resource anomalies: resources experiencing the anomaly/clear.

$metadata.resource_item_type

The server resource item type.

$metadata.resource_name

The server resource name.

$metadata.resource_resource_option

if your metric utilizes an option, such as the mount point, NIC, or disk drive, it will be present here.

$metadata.services

For service incident: services experiencing the incident/clear.

Plugin-Configuration Properties

Parameters

Type

Description

Required

name

String

A human-readable name for the CounterMeasure, will be displayed in the control panel and alerts

Yes

author

String

Identifier of the author (recommended to be your email address)

Yes

textkey

String

Unique identifier for the CounterMeasure, should be lowercase letters, numbers, underscores, and periods. No spaces allowed

Yes

description

String

Description of the countermeasure, for display at the command line and in the FortiMonitor control panel

Yes

max_frequency

String

The shortest allowed time between two executions of this plugin, in seconds. If less than that time has elapsed, the second execution won't be performed. Leave set to None to disable frequency checks

No

Execute Properties

The Execute function returns a dictionary, which contains two things: the CounterMeasure execution status and an array of output items. You can name the returned dictionary whatever you like, but for clarity, we'll use the property name $returndata.

Parameter

Type

Description

Required

ReturnData["return_code"]

String

Execution status of the CounterMeasure - either success or error

Yes

ReturnData[outputs_list]

Array of Dictionaries

An array output chunks that you'd like returned for viewing in the FortiMonitor control panel

Yes

outputs_list["format"]

String

Either text or HTML

Yes

outputs_list["output"]

String

Output to be returned

Yes

Plugin Functions

Function

Parameters

Description

Required

Execution

none

Executes the countermeasure action

Yes

Plugin-Configuration

none

Returns CounterMeasure plugin configuration information

Yes