McAfeeNSMv2
McAfee Network Security Manager gives you real-time visibility and control over all McAfee intrusion prevention systems deployed across your network.
Utilities · McAfee NSM
Details
| ID | McAfeeNSMv2 |
|---|---|
| Provider | Trellix |
| Category | Utilities |
| From Version | 6.5.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
McAfee Network Security Manager gives you real-time visibility and control over all McAfee intrusion prevention systems deployed across your network.
This integration was integrated and tested with version 9.1 of McAfeeNSMv2
Some changes have been made that might affect your existing content.
If you are upgrading from a previous of this integration, see Breaking Changes.
Configure McAfee NSM v2 in Cortex
| Parameter | Required |
|---|---|
| URL (for example: https://192.168.0.1:5000) | True |
| User Name | True |
| Password | True |
| Product Version | True |
| Trust any certificate (not secure) | False |
| Use system proxy settings | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
nsm-list-domain-firewall-policy
Gets the list of firewall policies defined in a particular domain.
Base Command
nsm-list-domain-firewall-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| domain_id | The ID of the domain. To get the domain_id, use the !nsm-get-domains command. | Required |
| limit | The maximum number of records to return. Default is 50. | Optional |
| page | The specific result page to display. | Optional |
| page_size | The number of records in a page. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Policy.policyId | Number | The ID of the policy. |
| NSM.Policy.policyName | String | Name of the firewall policy. |
| NSM.Policy.domainId | Number | The ID of the domain. |
| NSM.Policy.visibleToChild | Boolean | Whether the policy is visible to child domains. |
| NSM.Policy.description | String | Policy description. |
| NSM.Policy.isEditable | Boolean | Whether the policy is editable. |
| NSM.Policy.policyType | String | Policy type. Can be “ADVANCED” or “CLASSIC”. |
| NSM.Policy.policyVersion | Number | Policy version. |
| NSM.Policy.lastModUser | String | Last user who modified the policy. |
Command example
!nsm-list-domain-firewall-policy domain_id=0 limit=2
Context Example
{
"NSM": {
"Policy": [
{
"description": "hello updatingg",
"domainId": 0,
"isEditable": true,
"lastModUser": "user",
"policyId": 292,
"policyName": "another policy",
"policyType": "ADVANCED",
"policyVersion": 1,
"visibleToChild": true
},
{
"description": "hello updatingg",
"domainId": 0,
"isEditable": true,
"lastModUser": "user",
"policyId": 161,
"policyName": "policy",
"policyType": "ADVANCED",
"policyVersion": 1,
"visibleToChild": true
}
]
}
}
Human Readable Output
Firewall Policies List
policyId policyName domainId visibleToChild description isEditable policyType policyVersion lastModUser 292 another policy 0 true hello updatingg true ADVANCED 1 user 161 policy 0 true hello updatingg true ADVANCED 1 user
nsm-get-firewall-policy
Gets the firewall policy details.
Base Command
nsm-get-firewall-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_id | The ID of the policy. To get the policy_id, use the !nsm-list-domain-firewall-policy command. | Required |
| include_rule_objects | Whether to insert the rule objects that are linked to the policy in the context. True- the rule object will be inserted. False- not inserted. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Policy.FirewallPolicyId | Number | Unique firewall policy ID. |
| NSM.Policy.Name | String | Policy name. |
| NSM.Policy.DomainId | Number | ID of the domain to which this firewall policy belongs. |
| NSM.Policy.VisibleToChild | Boolean | Whether the policy is visible to a child domain. |
| NSM.Policy.Description | String | Firewall policy description. |
| NSM.Policy.LastModifiedTime | Date | Last modified time of the firewall Policy. |
| NSM.Policy.IsEditable | Boolean | Whether the policy is editable. |
| NSM.Policy.PolicyType | String | Policy type. Can be “Advanced” / “Classic”. |
| NSM.Policy.PolicyVersion | Number | Policy version. |
| NSM.Policy.LastModifiedUser | String | Last user user modified the policy. |
| NSM.Policy.MemberDetails.MemberRuleList.Description | String | Rule description. |
| NSM.Policy.MemberDetails.MemberRuleList.Enabled | Boolean | Whether the rule is enabled. |
| NSM.Policy.MemberDetails.MemberRuleList.Response | String | Action to be performed if the traffic matches this rule. Can be “Scan” / “Drop” / “Deny” / “Ignore” / “Stateless Ignore” / “Stateless Drop” / “Require Authentication”. |
| NSM.Policy.MemberDetails.MemberRuleList.IsLogging | Boolean | Whether logging is enabled for this rule. |
| NSM.Policy.MemberDetails.MemberRuleList.Direction | String | Rule direction. Can be “Inbound” / “Outbound” / “Either”. |
| NSM.Policy.MemberDetails.MemberRuleList.SourceAddressObjectList.RuleObjectId | String | Unique rule object ID. |
| NSM.Policy.MemberDetails.MemberRuleList.SourceAddressObjectList.Name | String | Rule object name. |
| NSM.Policy.MemberDetails.MemberRuleList.SourceAddressObjectList.RuleObjectType | Unknown | Source or destination mode. Can be “Endpoint IP V.4” / “Range IP V.4” / “Network IP V.4” / “Endpoint IP V.6” / “Range IP V.6” / “Network IP V.6”. |
| NSM.Policy.MemberDetails.MemberRuleList.DestinationAddressObjectList.RuleObjectId | String | Unique rule object ID. |
| NSM.Policy.MemberDetails.MemberRuleList.DestinationAddressObjectList.Name | String | Rule object name. |
| NSM.Policy.MemberDetails.MemberRuleList.DestinationAddressObjectList.RuleObjectType | Unknown | Source or destination mode. Can be “Endpoint IP V.4” / “Range IP V.4” / “Endpoint IP V.6” / “Range IP V.6” / “Network IP V.6”. |
| NSM.Policy.MemberDetails.MemberRuleList.SourceUserObjectList.RuleObjectId | String | Unique rule object ID. |
| NSM.Policy.MemberDetails.MemberRuleList.SourceUserObjectList.Name | String | Rule object name. |
| NSM.Policy.MemberDetails.MemberRuleList.SourceUserObjectList.RuleObjectType | String | Source user. Can be “USER” / “USER_GROUP”. |
| NSM.Policy.MemberDetails.MemberRuleList.ServiceObjectList.RuleObjectId | String | Unique service rule object ID. |
| NSM.Policy.MemberDetails.MemberRuleList.ServiceObjectList.Name | String | Rule object name. |
| NSM.Policy.MemberDetails.MemberRuleList.ServiceObjectList.RuleObjectType | Unknown | Service/ application mode. Can be “APPLICATION” / “APPLICATION_GROUP” / “APPLICATION_ON_CUSTOM_PORT” / “SERVICE” / “SERVICE_GROUP”. |
| NSM.Policy.MemberDetails.MemberRuleList.ServiceObjectList.ApplicationType | Unknown | Application type. Can be “DEFAULT” / “CUSTOM”. |
| NSM.Policy.MemberDetails.MemberRuleList.ApplicationObjectList.RuleObjectId | String | Unique service rule object ID. |
| NSM.Policy.MemberDetails.MemberRuleList.ApplicationObjectList.Name | String | Rule object name. |
| NSM.Policy.MemberDetails.MemberRuleList.ApplicationObjectList.RuleObjectType | Unknown | Service/ application mode. Can be “APPLICATION” / “APPLICATION_GROUP” / “APPLICATION_ON_CUSTOM_PORT” / “SERVICE” / “SERVICE_GROUP”. |
| NSM.Policy.MemberDetails.MemberRuleList.ApplicationObjectList.ApplicationType | Unknown | Application type. Can be “DEFAULT” / “CUSTOM”. |
| NSM.Policy.MemberDetails.MemberRuleList.TimeObjectList.RuleObjectId | String | Unique service rule object ID. |
| NSM.Policy.MemberDetails.MemberRuleList.TimeObjectList.Name | String | Rule object name. |
| NSM.Policy.MemberDetails.MemberRuleList.TimeObjectList.RuleObjectType | Unknown | Time mode. Can be “FINITE_TIME_PERIOD” / “RECURRING_TIME_PERIOD” / “RECURRING_TIME_PERIOD_GROUP”. |
Command example
!nsm-get-firewall-policy policy_id=147 include_rule_objects=true
Context Example
{
"NSM": {
"Policy": {
"Description": "update policy",
"DomainId": 0,
"FirewallPolicyId": 147,
"IsEditable": true,
"LastModifiedTime": "2022-12-28 05:37:23",
"LastModifiedUser": "user",
"MemberDetails": {
"MemberRuleList": [
{
"ApplicationObjectList": [],
"Description": "r",
"DestinationAddressObjectList": [
{
"Name": "Any",
"RuleObjectId": "-1",
"RuleObjectType": null
}
],
"Direction": "EITHER",
"Enabled": true,
"IsLogging": false,
"Response": "SCAN",
"ServiceObjectList": [
{
"ApplicationType": null,
"Name": "Any",
"RuleObjectId": "-1",
"RuleObjectType": null
}
],
"SourceAddressObjectList": [
{
"Name": "Range V6 Test",
"RuleObjectId": "117",
"RuleObjectType": "IPV_6_ADDRESS_RANGE"
}
],
"SourceUserObjectList": [
{
"Name": "Any",
"RuleObjectId": "-1",
"RuleObjectType": "USER"
}
],
"TimeObjectList": [
{
"Name": "Always",
"RuleObjectId": "-1",
"RuleObjectType": null
}
]
}
]
},
"Name": "name147",
"PolicyType": "ADVANCED",
"PolicyVersion": 1,
"VisibleToChild": true
}
}
}
Human Readable Output
Firewall Policy 147
Name Description VisibleToChild IsEditable PolicyType PolicyVersion LastModifiedUser LastModifiedTime name147 update policy true true ADVANCED 1 user 2022-12-28 05:37:23
nsm-create-firewall-policy
Adds a new firewall policy and access rules. You have to provide at lease one of the source/destination rule objects. If you provide the id or type of the source/destination rule object, you must provide the matching type or id the source/destination rule object as well.
Base Command
nsm-create-firewall-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | The ID of the domain. To get the domain ID, use the !nsm-get-domains command. | Required |
| name | The policy name. | Required |
| visible_to_child | Whether the policy is visible to the child domain. Possible values are: yes, no. Default is yes. | Optional |
| description | The description of the policy. | Required |
| is_editable | Whether the policy is editable. Possible values are: yes, no. Default is yes. | Optional |
| policy_type | The type of the policy. Possible values are: Advanced, Classic. | Required |
| rule_description | The rule description. | Required |
| response | Action to be performed if the traffic matches this rule. Possible values are: Scan, Drop, Deny, Ignore, Stateless Ignore, Stateless Drop, Require Authentication. | Required |
| rule_enabled | Whether the rule is enabled. Possible values are: yes, no. Default is yes. | Optional |
| direction | The direction of the rule. Possible values are: Inbound, Outbound, Either. | Required |
| source_rule_object_id | The ID of the rule connected to the policy. To get the rule_object_id use the command ‘!nsm-list-domain-rule-object’. | Optional |
| source_rule_object_type | The type of the rule connected to the policy. To get the rule_object_type use the command ‘!nsm-list-domain-rule-object’. Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6. | Optional |
| destination_rule_object_id | The ID of the rule connected to the policy. To get the rule_object_id use the command ‘!nsm-list-domain-rule-object’. | Optional |
| destination_rule_object_type | The type of the rule connected to the policy. To get the rule_object_type use the command ‘!nsm-list-domain-rule-object’. Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Policy.FirewallPolicyId | Number | The ID of the newly created firewall policy. |
Command example
!nsm-create-firewall-policy domain=0 name=policy visible_to_child=yes description="a new policy" is_editable=yes policy_type=Advanced response=Scan rule_description="Test Member Rule" direction=Inbound destination_rule_object_id=111 destination_rule_object_type="Range IP V.4"
Context Example
{
"NSM": {
"Policy": {
"FirewallPolicyId":112
}
}
}
Human Readable Output
The firewall policy no.112 was created successfully
nsm-update-firewall-policy
Updates the firewall policy details. If the argument is_overwrite=true, the new values of the provided addresses will replace the existing values, otherwise the addresses will be added to them.
- If you want to delete a rule, enter is_overwrite=true and the relevant rule_object_id=-1.
- If is_overwrite=false and there is no value in one of the rules (source or destination), their value will be as before.
- If is_overwrite=true, at least one of the rules (source or destination) must be provided.
- If you provide the id or type of the source/destination rule object, you must provide the matching type or id the source/destination rule object as well.
Base Command
nsm-update-firewall-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_id | The ID of the policy. To get the policy ID, use the !nsm-list-domain-firewall-policy. | Required |
| domain | The ID of the domain. To get the domain ID, use the !nsm-get-domains command. | Optional |
| name | The policy name. | Optional |
| visible_to_child | Whether the policy is visible to the child domain. Possible values are: yes, no. Default is yes. | Optional |
| description | The description of the policy. | Optional |
| is_editable | Whether the policy is editable. Possible values are: yes, no. | Optional |
| policy_type | The type of the policy. Possible values are: Advanced, Classic. | Optional |
| rule_description | The rule description. | Optional |
| response | Action to be performed if the traffic matches this rule. Possible values are: Scan, Drop, Deny, Ignore, Stateless Ignore, Stateless Drop, Require Authentication. | Optional |
| rule_enabled | Whether the rule is enabled. Possible values are: yes, no. Default is yes. | Optional |
| direction | The direction of the rule. Possible values are: Inbound, Outbound, Either. | Optional |
| source_rule_object_id | The ID of the rule connected to the policy. To get the rule_object_id use the command ‘!nsm-list-domain-rule-object’. | Optional |
| source_rule_object_type | The type of the rule connected to the policy. To get the rule_object_type use the command ‘!nsm-list-domain-rule-object’. Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6. | Optional |
| destination_rule_object_id | The ID of the rule connected to the policy. To get the rule_object_id use the command ‘!nsm-list-domain-rule-object’. | Optional |
| destination_rule_object_type | The type of the rule connected to the policy. To get the rule_object_type use the command ‘!nsm-list-domain-rule-object’. Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6. | Optional |
| is_overwrite | Whether the new addresses that were provided in the update processes will override the current ones or will be added to them. Possible values are: true, false. | Optional |
Context Output
There is no context output for this command.
Command example
!nsm-update-firewall-policy policy_id=147 description="update policy"
Human Readable Output
The firewall policy no.147 was updated successfully
nsm-delete-firewall-policy
Deletes the specified firewall policy.
Base Command
nsm-delete-firewall-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_id | The ID of the policy to delete. To get the policy ID, use the !nsm-list-domain-firewall-policy. | Required |
Context Output
There is no context output for this command.
Command example
!nsm-delete-firewall-policy policy_id=101
Human Readable Output
The firewall policy no.101 was deleted successfully
nsm-list-domain-rule-object
Gets the list of rule objects defined in a particular domain.
Base Command
nsm-list-domain-rule-object
Input
| Argument Name | Description | Required |
|---|---|---|
| domain_id | The ID of the domain. To get the domain ID, use the !nsm-get-domains command. | Required |
| type | The type of the rule. Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6, All. Default is All. | Optional |
| limit | The maximum number of records to return. Default is 50. | Optional |
| page | The specific result page to display. | Optional |
| page_size | The number of records in a page. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Rule.ruleobjId | String | The ID of the rule object. |
| NSM.Rule.ruleobjType | String | The type of the rule object. |
| NSM.Rule.name | String | The name of the rule object. |
| NSM.Rule.description | String | The description of the rule object. |
| NSM.Rule.domain | Number | The name of the rule object. |
| NSM.Rule.visibleToChild | Boolean | Whether the rule is visible to child domains. |
| NSM.Rule.hostCriticality | String | The critical level of the host. |
| NSM.Rule.ApplicationGroup | Unknown | Application Group object. Should be defined if ruleobjType is “APPLICATION_GROUP”. |
| NSM.Rule.ApplicationOnCustomPort | Unknown | Application defined on Custom Port object. Should be defined if ruleobjType is “APPLICATION_ON_CUSTOM_PORT”. |
| NSM.Rule.FiniteTimePeriod | Unknown | Finite Time Period object. Should be defined if ruleobjType is “FINITE_TIME_PERIOD”. |
| NSM.Rule.HostIPv4 | Unknown | Host IPv4 Address object. Should be defined if ruleobjType is “HOST_IPV_4”. |
| NSM.Rule.HostIPv6 | Unknown | Host IPv6 Address object. Should be defined if ruleobjType is “HOST_IPV_6”. |
| NSM.Rule.HostDNSName | Unknown | Host DNS Name object. Should be defined if ruleobjType is “HOST_DNS_NAME”. |
| NSM.Rule.IPv4AddressRange | Unknown | IPv4 Address Range object. Should be defined if ruleobjType is “IPV_4_ADDRESS_RANGE”. |
| NSM.Rule.IPv6AddressRange | Unknown | IPv6 Address Range object. Should be defined if ruleobjType is “IPV_6_ADDRESS_RANGE”. |
| NSM.Rule.Network_IPV_4 | Unknown | IPv4 Network object. Should be defined if ruleobjType is “NETWORK_IPV_4. |
| NSM.Rule.Network_IPV_6 | String | IPv6 Network object. Should be defined if ruleobjType is “NETWORK_IPV_6”. |
| NSM.Rule.NetworkGroup | Unknown | Network Group object. Should be defined if ruleobjType is “NETWORK_GROUP”. |
| NSM.Rule.RecurringTimePeriod | Unknown | Recurring Time Period object. Should be defined if ruleobjType is “RECURRING_TIME_PERIOD”. |
| NSM.Rule.RecurringTimePeriodGroup | Unknown | Recurring Time Period Group object. Should be defined if ruleobjType is “RECURRING_TIME_PERIOD_GROUP”. |
| NSM.Rule.Service | Unknown | Service object. Should be defined if ruleobjType is “CUSTOM_SERVICE”. |
| NSM.Rule.ServiceGroup | Unknown | Service Group object. Should be defined if ruleobjType is “SERVICE_GROUP”. |
| NSM.Rule.ServiceRange | Unknown | Service Range object. Should be defined if ruleobjType is “SERVICE_RANGE”. |
| NSM.Rule.IPv6AddressRange.IPV6RangeList | String | List of IPv6 Address Range. |
| NSM.Rule.HostIPv6.hostIPv6AddressList | String | Host IPv6 address list. |
| NSM.Rule.Network_IPV_4.networkIPV4List | String | Network IPV4 list. |
| NSM.Rule.IPv4AddressRange.IPV4RangeList | String | List of IPv4 address range. |
| NSM.Rule.HostIPv4.hostIPv4AddressList | String | Host IPv4 address list. |
| NSM.Rule.Network_IPV_6.networkIPV6List | String | Network IPV6 list. |
Command example
!nsm-list-domain-rule-object domain_id=0 limit=2
Context Example
{
"NSM": {
"Rule": [
{
"ApplicationGroup": null,
"ApplicationOnCustomPort": null,
"FiniteTimePeriod": null,
"HostDNSName": null,
"HostIPv4": {
"hostIPv4AddressList": [
"1.1.1.1"
]
},
"HostIPv6": null,
"IPv4AddressRange": null,
"IPv6AddressRange": null,
"NetworkGroup": null,
"Network_IPV_4": null,
"Network_IPV_6": null,
"RecurringTimePeriod": null,
"RecurringTimePeriodGroup": null,
"Service": null,
"ServiceGroup": null,
"ServiceRange": null,
"description": null,
"domain": 0,
"hostCriticality": "HIGH",
"name": "testing",
"ruleobjId": "134",
"ruleobjType": "Endpoint IP V.4",
"visibleToChild": true
},
{
"ApplicationGroup": null,
"ApplicationOnCustomPort": null,
"FiniteTimePeriod": null,
"HostDNSName": null,
"HostIPv4": null,
"HostIPv6": null,
"IPv4AddressRange": {
"IPV4RangeList": [
{
"FromAddress": "1.1.1.1",
"ToAddress": "2.2.2.2"
}
]
},
"IPv6AddressRange": null,
"NetworkGroup": null,
"Network_IPV_4": null,
"Network_IPV_6": null,
"RecurringTimePeriod": null,
"RecurringTimePeriodGroup": null,
"Service": null,
"ServiceGroup": null,
"ServiceRange": null,
"description": null,
"domain": 0,
"hostCriticality": null,
"name": "ruleo",
"ruleobjId": "133",
"ruleobjType": "Range IP V.4",
"visibleToChild": true
}
]
}
}
Human Readable Output
List of Rule Objects
RuleId Name VisibleToChild RuleType 134 testing true Endpoint IP V.4 133 ruleo true Range IP V.4
nsm-get-rule-object
Gets the details of a rule object.
Base Command
nsm-get-rule-object
Input
| Argument Name | Description | Required |
|---|---|---|
| rule_id | The ID of the rule object. To get the rule object ID, use the !nsm-list-domain-rule-object. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Rule.ruleobjId | String | The ID of the rule object. |
| NSM.Rule.ruleobjType | String | The type of the rule object. |
| NSM.Rule.name | String | The name of the rule object. |
| NSM.Rule.description | String | The description of the rule object. |
| NSM.Rule.domain | Number | The name of the rule object. |
| NSM.Rule.visibleToChild | Boolean | Whether the rule is visible to child domains. |
| NSM.Rule.ApplicationGroup | Unknown | Application Group object. Should be defined if ruleobjType is “APPLICATION_GROUP”. |
| NSM.Rule.ApplicationOnCustomPort | Unknown | Application defined on Custom Port object. Should be defined if ruleobjType is “APPLICATION_ON_CUSTOM_PORT”. |
| NSM.Rule.FiniteTimePeriod | Unknown | Finite Time Period object. Should be defined if ruleobjType is “FINITE_TIME_PERIOD”. |
| NSM.Rule.HostIPv4 | Unknown | Host IPv4 Address object. Should be defined if ruleobjType is “HOST_IPV_4”. |
| NSM.Rule.HostIPv6 | Unknown | Host IPv6 Address object. Should be defined if ruleobjType is “HOST_IPV_6”. |
| NSM.Rule.HostDNSName | Unknown | Host DNS Name object. Should be defined if ruleobjType is “HOST_DNS_NAME”. |
| NSM.Rule.IPv4AddressRange | Unknown | IPv4 Address Range object. Should be defined if ruleobjType is “IPV_4_ADDRESS_RANGE”. |
| NSM.Rule.IPv6AddressRange | Unknown | IPv6 Address Range object. Should be defined if ruleobjType is “IPV_6_ADDRESS_RANGE”. |
| NSM.Rule.Network_IPV_4 | Unknown | IPv4 Network object. Should be defined if ruleobjType is “NETWORK_IPV_4. |
| NSM.Rule.Network_IPV_6 | String | IPv6 Network object. Should be defined if ruleobjType is “NETWORK_IPV_6”. |
| NSM.Rule.NetworkGroup | Unknown | Network Group object. Should be defined if ruleobjType is “NETWORK_GROUP”. |
| NSM.Rule.RecurringTimePeriod | Unknown | Recurring Time Period object. Should be defined if ruleobjType is “RECURRING_TIME_PERIOD”. |
| NSM.Rule.RecurringTimePeriodGroup | Unknown | Recurring Time Period Group object. Should be defined if ruleobjType is “RECURRING_TIME_PERIOD_GROUP”. |
| NSM.Rule.Service | Unknown | Service object. Should be defined if ruleobjType is “CUSTOM_SERVICE”. |
| NSM.Rule.ServiceGroup | Unknown | Service Group object. Should be defined if ruleobjType is “SERVICE_GROUP”. |
| NSM.Rule.ServiceRange | Unknown | Service Range object. Should be defined if ruleobjType is “SERVICE_RANGE”. |
| NSM.Rule.IPv6AddressRange.IPV6RangeList | String | List of IPv6 Address Range. |
| NSM.Rule.HostIPv6.hostIPv6AddressList | String | Host IPv6 address list. |
| NSM.Rule.Network_IPV_4.networkIPV4List | String | Network IPV4 list. |
| NSM.Rule.Network_IPV_6.networkIPV6List | String | Network IPV6 list. |
| NSM.Rule.IPv4AddressRange.IPV4RangeList | String | List of IPv4 Address Range. |
| NSM.Rule.HostIPv4.hostIPv4AddressList | String | Host IPv4 address list. |
nsm-create-rule-object
Adds a new rule object.
- If the type is “Endpoint IP V.X” or “Network IP V.X”, only the argument “address_ip_v.X” must contain a value.
- If the type is “Range IP V.X”, only the arguments “from_address_ip_v.X”, “to_address_ip_v.X” must contain a value. Where X is 4 or 6 respectively.
Base Command
nsm-create-rule-object
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | The ID of the domain. To get the domain ID, use the !nsm-get-domains command. | Required |
| rule_object_type | The type of the rule. If the type is “Endpoint IP V.X” or “Network IP V.X”, only the argument “address_ip_v.X” must contain a value. If the type is “Range IP V.X”, only the arguments “from_address_ip_v.X”, “to_address_ip_v.X” must contain a value, where X is 4 or 6 respectively. * Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6. |
Required |
| name | The rule object name. | Required |
| visible_to_child | Whether the rule object is visible to the child domain. Possible values are: yes, no. Default is yes. | Optional |
| description | The description of the rule object. | Optional |
| address_ip_v.4 | List of IPv4 Host Address, separated by a comma. | Optional |
| from_address_ip_v.4 | Start of the IPv4 range. | Optional |
| to_address_ip_v.4 | End of the IPv4 range. | Optional |
| address_ip_v.6 | List of IPv6 host addresses, separated by a comma. | Optional |
| from_address_ip_v.6 | Start of the IPv6 range. | Optional |
| to_address_ip_v.6 | End of the IPv6 range. | Optional |
| state | Whether to enable or disable the rule object. Note: This argument is only relevant to version 10x. Default value is ‘Enabled’ | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Rule.ruleobjId | Number | The ID of the newly created rule object. |
Command example
!nsm-create-rule-object domain=0 rule_object_type="Range IP V.4" name="ruleo" visible_to_child=yes from_address_ip_v.4=1.1.1.1 to_address_ip_v.4=2.2.2.2
Context Example
{
"NSM": {
"Rule": {
"ruleobjId": 154
}
}
}
Human Readable Output
The rule object no.154 was created successfully
nsm-update-rule-object
Updates a Rule object. In case of address rule update:
- if the rule type is “Endpoint IP V.X” or “Network IP V.X”, only the argument “address_ip_v.X” should contain a value.
- If the type is “Range IP V.X”, only the arguments “from_address_ip_v.X”, “to_address_ip_v.X” should contain a value, Where X is 4 or 6 respectively.
Base Command
nsm-update-rule-object
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | The ID of the domain. To get the domain ID, use the !nsm-get-domains command. | Required |
| rule_id | The ID of the rule. To get the rule object ID, use the !nsm-list-domain-rule-object. | Required |
| name | The rule object name. | Optional |
| visible_to_child | Whether the rule object is visible to the child domain. Possible values are: yes, no. Default is yes. | Optional |
| description | The description of the rule object. | Optional |
| address_ip_v.4 | List of IPv4 host addresses, separated by a comma. | Optional |
| from_address_ip_v.4 | Start of the IPv4 range. | Optional |
| to_address_ip_v.4 | End of the IPv4 range. | Optional |
| address_ip_v.6 | List of IPv6 host addresses, separated by a comma. | Optional |
| from_address_ip_v.6 | Start of the IPv6 range. | Optional |
| to_address_ip_v.6 | End of the IPv6 range. | Optional |
| is_overwrite | Whether the new addresses that were provided in the update processes will override the current ones or will be added to them. The default is false, and the addresses will be added. Possible values are: true, false. | Optional |
| state | Whether to enable or disable the rule object. Note: This argument is only relevant to version 10x. Default value is ‘Enabled’ | Optional |
Context Output
There is no context output for this command.
Command example
!nsm-update-rule-object domain=0 rule_id=125 description="new desc"
Human Readable Output
The rule object no.125 was updated successfully.
nsm-delete-rule-object
Deletes a rule object.
Base Command
nsm-delete-rule-object
Input
| Argument Name | Description | Required |
|---|---|---|
| rule_id | The ID of the rule object. To get the rule object ID, use the !nsm-list-domain-rule-object. | Required |
Context Output
There is no context output for this command.
Command example
!nsm-delete-rule-object rule_id=125
Human Readable Output
The rule object no.125 was deleted successfully.
nsm-get-alerts
Retrieves the alerts.
Base Command
nsm-get-alerts
Input
| Argument Name | Description | Required |
|---|---|---|
| limit | The maximum number of records to return. Default is 50. | Optional |
| page | The specific result page to display. | Optional |
| page_size | The number of records in a page. | Optional |
| time_period | Time period. Possible values are: LAST_5_MINUTES, LAST_1_HOUR, LAST_6_HOURS, LAST_12_HOURS, LAST_24_HOURS, LAST_7_DAYS, LAST_14_DAYS, CUSTOM. Default is LAST_7_DAYS. | Optional |
| start_time | Start time in “mm/dd/yyyy HH:MM” format. Used for custom time only. | Optional |
| end_time | End time in “mm/dd/yyyy HH:MM” format. Used for custom time only. | Optional |
| state | Alert state. Possible values are: ANY, Acknowledged, Unacknowledged. Default is ANY. | Optional |
| search | Search string in alert details. | Optional |
| filter | Filter alert by fields. For example: “name:hello;direction:Inbound,Outbound;attackcount:>3,<4”. To use the “name” field in the filter, enter only one name in each command run. Filter on the following columns is allowed- name, assignTo, application, layer7Data, result, attackCount, relevance, alertId, direction, device, domain, interface, attackSeverity, nspId, btp, attackCategory, malwarefileName, malwarefileHash, malwareName, malwareConfidence, malwareEngine ,executableName, executableHash, executableConfidenceName, attackerIPAddress, attackerPort, attackerRisk, attackerProxyIP, attackerHostname, targetIPAddress, targetPort, targetRisk, targetProxyIP, targetHostname, botnetFamily. | Optional |
| domain_id | The ID of the domain. To get the domain_id, use the !nsm-get-domains command. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Alerts.ID | number | Alert ID. |
| NSM.Alerts.Name | String | Alert name. |
| NSM.Alerts.uniqueAlertId | String | Unique alert ID. |
| NSM.Alerts.State | String | Alert state (Acknowledged,Unacknowledged). |
| NSM.Alerts.Assignee | String | Alert assignee. |
| NSM.Alerts.CreatedTime | String | Alert creation time. |
| NSM.Alerts.AttackSeverity | String | Alert severity. |
| NSM.Alerts.Event.time | Date | The creation time of the event that triggered the alert. |
| NSM.Alerts.Event.direction | String | The direction of the event (Outbound, Inbound). |
| NSM.Alerts.Event.result | String | The result of the event. |
| NSM.Alerts.Event.attackCount | Number | Attack count. |
| NSM.Alerts.Event.relevance | String | The event relevance. |
| NSM.Alerts.Event.alertId | String | Alert ID. |
| NSM.Alerts.Event.domain | String | The event’s domain. |
| NSM.Alerts.Event.interface | String | The event’s interface. |
| NSM.Alerts.Event.device | String | The relevant device. |
| NSM.Alerts.Attack.nspId | String | Network Security Platform (NSP) ID. |
| NSM.Alerts.Attack.btp | String | Benign Trigger Probability (BTP). |
| NSM.Alerts.Attack.attackCategory | String | The attack category. |
| NSM.Alerts.Attacker.ipAddrs | String | The attacker IP address. |
| NSM.Alerts.Attacker.port | Number | The attacker port. |
| NSM.Alerts.Attacker.hostName | String | The attacker host name. |
| NSM.Alerts.Attacker.country | String | The attacker country. |
| NSM.Alerts.Attacker.os | Unknown | The attacker operating system. |
| NSM.Alerts.Attacker.vmName | Unknown | The attacker VM name. |
| NSM.Alerts.Attacker.proxyIP | String | The attacker proxy IP. |
| NSM.Alerts.Attacker.user | Unknown | The user. |
| NSM.Alerts.Attacker.risk | String | Attacker risk. |
| NSM.Alerts.Attacker.networkObject | Unknown | The attacker network object. |
| NSM.Alerts.Target.ipAddrs | String | The target IP address. |
| NSM.Alerts.Target.port | Number | The target port. |
| NSM.Alerts.Target.hostName | String | The target host name. |
| NSM.Alerts.Target.country | String | The target country. |
| NSM.Alerts.Target.os | Unknown | The target operating system. |
| NSM.Alerts.Target.vmName | Unknown | The target VM name. |
| NSM.Alerts.Target.proxyIP | String | The target proxy IP. |
| NSM.Alerts.Target.user | Unknown | The target user. |
| NSM.Alerts.Target.risk | String | The target risk. |
| NSM.Alerts.Target.networkObject | Unknown | The target network object. |
| NSM.Alerts.MalwareFile.fileName | String | The name of the malware file. |
| NSM.Alerts.MalwareFile.fileHash | String | The file hash of the malware file. |
| NSM.Alerts.MalwareFile.fileSHA1Hash | String | The malware file SHA1 hash. |
| NSM.Alerts.MalwareFile.fileSHA256Hash | Unknown | The file SHA256 hash of the malware file. |
| NSM.Alerts.MalwareFile.malwareName | String | The name of the malware. |
| NSM.Alerts.MalwareFile.malwareConfidence | String | Malware confidence |
| NSM.Alerts.MalwareFile.engine | String | Malware file engine. |
| NSM.Alerts.MalwareFile.engineId | Number | Malware file engine ID. |
| NSM.Alerts.MalwareFile.size | Unknown | The malware file size. |
| NSM.Alerts.MalwareFile.description | Unknown | Malware file description. |
| NSM.Alerts.MalwareFile.additionalReference | Unknown | Malware file additional reference. |
| NSM.Alerts.MalwareFile.cveId | Unknown | Malware file CVE ID. |
| NSM.Alerts.endpointExcutable.name | String | Endpoint executable name. |
| NSM.Alerts.endpointExcutable.hash | String | Endpoint executable hash. |
| NSM.Alerts.endpointExcutable.malwareConfidence | String | Endpoint executable malware confidence. |
| NSM.Alerts.detection.managerId | Number | manager ID. |
| NSM.Alerts.detection.manager | Unknown | The detection manager. |
| NSM.Alerts.detection.domain | String | Detection domain. |
| NSM.Alerts.detection.device | String | Detection device. |
| NSM.Alerts.detection.deviceId | String | Detection device ID. |
| NSM.Alerts.detection.interface | String | Detection interface. |
| NSM.Alerts.Application | String | The application associated to the alert. |
| NSM.Alerts.layer7Data | String | Layer 7 information. |
| NSM.Alerts.EventResult | String | Event result. |
| NSM.Alerts.SensorID | String | Sensor ID. |
Command example
!nsm-get-alerts domain_id=0 time_period=CUSTOM start_time="12/17/2000 14:14:22" end_time="12/18/2022 00:26:45" limit=2
Context Example
{
"NSM": {
"Alerts": [
{
"Application": "HTTP",
"Assignee": "",
"Attack": {
"attackCategory": "Exploit",
"btp": "Medium",
"nspId": "0x00000000"
},
"Attacker": {
"country": null,
"hostName": "",
"ipAddrs": "1.1.1.1",
"networkObject": null,
"os": null,
"port": 22222,
"proxyIP": "",
"risk": "Disabled",
"user": null,
"vmName": null
},
"CreatedTime": "Dec 17, 2018 21:06:21",
"Event": {
"alertId": "3333333333333333333",
"attackCount": 1,
"device": "VVVV1",
"direction": "Outbound",
"domain": "/My Domain",
"interface": "1-2",
"relevance": "Unknown",
"result": "Inconclusive",
"time": "Dec 17, 2018 21:06:21"
},
"EventResult": "Inconclusive",
"ID": "3333333333333333333",
"MalwareFile": {
"additionalReference": null,
"cveId": null,
"description": null,
"engine": "",
"engineId": 0,
"fileHash": "",
"fileName": "",
"malwareConfidence": "",
"malwareName": "",
"size": null
},
"Name": "HTTP: vulnerability",
"SensorID": "4444",
"Target": {
"country": null,
"hostName": "",
"ipAddrs": "2.2.2.2",
"networkObject": null,
"os": null,
"port": 80,
"proxyIP": "",
"risk": "Disabled",
"user": null,
"vmName": null
},
"State": "Acknowledged",
"attackSeverity": "High",
"detection": {
"device": "VVVV1",
"deviceId": "4444",
"domain": "/My Domain",
"interface": "1-2",
"manager": null,
"managerId": 0
},
"endpointExcutable": {
"hash": "",
"malwareConfidence": "",
"name": ""
},
"layer7Data": "HTTP Request Method: GET ",
"uniqueAlertId": "1212121212121212121"
},
{
"Application": "Web",
"Assignee": "",
"Attack": {
"attackCategory": "Exploit",
"btp": "Low",
"nspId": "0x00000000"
},
"Attacker": {
"country": null,
"hostName": "",
"ipAddrs": "1.1.1.1",
"networkObject": null,
"os": null,
"port": 12345,
"proxyIP": "",
"risk": "---",
"user": null,
"vmName": null
},
"CreatedTime": "Dec 17, 2018 21:04:21",
"Event": {
"alertId": "5555555555555555555",
"attackCount": 1,
"device": "VVVV1",
"direction": "Inbound",
"domain": "/My Dmain",
"interface": "1-2",
"relevance": "Unknown",
"result": "Inconclusive",
"time": "Dec 17, 2018 21:04:21"
},
"EventResult": "Inconclusive",
"ID": "5555555555555555555",
"MalwareFile": {
"additionalReference": null,
"cveId": null,
"description": null,
"engine": "",
"engineId": 0,
"fileHash": "",
"fileName": "",
"malwareConfidence": "",
"malwareName": "",
"size": null
},
"Name": "HTTP: IIS 6.0 (CVE-2017-7269)",
"SensorID": "4444",
"Target": {
"country": null,
"hostName": "",
"ipAddrs": "2.2.2.2",
"networkObject": null,
"os": null,
"port": 80,
"proxyIP": "",
"risk": "---",
"user": null,
"vmName": null
},
"alertState": "Acknowledged",
"attackSeverity": "High",
"detection": {
"device": "VVVV1",
"deviceId": "4444",
"domain": "/My Domain",
"interface": "1-2",
"manager": null,
"managerId": 0
},
"endpointExcutable": {
"hash": "",
"malwareConfidence": "",
"name": ""
},
"layer7Data": "HTTP Request Method: PROPFIND",
"uniqueAlertId": "2323232323232323232"
}
]
}
}
Human Readable Output
Alerts list. Showing 2 of 20
ID Name Severity State 3333333333333333333 HTTP: vulnerability High Acknowledged 5555555555555555555 HTTP: IIS 6.0 (CVE-2017-7269) High Acknowledged
nsm-get-alert-details
Retrieves the relevant alert details.
Base Command
nsm-get-alert-details
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | Alert ID. In order to get the alert ID, use the command ‘!nsm-get-alerts’ and use the output field “ID”. | Required |
| sensor_id | Sensor ID. In order to get the sensor ID, use the command ‘!nsm-get-alerts’ and use the output field “SensorID”. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Alerts.ID | number | Alert ID. |
| NSM.Alerts.Name | String | Alert name. |
| NSM.Alerts.CreatedTime | String | Alert creation time. |
| NSM.Alerts.uniqueAlertId | String | Unique alert ID. |
| NSM.Alerts.State | String | The state of the alert. |
| NSM.Alerts.Assignee | String | Alert assignee. |
| NSM.Alerts.Event.application | String | The event application. |
| NSM.Alerts.Event.protocol | Unknown | The event protocol. |
| NSM.Alerts.Event.domain | String | The domain of the event. |
| NSM.Alerts.Event.manager | Unknown | The event manager. |
| NSM.Alerts.Event.device | String | The event device. |
| NSM.Alerts.Event.deviceId | String | The ID of the device related to the event. |
| NSM.Alerts.Event.matchedPolicy | String | The policy that matched the event. |
| NSM.Alerts.Event.zone | Unknown | The event zone. |
| NSM.Alerts.Event.vlan | String | The event VLAN. |
| NSM.Alerts.Event.detection | String | The event detection. |
| NSM.Alerts.CreatedTime | Date | The creation time of the event. |
| NSM.Alerts.EventResult | String | The event result. |
| NSM.Alerts.Event.attackCount | Number | Event attack count. |
| NSM.Alerts.Event.relevance | String | The relevance of the event. |
| NSM.Alerts.Event.alertId | String | Alert ID. |
| NSM.Alerts.Attacker.ipAddrs | Unknown | Attacker IP addresses. |
| NSM.Alerts.Attacker.port | Number | Attacker port. |
| NSM.Alerts.Attacker.hostName | Unknown | Attacker host name. |
| NSM.Alerts.Attacker.country | Unknown | Attacker country. |
| NSM.Alerts.Attacker.os | String | Attacker operating system. |
| NSM.Alerts.Attacker.vmName | Unknown | Attacker VM name. |
| NSM.Alerts.Attacker.proxyIP | Unknown | Attacker proxy IP. |
| NSM.Alerts.Attacker.user | String | Attacker user. |
| NSM.Alerts.Attacker.risk | String | Attacker risk. |
| NSM.Alerts.Attacker.networkObject | String | Attacker network object. |
| NSM.Alerts.Target.ipAddrs | Unknown | Target IP address. |
| NSM.Alerts.Target.port | Number | Target port. |
| NSM.Alerts.Target.hostName | Unknown | Target host name. |
| NSM.Alerts.Target.country | Unknown | Target country. |
| NSM.Alerts.Target.os | String | Target operating system. |
| NSM.Alerts.Target.vmName | Unknown | Target VM name. |
| NSM.Alerts.Target.proxyIP | Unknown | Target proxy IP. |
| NSM.Alerts.Target.user | String | Target user. |
| NSM.Alerts.Target.risk | String | Target risk. |
| NSM.Alerts.Target.networkObject | String | Target network object. |
| NSM.Alerts.summary.source | Unknown | The source of the alert. |
| NSM.Alerts.summary.destination | Unknown | The destination of the alert. |
| NSM.Alerts.summary.zoombie | Unknown | Alert zoombie. |
| NSM.Alerts.summary.cAndcServer | Unknown | The command and control server. |
| NSM.Alerts.summary.fastFluxAgent | Unknown | Fast flux agent. |
| NSM.Alerts.summary.attackedHIPEndpoint | Unknown | Attacked host intrusion prevention (HIP) endpoint. |
| NSM.Alerts.summary.compromisedEndpoint | Unknown | Compromised endpoint. |
| NSM.Alerts.Details.matchedSignature | Unknown | Matched signature. |
| NSM.Alerts.MalwareFile | Unknown | Malware file. |
| NSM.Alerts.Details.hostSweep | Unknown | Host sweep. |
| NSM.Alerts.Details.portScan | Unknown | Port scan. |
| NSM.Alerts.Details.fastFlux | Unknown | Fast flux. |
| NSM.Alerts.Details.triggeredComponentAttacks | Unknown | Triggered component attack. |
| NSM.Alerts.Details.sqlInjection | Unknown | SQL injection. |
| NSM.Alerts.Details.callbackDetectors | Unknown | Callback detectors. |
| NSM.Alerts.Details.exceededThreshold | Unknown | Exceeded threshold. |
| NSM.Alerts.Details.communicationRuleMatch | Unknown | Communication rule match. |
| NSM.Alerts.Description | String | Description. |
| NSM.Alerts.Description.btp | String | Benign Trigger Probability (BTP). |
| NSM.Alerts.Description.rfSB | String | Recommended For Smart Blocking (RFSB). |
| NSM.Alerts.Description.protectionCategory | String | Protection category. |
| NSM.Alerts.Description.target | String | The target. |
| NSM.Alerts.Description.httpResponseAttack | String | HTTP response attack. |
| NSM.Alerts.Description.priority | String | Priority. |
| NSM.Alerts.Protocols | String | Protocols. |
| NSM.Alerts.Attack.attackCategory | String | Attack category. |
| NSM.Alerts.Attack.attackSubCategory | String | Attack sub-category. |
| NSM.Alerts.Description.snortEngine | String | Snort engine. |
| NSM.Alerts.Description.versionAdded | String | The date the version was added. |
| NSM.Alerts.Description.versionUpdated | Unknown | The date the version was updated. |
| NSM.Alerts.Attack.nspId | String | Network Security Platform (NSP) ID. |
| NSM.Alerts.Description.reference.cveId | String | Common Vulnerabilities and Exposures (CVE) ID. |
| NSM.Alerts.Description.reference.microsoftId | String | Microsoft ID. |
| NSM.Alerts.Description.reference.bugtraqId | String | Bugtraq ID. |
| NSM.Alerts.Description.reference.certId | Unknown | Cert ID. |
| NSM.Alerts.Description.reference.arachNidsId | String | Arachnics ID. |
| NSM.Alerts.Description.reference.additionInfo | String | Additional information. |
| NSM.Alerts.Description.comments.comments | String | Comments. |
| NSM.Alerts.Description.comments.availabeToChildDomains | Boolean | Whether the alert is available to child domains. |
| NSM.Alerts.Description.comments.parentDomainComments | Unknown | Parent domain comments. |
| NSM.Alerts.Event.direction | String | The event direction. |
| NSM.Alerts.Event.interface | String | The event interface. |
Command example
!nsm-get-alert-details alert_id=6666666666666666666 sensor_id=1001
Context Example
{
"NSM": {
"Alerts": {
"ID": "6666666666666666666",
"Name": "Buffer Overflow",
"uniqueAlertId": "3333333333333333333",
"State": "UnAcknowledged",
"CreatedTime": "Apr 23, 2020 22:26:13",
"Assignee": "---",
"Description": "some description",
"EventResult": "Inconclusive",
"Attack": {
"attackCategory": "Exploit",
"attackSubCategory": "Buffer Overflow",
"nspId": "0x00000000"
},
"Protocols": "dns",
"SensorID": "1001",
"Event": {
"application": "Not Available",
"protocol": "telnet",
"domain": "/My Domain",
"manager": null,
"device": "vm600-nsmapi-cc",
"interface": "1-2",
"matchedPolicy": "Default Prevention",
"zone": null,
"vlan": "-10",
"detection": "Application anomaly",
"direction": "Inbound",
"attackCount": 1,
"relevance": "Unknown",
"alertId": "6666666666666666666"
},
"Attacker": {
"ipAddrs": "9.9.9.9",
"port": 11111,
"hostName": null,
"country": null,
"os": "Microsoft Windows Server 2008",
"vmName": null,
"proxyIP": null,
"user": "Unknown",
"risk": "N/A",
"networkObject": "---"
},
"Target": {
"ipAddrs": "1.1.1.1",
"port": 88888,
"hostName": null,
"country": null,
"os": "Microsoft Windows Server 2003 Service Pack 1",
"vmName": null,
"proxyIP": null,
"user": "Unknown",
"risk": "N/A",
"networkObject": "---"
},
"MalwareFile": null,
"summary": {
"source": null,
"destination": null,
"zoombie": null,
"cAndcServer": null,
"fastFluxAgent": null,
"attackedHIPEndpoint": null,
"compromisedEndpoint": null
},
"Details": {
"matchedSignature": {
"signatureName": "overflow-iquery.c",
"signature": {
"name": "Signature#1",
"conditions": [
"condition 1",
"condition 2",
"condition 3",
"condition 4"
]
}
},
"layer7": null,
"hostSweep": null,
"portScan": null,
"fastFlux": null,
"triggeredComponentAttacks": null,
"sqlInjection": null,
"callbackDetectors": null,
"exceededThreshold": null,
"communicationRuleMatch": null
},
"description": {
"btp": "Low",
"rfSB": "Yes",
"protectionCategory": "[Server Protection/Name Servers]",
"target": "Server",
"httpResponseAttack": "No",
"priority": "High",
"reference": {
"cveId": "CVE-1999-0009",
"microsoftId": "",
"bugtraqId": "123",
"certId": null,
"arachNidsId": "",
"additionInfo": "http://www.website.com/"
},
"signatures": [
{
"name": "Signature#1",
"conditions": [
"condition 1",
"condition 2",
"condition 3",
"condition 4"
]
},
{
"name": "Signature#2",
"conditions": [
"condition 1",
"condition 2",
"condition 3",
"condition 4"
]
},
{
"name": "Signature#3",
"conditions": [
"condition 1",
"condition 2",
"condition 3",
"condition 4",
"condition 5"
]
}
],
"componentAttacks": [],
"comments": {
"comments": "",
"availabeToChildDomains": true,
"parentDomainComments": null
}
}
}
}
}
Human Readable Output
Alerts list. Showing 2 of 20
ID Name Event Time State Direction Result Attack Count Attacker IP Target IP 6666666666666666666 Buffer Overflow Apr 23, 2020 22:26:13 UnAcknowledged Inbound Inconclusive 1 9.9.9.9 1.1.1.1
nsm-get-attacks
If an attack is given, the command returns the details for the specific attack. Otherwise, gets all available attack definitions in the Manager UI. This command can take a few minutes. If you get a timeout error, increase the timeout by using the parameter “execution-timeout”.
Base Command
nsm-get-attacks
Input
| Argument Name | Description | Required |
|---|---|---|
| attack_id | The ID of the attack. To get the attack_id, use the !nsm-get-attacks command, without an attack ID. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| InfoFile.Name | string | File name. |
| InfoFile.EntryID | string | The entry ID of the report. |
| InfoFile.Size | number | File size. |
| InfoFile.Type | string | File type, e.g., “PE”. |
| InfoFile.Info | string | Basic information about the file. |
| NSM.Attacks.Direction | Unknown | Attack direction. |
| NSM.Attacks.Severity | Number | Attack severity. |
| NSM.Attacks.ID | String | Attack ID. |
| NSM.Attacks.Name | String | Attack name. |
| NSM.Attacks.Category | String | Attack category. |
| NSM.Attacks.description.definition | String | Attack Definition |
| NSM.Attacks.description.btp | String | Benign Trigger Probability (BTP). |
| NSM.Attacks.description.rfSB | String | Recommended For Smart Blocking (RFSB). |
| NSM.Attacks.description.protectionCategory | String | Protection category. |
| NSM.Attacks.description.target | String | Attack target. |
| NSM.Attacks.description.httpResponseAttack | String | HTTP Response Attack. |
| NSM.Attacks.description.priority | String | Attack priority. |
| NSM.Attacks.description.protocols | String | Attack protocols. |
| NSM.Attacks.description.attackCategory | String | Attack category. |
| NSM.Attacks.description.attackSubCategory | String | Attack sub-category. |
| NSM.Attacks.description.snortEngine | String | Attack snort engine. |
| NSM.Attacks.description.versionAdded | String | The date the attack version was added. |
| NSM.Attacks.description.versionUpdated | String | The date the attack version was updated. |
| NSM.Attacks.description.reference.nspId | String | Attack Network Security Platform (NSP) ID. |
| NSM.Attacks.description.reference.cveId | String | Attack Common Vulnerabilities and Exposures (CVE) ID. |
| NSM.Attacks.description.reference.microsoftId | String | Attack Microsoft ID. |
| NSM.Attacks.description.reference.bugtraqId | String | Attack bugtraq ID. |
| NSM.Attacks.description.reference.certId | String | Attack cert ID. |
| NSM.Attacks.description.reference.arachNidsId | String | Arachnids ID. |
| NSM.Attacks.description.reference.additionInfo | Unknown | Additional information. |
| NSM.Attacks.description.comments.comments | String | Comments. |
| NSM.Attacks.description.comments.availabeToChildDomains | Boolean | Whether the attack is available to child domains. |
| NSM.Attacks.description.comments.parentDomainComments | Unknown | Parent domain comments. |
Command example
!nsm-get-attacks attack_id=0x00000100
Context Example
{
"NSM": {
"Attacks": {
"Category": null,
"Direction": null,
"ID": "0x00000100",
"Name": "IP: too Large",
"Severity": 5,
"UiCategory": "EXPLOIT"
}
}
}
Human Readable Output
Attack no.0x00000100
ID Name Severity 0x00000100 IP: too Large 5
nsm-get-domains
If a domain ID is given, the command returns the details of the specific domain. Otherwise, gets all available domains.
Base Command
nsm-get-domains
Input
| Argument Name | Description | Required |
|---|---|---|
| domain_id | Specific domain ID. Leave blank for all domains. To get the domain_id use !nsm-get-domains command and leave the parameter blank. | Optional |
| limit | The maximum number of records to return. Default is 50.0. | Optional |
| page | The specific result page to display. | Optional |
| page_size | The number of records in a page. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Domains.ID | Number | Domain ID. |
| NSM.Domains.Name | String | Domain name. |
| NSM.Domains.childdomains | Unknown | The children of the domain. |
Command example
#### Context Example
```json
{
"NSM": {
"Domains": {
"ID": 0,
"Name": "My Company",
"childdomains": []
}
}
}
Human Readable Output
List of Domains
ID Name 0 My Company
nsm-get-sensors
Gets the list of sensors available in the specified domain. If the domain is not specified, details of all the sensors in all ADs will be provided.
Base Command
nsm-get-sensors
Input
| Argument Name | Description | Required |
|---|---|---|
| domain_id | Specific domain ID. Leave blank for all domains. To get the domain_id use !nsm-get-domains command and leave the parameter blank. | Optional |
| limit | The maximum number of records to return. Default is 50. | Optional |
| page | The specific result page to display. | Optional |
| page_size | The number of records in a page. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Sensors.ID | Number | Sensor ID. |
| NSM.Sensors.Name | String | Name of the sensor. |
| NSM.Sensors.model | String | Sensor model. |
| NSM.Sensors.Description | String | Sensor description. |
| NSM.Sensors.DomainID | Number | ID of the domain to which this sensor belongs. |
| NSM.Sensors.isFailOver | Boolean | Whether the sensor is failover. |
| NSM.Sensors.isNTBA | Boolean | Whether there is Network Threat Behavior Analysis (NTBA). |
| NSM.Sensors.isLoadBalancer | Boolean | Whether the sensor is a load balancer. |
| NSM.Sensors.SerialNumber | Unknown | The sensor serial number. |
| NSM.Sensors.SigsetVersion | String | Signature set version number applied to the sensor. |
| NSM.Sensors.DATVersion | String | DAT version of the sensor. |
| NSM.Sensors.SoftwareVersion | String | Sensor software version. |
| NSM.Sensors.LastSignatureUpdateTs | Date | Last configuration download timestamp. |
| NSM.Sensors.IPSPolicyID | Number | Intrusion prevent system (IPS) policy ID applied to the sensor. |
| NSM.Sensors.ReconPolicyID | Number | Recon policy ID applied to the sensor. |
| NSM.Sensors.LastModTs | Unknown | Last modified timestamp. |
| NSM.Sensors.IP Address | String | Sensor IP address. |
| NSM.Sensors.nsmVersion | String | Network Security Manager (NSM) version. |
| NSM.Sensors.MemberSensors | Unknown | Sensors members. |
Command example
#### Context Example
```json
{
"NSM": {
"Sensors": {
"DATVersion": null,
"Description": "MCAFEE-NETWORK-SECURITY-PLATFORM",
"DomainID": 0,
"ID": 1111,
"IP Address": "1.1.1.1",
"IPSPolicyID": 0,
"LastModTs": null,
"LastSignatureUpdateTs": "2022-12-04 02:07:45",
"MemberSensors": [],
"Name": "VVVV1",
"ReconPolicyID": 0,
"SigsetVersion": null,
"SoftwareVersion": "9.9.9.9",
"isFailOver": false,
"isLoadBalancer": false,
"model": "IPS-VM100",
"nsmVersion": "9.1"
}
}
}
Human Readable Output
Sensors List
ID Name Description DomainID IPSPolicyID IP Address 1111 VVVV1 MCAFEE-NETWORK-SECURITY-PLATFORM 0 0 1.1.1.1
nsm-get-ips-policies
Gets all the IPS policies defined in the specific domain.
Base Command
nsm-get-ips-policies
Input
| Argument Name | Description | Required |
|---|---|---|
| domain_id | Specific domain ID. To get the domain_id use !nsm-get-domains command and leave the parameter blank. | Required |
| limit | The maximum number of records to return. Default is 50. | Optional |
| page | The specific result page to display. | Optional |
| page_size | The number of records in a page. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.IPSPolicies.IsEditable | Boolean | Whether the IPS policy is editable. |
| NSM.IPSPolicies.DomainID | Number | ID of the domain to which this policy belongs. |
| NSM.IPSPolicies.VisibleToChildren | Boolean | Policy visible to child domain. |
| NSM.IPSPolicies.ID | Number | IPS policy ID. |
| NSM.IPSPolicies.Name | String | IPS policy name. |
Command example
!nsm-get-ips-policies domain_id=0 limit=2
Context Example
{
"NSM": {
"IPSPolicies": [
{
"DomainID": 0,
"ID": -1,
"IsEditable": true,
"Name": "Master",
"VisibleToChildren": true
},
{
"DomainID": 0,
"ID": 0,
"IsEditable": true,
"Name": "Default",
"VisibleToChildren": true
}
]
}
}
Human Readable Output
IPS Policies List of Domain no.0
ID Name DomainID IsEditable VisibleToChildren -1 Master 0 true true 0 Default 0 true true
nsm-get-ips-policy-details
Gets all the IPS policies defined in the specific domain.
Base Command
nsm-get-ips-policy-details
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_id | Specific IPS policy ID. To get the policy_id use !nsm-get-ips-policies command. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.IPSPolicies.ID | number | IPS policy ID. |
| NSM.IPSPolicies.Name | string | IPS policy name. |
| NSM.IPSPolicies.Description | string | IPS policy information. |
| NSM.IPSPolicies.CreatedTime | string | Policy creation time. |
| NSM.IPSPolicies.IsEditable | boolean | Whether the IPS policy is editable. |
| NSM.IPSPolicies.VisibleToChildren | boolean | Whether the IPS Policy is visible to the domain’s children. |
| NSM.IPSPolicies.Version | number | IPS policy version. |
| NSM.IPSPolicies.InboundRuleSet | string | Inbound rule set. |
| NSM.IPSPolicies.OutboundRuleSet | string | Outbound rule set. |
| NSM.IPSPolicies.ExploitAttacks | Unknown | A list of exploit attacks related to the IPS policy. |
Command example
!nsm-get-ips-policy-details policy_id=17
Context Example
{
"NSM": {
"IPSPolicies": {
"ID": 17,
"Name": "IpsPolicy",
"Description": "To test the IPS policy",
"VisibleToChildren": true,
"InboundRuleSet": "TestIPS",
"OutboundRuleSet": "Null",
"ExpolitAttack":
[
{
"attackName": "FTP: VMware",
"nspId": "0x00000000",
"severity": 7,
"isSeverityCustomized": false,
"isEnabled": true,
"isAlertCustomized": false,
"isRecommendedForSmartBlocking": false,
"AttackResponse":
{
"TCPReset": "DISABLED",
"isTcpResetCustomized": false,
"isICMPSend": false,
"isICMPSendCustomized": false,
"mcAfeeNACNotification": "DISABLED",
"isMcAfeeNACNotificationEnabled": false,
"isQuarantineCustomized": false,
"isRemediateEnabled": false,
"blockingOption": "DISABLE",
"isBlockingOptionCustomized": false,
"isCapturedPrior": true,
"isCapturedPriorCustomized": false,
"action": "SEND_ALERT_ONLY",
"isLogCustomized": false,
"isFlowCustomized": false,
"isNbytesCustomized": false,
"numberOfBytesInEachPacket":
{
"LogEntirePacket":
{
}
}
},
"notification":
{
"isEmail": false,
"isPager": false,
"isScript": false,
"isAutoAck": false,
"isSnmp": false,
"isSyslog": false,
"isEmailCustomized": false,
"isPagerCustomized": false,
"isScriptCustomized": false,
"isAutoAckCustomized": false,
"isSnmpCustomized": false,
"isSyslogCustomized": false
},
"protocolList":
[
"ftp"
],
"benignTriggerProbability": "1 (Low)",
"blockingType": "attack-packet",
"subCategory": "code-execution",
"direction": "INBOUND",
"isAttackCustomized": false
}
],
"AttackCategory":
{
},
"OutboundAttackCategory":
{
},
"DosPolicy":
{
"LearningAttack":
[
{
"attackName": "TCP Control Segment Anomaly",
"nspId": "0x00000000",
"isSeverityCustomized": false,
"severity": 7,
"isBlockingSettingCustomized": false,
"isDropPacket": false,
"IsAlertCustomized": false,
"isSendAlertToManager": true,
"direction": "BOTH",
"notification":
{
"isEmail": false,
"isPager": false,
"isScript": false,
"isAutoAck": false,
"isSnmp": false,
"isSyslog": false,
"isEmailCustomized": false,
"isPagerCustomized": false,
"isScriptCustomized": false,
"isAutoAckCustomized": false,
"isSnmpCustomized": false,
"isSyslogCustomized": false
},
"isAttackCustomized": false
}
],
"ThresholdAttack":
[
{
"attackName": "Too Many Inbound TCP SYNs",
"nspId": "0x00000000",
"isSeverityCustomized": false,
"severity": 6,
"isThresholdValueCustomized": false,
"isThresholdDurationCustomized": false,
"ThresholdValue": 2000,
"ThresholdDuration": 5,
"isAlertCustomized": false,
"isSendAlertToManager": false,
"Notification":
{
"isEmail": false,
"isPager": false,
"isScript": false,
"isAutoAck": false,
"isSnmp": false,
"isSyslog": false,
"isEmailCustomized": false,
"isPagerCustomized": false,
"isScriptCustomized": false,
"isAutoAckCustomized": false,
"isSnmpCustomized": false,
"isSyslogCustomized": false
},
"direction": "INBOUND",
"isAttackCustomized": false
}
],
"TimeStamp": "2012-06-20 18:44:55.000"
},
"DosResponseSensitivityLevel": 0,
"IsEditable": false,
"CreatedTime": "2012-06-20 18:44:55.000",
"Version": 1,
"IsLightWeightPolicy": false
}
}
}
Human Readable Output
IPS Policy no.17 Details
ID Name Description CreatedTime IsEditable VisibleToChildren Version InboundRuleSet OutboundRuleSet 17 IpsPolicy To test the IPS policy To test the IPS policy false true 1 To test the IPS policy Null
nsm-update-alerts
Update state or assignee of alerts. It is required to provide at least one of them. If none of the alerts match the time_period they won’t be updated.
Base Command
nsm-update-alerts
Input
| Argument Name | Description | Required |
|---|---|---|
| state | Alert state. Possible values are: ANY, Acknowledged, Unacknowledged. Default is ANY. | Optional |
| time_period | Time period. Possible values are: LAST_5_MINUTES, LAST_1_HOUR, LAST_6_HOURS, LAST_12_HOURS, LAST_24_HOURS, LAST_7_DAYS, LAST_14_DAYS, CUSTOM. Default is LAST_7_DAYS. | Optional |
| start_time | Start time in “mm/dd/yyyy HH:MM” format. Used for custom time only. | Optional |
| end_time | End time in “mm/dd/yyyy HH:MM” format. Used for custom time only. | Optional |
| new_state | The new alert state. Possible values are: Acknowledged, Unacknowledged. | Optional |
| new_assignee | The new assignee. | Optional |
| search | Search string in alert details. | Optional |
| filter | Filter alert by fields. example: “name:hello;direction:Inbound,Outbound;attackcount:>3,<4”. To use the “name” field in the filter, enter only one name in each command run. Filter on the following columns is allowed - name, assignTo, application, layer7Data, result, attackCount, relevance, alertId, direction, device, domain, interface, attackSeverity, nspId, btp, attackCategory, malwarefileName, malwarefileHash, malwareName, malwareConfidence, malwareEngine ,executableName, executableHash, executableConfidenceName, attackerIPAddress, attackerPort, attackerRisk, attackerProxyIP, attackerHostname, targetIPAddress, targetPort, targetRisk, targetProxyIP, targetHostname, botnetFamily. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Alerts.ID | number | Alert ID. |
| NSM.Alerts.Name | String | Alert name. |
| NSM.Alerts.uniqueAlertId | String | Unique alert ID. |
| NSM.Alerts.State | String | Alert state (Acknowledged,Unacknowledged). |
| NSM.Alerts.Assignee | String | Alert assignee. |
| NSM.Alerts.CreatedTime | String | Alert creation time. |
| NSM.Alerts.AttackSeverity | String | Alert severity. |
| NSM.Alerts.Event.time | Date | The creation time of the event that triggered the alert. |
| NSM.Alerts.Event.direction | String | The direction of the event (Outbound, Inbound). |
| NSM.Alerts.Event.result | String | The result of the event. |
| NSM.Alerts.Event.attackCount | Number | Attack count. |
| NSM.Alerts.Event.relevance | String | The event relevance. |
| NSM.Alerts.Event.alertId | String | Alert ID. |
| NSM.Alerts.Event.domain | String | The domain. |
| NSM.Alerts.Event.interface | String | The event’s interface. |
| NSM.Alerts.Event.device | String | The relevant device. |
| NSM.Alerts.Attack.nspId | String | Network Security Platform (NSP) ID. |
| NSM.Alerts.Attack.btp | String | Benign Trigger Probability (BTP). |
| NSM.Alerts.Attack.attackCategory | String | The attack category. |
| NSM.Alerts.Attacker.ipAddrs | String | The attacker IP address. |
| NSM.Alerts.Attacker.port | Number | The port. |
| NSM.Alerts.Attacker.hostName | String | The attacker host name. |
| NSM.Alerts.Attacker.country | String | The attacker country. |
| NSM.Alerts.Attacker.os | Unknown | The attacker operating system. |
| NSM.Alerts.Attacker.vmName | Unknown | The attacker VM name. |
| NSM.Alerts.Attacker.proxyIP | String | The attacker proxy IP. |
| NSM.Alerts.Attacker.user | Unknown | The user. |
| NSM.Alerts.Attacker.risk | String | Attacker risk. |
| NSM.Alerts.Attacker.networkObject | Unknown | The attacker network object. |
| NSM.Alerts.Target.ipAddrs | String | The target IP address. |
| NSM.Alerts.Target.port | Number | The target port. |
| NSM.Alerts.Target.hostName | String | The target host name. |
| NSM.Alerts.Target.country | String | The target country. |
| NSM.Alerts.Target.os | Unknown | The target operating system. |
| NSM.Alerts.Target.vmName | Unknown | The target VM name. |
| NSM.Alerts.Target.proxyIP | String | The target proxy IP. |
| NSM.Alerts.Target.user | Unknown | The target user. |
| NSM.Alerts.Target.risk | String | The target risk. |
| NSM.Alerts.Target.networkObject | Unknown | The target network object. |
| NSM.Alerts.MalwareFile.fileName | String | The name of the malware file. |
| NSM.Alerts.MalwareFile.fileHash | String | The file hash of the malware file. |
| NSM.Alerts.MalwareFile.fileSHA1Hash | String | The malware file SHA1 hash. |
| NSM.Alerts.MalwareFile.fileSHA256Hash | Unknown | The file SHA256 hash of the malware file. |
| NSM.Alerts.MalwareFile.malwareName | String | The name of the malware. |
| NSM.Alerts.MalwareFile.malwareConfidence | String | Malware confidence. |
| NSM.Alerts.MalwareFile.engine | String | Malware file engine. |
| NSM.Alerts.MalwareFile.engineId | Number | Malware file engine ID. |
| NSM.Alerts.MalwareFile.size | Unknown | The Malware file size. |
| NSM.Alerts.MalwareFile.description | Unknown | Malware file description. |
| NSM.Alerts.MalwareFile.additionalReference | Unknown | Malware file additional reference. |
| NSM.Alerts.MalwareFile.cveId | Unknown | Malware File CVE ID. |
| NSM.Alerts.endpointExcutable.name | String | Endpoint executable name. |
| NSM.Alerts.endpointExcutable.hash | String | Endpoint executable hash. |
| NSM.Alerts.endpointExcutable.malwareConfidence | String | Endpoint executable malware confidence. |
| NSM.Alerts.detection.managerId | Number | Manager ID. |
| NSM.Alerts.detection.manager | Unknown | The detection manager. |
| NSM.Alerts.detection.domain | String | Detection domain. |
| NSM.Alerts.detection.device | String | Detection device. |
| NSM.Alerts.detection.deviceId | String | Detection device ID. |
| NSM.Alerts.detection.interface | String | Detection interface. |
| NSM.Alerts.Application | String | The application associated with the alert. |
| NSM.Alerts.layer7Data | String | Layer 7 information. |
| NSM.Alerts.EventResult | String | Event result. |
| NSM.Alerts.SensorID | String | Sensor ID. |
Command example
!nsm-update-alerts state=Unacknowledged new_state=Acknowledged 'time_period': 'CUSTOM', 'start_time': '12/17/2000 14:14:22', 'end_time': '12/28/2022 00:26:45'
Context Example
{
"NSM": {
"Alerts": [
{
"Application": "HTTP",
"Assignee": "",
"Attack": {
"attackCategory": "Exploit",
"btp": "Medium",
"nspId": "0x00000000"
},
"Attacker": {
"country": null,
"hostName": "",
"ipAddrs": "1.1.1.1",
"networkObject": null,
"os": null,
"port": 22222,
"proxyIP": "",
"risk": "Disabled",
"user": null,
"vmName": null
},
"CreatedTime": "Dec 17, 2018 21:06:21",
"Event": {
"alertId": "3333333333333333333",
"attackCount": 1,
"device": "VVVV1",
"direction": "Outbound",
"domain": "/My Domain",
"interface": "1-2",
"relevance": "Unknown",
"result": "Inconclusive",
"time": "Dec 17, 2018 21:06:21"
},
"EventResult": "Inconclusive",
"ID": "3333333333333333333",
"MalwareFile": {
"additionalReference": null,
"cveId": null,
"description": null,
"engine": "",
"engineId": 0,
"fileHash": "",
"fileName": "",
"malwareConfidence": "",
"malwareName": "",
"size": null
},
"Name": "HTTP: vulnerability",
"SensorID": "4444",
"Target": {
"country": null,
"hostName": "",
"ipAddrs": "2.2.2.2",
"networkObject": null,
"os": null,
"port": 80,
"proxyIP": "",
"risk": "Disabled",
"user": null,
"vmName": null
},
"State": "Acknowledged",
"attackSeverity": "High",
"detection": {
"device": "VVVV1",
"deviceId": "4444",
"domain": "/My Domain",
"interface": "1-2",
"manager": null,
"managerId": 0
},
"endpointExcutable": {
"hash": "",
"malwareConfidence": "",
"name": ""
},
"layer7Data": "HTTP Request Method: GET",
"uniqueAlertId": "1212121212121212121"
},
{
"Application": "WebDAV",
"Assignee": "",
"Attack": {
"attackCategory": "Exploit",
"btp": "Low",
"nspId": "0x00000000"
},
"Attacker": {
"country": null,
"hostName": "",
"ipAddrs": "1.1.1.1",
"networkObject": null,
"os": null,
"port": 11111,
"proxyIP": "",
"risk": "---",
"user": null,
"vmName": null
},
"CreatedTime": "Dec 17, 2018 21:04:21",
"Event": {
"alertId": "5555555555555555555",
"attackCount": 1,
"device": "VVVV1",
"direction": "Inbound",
"domain": "/My Dmain",
"interface": "1-2",
"relevance": "Unknown",
"result": "Inconclusive",
"time": "Dec 17, 2018 21:04:21"
},
"EventResult": "Inconclusive",
"ID": "5555555555555555555",
"MalwareFile": {
"additionalReference": null,
"cveId": null,
"description": null,
"engine": "",
"engineId": 0,
"fileHash": "",
"fileName": "",
"malwareConfidence": "",
"malwareName": "",
"size": null
},
"Name": "HTTP: IIS 6.0 (CVE-2017-7269)",
"SensorID": "4444",
"Target": {
"country": null,
"hostName": "",
"ipAddrs": "2.2.2.2",
"networkObject": null,
"os": null,
"port": 80,
"proxyIP": "",
"risk": "---",
"user": null,
"vmName": null
},
"alertState": "Acknowledged",
"attackSeverity": "High",
"detection": {
"device": "VVVV1",
"deviceId": "4444",
"domain": "/My Domain",
"interface": "1-2",
"manager": null,
"managerId": 0
},
"endpointExcutable": {
"hash": "",
"malwareConfidence": "",
"name": ""
},
"layer7Data": "HTTP Request Method: PROPFIND",
"uniqueAlertId": "2323232323232323232"
}
]
}
}
Human Readable Output
Updated Alerts list. Showing 2 of 20
ID Name Severity State 3333333333333333333 HTTP: vulnerability High Acknowledged 5555555555555555555 HTTP: IIS 6.0 (CVE-2017-7269) High Acknowledged
nsm-list-pcap-file
Retrieves the list of captured PCAP files.
Base Command
nsm-list-pcap-file
Input
| Argument Name | Description | Required |
|---|---|---|
| sensor_id | The ID of the sensor. To get the sensor_id, use the !nsm-get-sensors command. | Required |
| limit | The maximum number of records to return. Default is 50. | Optional |
| page | The specific result page to display. The default is 1. | Optional |
| page_size | The number of records in a page. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.PcapFile | string | PCAP file name. |
Command example
!nsm-update-alerts state=Unacknowledged new_state=Acknowledged 'time_period': 'CUSTOM', 'start_time': '12/17/2000 14:14:22', 'end_time': '12/28/2022 00:26:45'
Context Example
{
"NSM": {
"PcapFile": [
{
"files":["capture_Mon_Aug_18_16_12_49_IST_2014.pcap", "capture_Mon_Aug_18_16_12_55_IST_2014.pcap"]
}
]
}
}
Human Readable Output
PCAP files List
FileName capture_Mon_Aug_18_16_12_49_IST_2014.pcap capture_Mon_Aug_18_16_12_55_IST_2014.pcap
nsm-export-pcap-file
Exports the captured PCAP file.
Base Command
nsm-export-pcap-file
Input
| Argument Name | Description | Required |
|---|---|---|
| sensor_id | The ID of the sensor. To get the sensor_id, use the command !nsm-get-sensors. | Required |
| file_name | The name of the wanted file. To get the file_name, use the command !nsm-list-pcap-file. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| InfoFile.Name | string | File name. |
| InfoFile.EntryID | string | The entry ID of the report. |
| InfoFile.Size | number | File size. |
| InfoFile.Type | string | File type, e.g., “PE”. |
| InfoFile.Info | string | Basic information about the file. |
Command example
!nsm-export-pcap-file sensor_id=1003 file_name=Dummy Device Name-PacketCapture-2022-12-21_16-25-52.pcap
Human Readable Output
There isn’t a human readable.
Breaking changes from the previous version of this integration - McAfee NSM v2
The following sections list the changes in this version.
Arguments
The following arguments were removed in this version
In the nsm-get-sensors command:
- domainID - this argument was replaced by domain_id.
In the nsm-get-domains command:
- domain - this argument was replaced by domain_id.
The behavior of the following arguments was changed
In the nsm-get-alerts command:
- time_period - The default value changed to ‘LAST_7_DAYS’.
- domain_id - The default value changed to 0.
In the nsm-get-alert-details command:
- sensor_id - Is now required.
nsm-list-domain-device
List the devices related to a given domain.
Base Command
nsm-list-domain-device
Input
| Argument Name | Description | Required |
|---|---|---|
| domain_id | The ID of the domain. To get the domain_id, use the !nsm-get-domains command. | Required |
| limit | The maximum number of devices to return. | Optional |
| all_results | Return all devices related to the given domain. Possible values are: yes, no. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Device.ContactInformation | string | The contact information of the device. |
| NSM.Device.DeviceId | number | The id of the device. |
| NSM.Device.DeviceName | string | The name of the device. |
| NSM.Device.DeviceType | string | The type of the device. |
| NSM.Device.Location | string | The location of the device. |
| NSM.Device.UpdatingMode | string | The updating mode of the device. |
Command example
!nsm-list-domain-device domain_id=0
Context Example
{
"NSM": {
"Device": [
{
"ContactInformation": null,
"DeviceId": 1003,
"DeviceName": "Dummy Device Name",
"DeviceType": "IPS_NAC_SENSOR",
"Location": null,
"UpdatingMode": "ONLINE"
}
]
}
}
Human Readable Output
Domain devices List
DeviceId DeviceName DeviceType UpdatingMode 1003 Dummy Device Name IPS_NAC_SENSOR ONLINE
nsm-list-device-interface
List the interfaces related to a given device.
Base Command
nsm-list-device-interface
Input
| Argument Name | Description | Required |
|---|---|---|
| domain_id | The ID of the domain. To get the domain_id, use the !nsm-get-domains command. | Required |
| device_id | The ID of the device. To get the device ID, use the !nsm-list-domain-device command. | Required |
| limit | The maximum number of interfaces to return. | Optional |
| all_results | Return all interfaces related to the given device. Possible values are: yes, no. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.Interface.InterfaceId | number | The id of the interface. |
| NSM.Interface.InterfaceName | Unknown | The name of the interface. |
| NSM.Interface.InterfaceType | string | The type of the interface. |
Command example
!nsm-list-device-interface device_id=1003 domain_id=0
Context Example
{
"NSM": {
"Interface": [
{
"InterfaceId": 102,
"InterfaceName": "5-6",
"InterfaceType": "Dedicated"
},
{
"InterfaceId": 103,
"InterfaceName": "3-4",
"InterfaceType": "Dedicated"
},
{
"InterfaceId": 104,
"InterfaceName": "1-2",
"InterfaceType": "Dedicated"
}
]
}
}
Human Readable Output
Device interfaces List
InterfaceId InterfaceName InterfaceType 102 5-6 Dedicated 103 3-4 Dedicated 104 1-2 Dedicated
nsm-list-device-policy
List all the policies assigned to a domain or a specific device.
Base Command
nsm-list-device-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| domain_id | The ID of the domain. To get the domain_id, use the !nsm-get-domains command. | Required |
| device_id | The ID of the device. To get the device ID, use the !nsm-list-domain-device command. | Optional |
| limit | The maximum number of policies to return. | Optional |
| all_results | Return all policies assigned to a domain or a specific device. Possible values are: yes, no. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.DevicePolicy.DeviceName | string | The name of the device. |
| NSM.DevicePolicy.AtdUserForInboundATDAnalysis | Unknown | |
| NSM.DevicePolicy.InterfaceName | string | The name of the interface. |
| NSM.DevicePolicy.FirewallPolicyLast | Unknown | |
| NSM.DevicePolicy.ReconnaissancePolicy | Unknown | |
| NSM.DevicePolicy.PolicyGroup | Unknown | |
| NSM.DevicePolicy.AtdUserForOutboundATDAnalysis | Unknown | |
| NSM.DevicePolicy.DeviceId | number | The id of the device. |
| NSM.DevicePolicy.AdvancedMalwareOutboundPolicy | Unknown | |
| NSM.DevicePolicy.QosInboundPolicy | Unknown | |
| NSM.DevicePolicy.ConnectionLimitingPolicy | Unknown | |
| NSM.DevicePolicy.QosOutboundPolicy | Unknown | |
| NSM.DevicePolicy.ProtectionOptionsPolicy | Unknown | |
| NSM.DevicePolicy.AdvancedMalwareInboundPolicy | Unknown | |
| NSM.DevicePolicy.QosOutboundRateLimitingProfile | Unknown | |
| NSM.DevicePolicy.IpsPolicy | Unknown | |
| NSM.DevicePolicy.QosInboundRateLimitingProfile | Unknown | |
| NSM.DevicePolicy.FirewallPolicyFirst | Unknown |
Command example
!nsm-list-device-policy domain_id=0
Context Example
{
"NSM": {
"DevicePolicy": [
{
"AdvancedMalwareInboundPolicy": null,
"AdvancedMalwareOutboundPolicy": null,
"AtdUserForInboundATDAnalysis": null,
"AtdUserForOutboundATDAnalysis": null,
"ConnectionLimitingPolicy": null,
"DeviceId": 1003,
"DeviceName": "Dummy Device Name",
"FirewallPolicy": null,
"FirewallPolicyFirst": "Test",
"FirewallPolicyLast": null,
"FirewallPortPolicy": null,
"InterfaceId": 0,
"InterfaceName": null,
"IpsPolicy": null,
"PolicyGroup": null,
"ProtectionOptionsPolicy": null,
"QosInboundPolicy": null,
"QosInboundRateLimitingProfile": null,
"QosOutboundPolicy": null,
"QosOutboundRateLimitingProfile": null,
"ReconnaissancePolicy": null
}
]
}
}
Human Readable Output
Device policy List
DeviceId DeviceName FirewallPolicyFirst InterfaceId 1003 Dummy Device Name Test 0
nsm-list-interface-policy
List all the policies assigned to all interfaces or a specific interface.
Base Command
nsm-list-interface-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| domain_id | The ID of the domain. To get the domain_id, use the !nsm-get-domains command. | Required |
| interface_id | The ID of the interface. To get the interface ID, use the !nsm-list-device-interface command. | Optional |
| limit | The maximum number of policies to return. | Optional |
| all_results | Return all policies assigned to all interfaces or a specific interface. Possible values are: yes, no. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.InterfacePolicy.DeviceName | string | The name of the device. |
| NSM.InterfacePolicy.AtdUserForInboundATDAnalysis | Unknown | |
| NSM.InterfacePolicy.InterfaceName | string | The name of the interface. |
| NSM.InterfacePolicy.FirewallPolicyLast | Unknown | |
| NSM.InterfacePolicy.ReconnaissancePolicy | Unknown | |
| NSM.InterfacePolicy.PolicyGroup | Unknown | |
| NSM.InterfacePolicy.AtdUserForOutboundATDAnalysis | Unknown | |
| NSM.InterfacePolicy.DeviceId | number | The id of the device. |
| NSM.InterfacePolicy.AdvancedMalwareOutboundPolicy | Unknown | |
| NSM.InterfacePolicy.QosInboundPolicy | Unknown | |
| NSM.InterfacePolicy.ConnectionLimitingPolicy | Unknown | |
| NSM.InterfacePolicy.QosOutboundPolicy | Unknown | |
| NSM.InterfacePolicy.ProtectionOptionsPolicy | Unknown | |
| NSM.InterfacePolicy.AdvancedMalwareInboundPolicy | Unknown | |
| NSM.InterfacePolicy.QosOutboundRateLimitingProfile | Unknown | |
| NSM.InterfacePolicy.IpsPolicy | Unknown | |
| NSM.InterfacePolicy.QosInboundRateLimitingProfile | Unknown | |
| NSM.InterfacePolicy.FirewallPolicyFirst | Unknown |
Command example
!nsm-list-interface-policy domain_id=0
Context Example
{
"NSM": {
"InterfacePolicy": [
{
"AdvancedMalwareInboundPolicy": null,
"AdvancedMalwareOutboundPolicy": null,
"AtdUserForInboundATDAnalysis": null,
"AtdUserForOutboundATDAnalysis": null,
"ConnectionLimitingPolicy": null,
"DeviceId": 1003,
"DeviceName": "Dummy Device Name",
"FirewallPolicy": "a policy",
"FirewallPolicyFirst": null,
"FirewallPolicyLast": null,
"FirewallPortPolicy": null,
"InterfaceId": 104,
"InterfaceName": "1-2",
"IpsPolicy": "Default Prevention",
"PolicyGroup": null,
"ProtectionOptionsPolicy": null,
"QosInboundPolicy": null,
"QosInboundRateLimitingProfile": null,
"QosOutboundPolicy": null,
"QosOutboundRateLimitingProfile": null,
"ReconnaissancePolicy": null
},
{
"AdvancedMalwareInboundPolicy": null,
"AdvancedMalwareOutboundPolicy": null,
"AtdUserForInboundATDAnalysis": null,
"AtdUserForOutboundATDAnalysis": null,
"ConnectionLimitingPolicy": null,
"DeviceId": 1003,
"DeviceName": "Dummy Device Name",
"FirewallPolicy": null,
"FirewallPolicyFirst": null,
"FirewallPolicyLast": null,
"FirewallPortPolicy": null,
"InterfaceId": 103,
"InterfaceName": "3-4",
"IpsPolicy": "testing",
"PolicyGroup": null,
"ProtectionOptionsPolicy": null,
"QosInboundPolicy": null,
"QosInboundRateLimitingProfile": null,
"QosOutboundPolicy": null,
"QosOutboundRateLimitingProfile": null,
"ReconnaissancePolicy": null
},
{
"AdvancedMalwareInboundPolicy": null,
"AdvancedMalwareOutboundPolicy": null,
"AtdUserForInboundATDAnalysis": null,
"AtdUserForOutboundATDAnalysis": null,
"ConnectionLimitingPolicy": null,
"DeviceId": 1003,
"DeviceName": "Dummy Device Name",
"FirewallPolicy": null,
"FirewallPolicyFirst": null,
"FirewallPolicyLast": null,
"FirewallPortPolicy": null,
"InterfaceId": 102,
"InterfaceName": "5-6",
"IpsPolicy": "testing",
"PolicyGroup": null,
"ProtectionOptionsPolicy": null,
"QosInboundPolicy": null,
"QosInboundRateLimitingProfile": null,
"QosOutboundPolicy": null,
"QosOutboundRateLimitingProfile": null,
"ReconnaissancePolicy": null
}
]
}
}
Human Readable Output
Interface policy List
DeviceId DeviceName FirewallPolicy InterfaceId InterfaceName IpsPolicy 1003 Dummy Device Name a policy 104 1-2 Default Prevention 1003 Dummy Device Name 103 3-4 testing 1003 Dummy Device Name 102 5-6 testing
nsm-assign-device-policy
Assign a policy to a specific device.
Base Command
nsm-assign-device-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| domain_id | The ID of the domain. To get the domain_id, use the !nsm-get-domains command. | Required |
| device_id | The ID of the device. To get the device ID, use the !nsm-list-domain-device command. | Required |
| pre_firewall_policy_name | The name of the policy to add to the top of the rule order and evaluated first. To get the policies, use the !nsm-list-domain-firewall-policy command. | Optional |
| post_firewall_policy_name | The name of the policy to add to the end of the rule order and evaluated last. To get the policies, use the !nsm-list-domain-firewall-policy command. | Optional |
Context Output
There is no context output for this command.
Command example
!nsm-assign-device-policy device_id=1003 domain_id=0 pre_firewall_policy_name=Test
Human Readable Output
Policy assigned successfully.
nsm-assign-interface-policy
Assign a policy to a specific interface.
Base Command
nsm-assign-interface-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| domain_id | The ID of the domain. To get the domain_id, use the !nsm-get-domains command. | Required |
| interface_id | The ID of the interface. To get the interface ID, use the !nsm-list-device-interface command. | Required |
| firewall_policy_name | The name of the firewall policy that will be connected to the interface. To get the policy name, use the !nsm-list-domain-firewall-policy command. | Optional |
| firewall_port_policy_name | The name of the firewall policy that will be connected to the interface/port. To get the policy name, use the !nsm-list-domain-firewall-policy command. | Optional |
| ips_policy_name | The name of the IPS policy that will be connected to the interface. To get the policy name, use the !nsm-get-ips-policies command. | Optional |
| custom_policy_json | A Json with firewall policy types as keys and firewall policy names as values. (e.g {"advancedMalwareInboundPolicy":"test"}). To see all the firewall policy options visit this page https://docs.trellix.com/bundle/network-security-platform-9.1.x-manager-api-reference-guide/page/GUID-5E5F9514-935F-4F16-B2F0-C48E465A4E7C.html. |
Optional |
Context Output
There is no context output for this command.
Command example
!nsm-assign-interface-policy domain_id=0 interface_id=102 ips_policy_name=testing
Human Readable Output
Policy assigned successfully.
nsm-get-device-configuration
Provides configuration information of a given device.
Base Command
nsm-get-device-configuration
Input
| Argument Name | Description | Required |
|---|---|---|
| device_id | The ID of the device. To get the device ID, use the !nsm-get-sensors command. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| NSM.DeviceConfiguration.IsSSLConfigurationChanged | boolean | Was the ssl configuration changed. |
| NSM.DeviceConfiguration.DeviceName | string | The name of the device. |
| NSM.DeviceConfiguration.IsConfigurationChanged | boolean | Was the configuration changed. |
| NSM.DeviceConfiguration.IsMalwareConfigurationChanged | boolean | |
| NSM.DeviceConfiguration.LastUpdateTime | Unknown | |
| NSM.DeviceConfiguration.IsGAMUpdateRequired | boolean | |
| NSM.DeviceConfiguration.IsSignatureSetConfigurationChanged | Unknown | |
| NSM.DeviceConfiguration.IsSigsetConfigPushRequired | boolean | |
| NSM.DeviceConfiguration.IsBotnetPushRequired | boolean | |
| NSM.DeviceConfiguration.IsPolicyConfigurationChanged | boolean | |
| NSM.DeviceConfiguration.IsSSLPushRequired | boolean | |
| NSM.DeviceConfiguration.IsGloablPolicyConfigurationChanged | boolean | |
| NSM.DeviceConfiguration.IsBotnetConfigurationChanged | boolean |
Command example
!nsm-get-device-configuration device_id=1003
Context Example
{
"NSM": {
"DeviceConfiguration": {
"DeviceName": "Dummy Device Name",
"IsBotnetConfigurationChanged": false,
"IsBotnetPushRequired": false,
"IsConfigurationChanged": true,
"IsGAMUpdateRequired": false,
"IsGloablPolicyConfigurationChanged": false,
"IsMalwareConfigurationChanged": false,
"IsPolicyConfigurationChanged": false,
"IsSSLConfigurationChanged": false,
"IsSSLPushRequired": false,
"IsSignatureSetConfigurationChanged": false,
"IsSigsetConfigPushRequired": true,
"LastUpdateTime": "2023-03-25 20:52:59.600 UTC"
}
}
}
Human Readable Output
Device Configuration
DeviceName IsBotnetConfigurationChanged IsBotnetPushRequired IsConfigurationChanged IsGAMUpdateRequired IsGloablPolicyConfigurationChanged IsMalwareConfigurationChanged IsPolicyConfigurationChanged IsSSLConfigurationChanged IsSSLPushRequired IsSignatureSetConfigurationChanged IsSigsetConfigPushRequired LastUpdateTime Dummy Device Name false false true false false false false false false false true 2023-03-25 20:52:59.600 UTC
nsm-deploy-device-configuration
Deploy the pending changes.
Note: In order to avoid extra run time, it is recommended to deploy only the changes that are pending.
To get the pending changes, use the !nsm-get-device-configuration command.
Base Command
nsm-deploy-device-configuration
Input
| Argument Name | Description | Required |
|---|---|---|
| request_id | This is for the polling to work. not for the user. | Optional |
| device_id | The ID of the device. To get the device ID, use the !nsm-get-sensors command. | Required |
| push_ssl_key | Deploy the SSL configuration pending changes. Possible values are: true, false. | Optional |
| push_gam_updates | Deploy the Gateway Anti-Malware configuration pending changes. Possible values are: true, false. | Optional |
| push_configuration_signature_set | Deploy the Signature set configuration pending changes. Possible values are: true, false. | Optional |
| push_botnet | Deploy the Firewall policy description pending changes. Possible values are: true, false. | Optional |
| interval_in_seconds | The interval between status checks. | Optional |
Context Output
There is no context output for this command.
Command example
!nsm-deploy-device-configuration device_id=1003 push_configuration_signature_set="true" interval_in_seconds=10
Human Readable Output
The current percentage of deployment for ‘push_configuration_signature_set’ is: 0%
And the current message is: NA
Checking again in 10 seconds…
Configuration parameters
url— URL (for example: https://192.168.0.1:5000) (required)credentials— User Name (required)version— Product Versioninsecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (28)
-
nsm-assign-device-policyAssign a policy to a specific device.
-
nsm-assign-interface-policyAssign a policy to a specific interface.
-
nsm-create-firewall-policyAdds a new firewall policy and access rules. You have to provide at lease one of the source/destination rule objects. If you provide the id or type of the source/destination rule object, you must provide the matching type or id the source/destination rule object as well.
-
nsm-create-rule-objectAdds a new rule object. If the type is “Endpoint IP V.X” or “Network IP V.X”, only the argument “address_ip_v.X” must contain a value. If the type is “Range IP V.X”, only the arguments “from_address_ip_v.X”, “to_address_ip_v.X” must contain a value. Where X is 4 or 6 respectively.
-
nsm-delete-firewall-policyDeletes the specified firewall policy.
-
nsm-delete-rule-objectDeletes a rule object.
-
nsm-deploy-device-configurationDeploy the pending changes. Note: In order to avoid extra run time, it is recommended to deploy only the changes that are pending. To get the pending changes, use the !nsm-get-device-configuration command.
-
nsm-export-pcap-fileExports the captured PCAP file.
-
nsm-get-alert-detailsRetrieves the relevant alert details.
-
nsm-get-alertsRetrieves the alerts.
-
nsm-get-attacksIf an attack is given, the command returns the details for the specific attack. Otherwise, gets all available attack definitions in the Manager UI. This command can take a few minutes. If you get a timeout error, increase the timeout by using the parameter "execution-timeout".
-
nsm-get-device-configurationProvides configuration information of a given device.
-
nsm-get-domainsIf a domain ID is given, the command returns the details of the specific domain. Otherwise, gets all available domains.
-
nsm-get-firewall-policyGets the firewall policy details.
-
nsm-get-ips-policiesGets all the IPS policies defined in the specific domain.
-
nsm-get-ips-policy-detailsGets all the IPS policies defined in the specific domain.
-
nsm-get-rule-objectGets the details of a rule object.
-
nsm-get-sensorsGets the list of sensors available in the specified domain. If the domain is not specified, details of all the sensors in all ADs will be provided.
-
nsm-list-device-interfaceList the interfaces related to a given device.
-
nsm-list-device-policyList all the policies assigned to a domain or a specific device.
-
nsm-list-domain-deviceList the devices related to a given domain.
-
nsm-list-domain-firewall-policyGets the list of firewall policies defined in a particular domain.
-
nsm-list-domain-rule-objectGets the list of rule objects defined in a particular domain.
-
nsm-list-interface-policyList all the policies assigned to all interfaces or a specific interface.
-
nsm-list-pcap-fileRetrieves the list of captured PCAP files.
-
nsm-update-alertsUpdate state or assignee of alerts. It is required to provide at least one of them. If none of the alerts match the time_period they won't be updated.
-
nsm-update-firewall-policyUpdates the firewall policy details. If the argument is_overwrite=true, the new values of the provided addresses will replace the existing values, otherwise the addresses will be added to them. If you want to delete a rule, enter is_overwrite=true and the relevant rule_object_id=-1. If is_overwrite=false and there is no value in one of the rules (source or destination), their value will be as before. If is_overwrite=true, at least one of the rules (source or destination) must be provided. If you provide the id or type of the source/destination rule object, you must provide the matching type or id the source/destination rule object as well.
-
nsm-update-rule-objectUpdates a Rule object. In case of address rule update, if the rule type is “Endpoint IP V.X” or “Network IP V.X”, only the argument “address_ip_v.X” should contain a value. If the type is “Range IP V.X”, only the arguments “from_address_ip_v.X”, “to_address_ip_v.X” should contain a value, where X is 4 or 6 respectively.
import base64 import re from typing import Any import demistomock as demisto # noqa: F401 import urllib3 from CommonServerPython import * # noqa: F401 from requests import Response from CommonServerUserPython import * # noqa # Disable insecure warnings urllib3.disable_warnings() V10 = "V10x" V9 = "V9x" VERSION = demisto.params().get("version", V9) DEFAULT_LIMIT = 50 HOST = "HOST" ADDRESS_RANGE = "ADDRESS_RANGE" STATE_TO_NUMBER = {"Disabled": 0, "Enabled": 1} DEPLOY_ARGUMENT_MAPPER = { "push_ssl_key": "SSLPercentageComplete", "push_gam_updates": "GamUpdatePercentageComplete", "push_configuration_signature_set": "sigsetConfigPercentageComplete", "push_botnet": "botnetPercentageComplete", } MESSAGE_MAP = { "push_ssl_key": "SSLStatusMessage", "push_gam_updates": "GamUpdateStatusMessage", "push_configuration_signature_set": "sigsetConfigStatusMessage", "push_botnet": "botnetStatusMessage", } ADDRESS_LIST_MAP = { "IPv6AddressRange": "IPV6RangeList", "IPv4AddressRange": "IPV4RangeList", "HostIPv4": "hostIPv4AddressList", "HostIPv6": "hostIPv6AddressList", "Network_IPV_6": "networkIPV6List", "Network_IPV_4": "networkIPV4List", } INTERVAL = arg_to_number(demisto.args().get("interval_in_seconds", 30)) """ CLIENT CLASS """ class Client(BaseClient): def __init__(self, url: str, auth: tuple, headers: dict, proxy: bool = False, verify: bool = False): self.url = url self.headers = headers super().__init__(base_url=url, verify=verify, proxy=proxy, auth=auth, headers=headers) def get_session_request(self, encoded_str: str) -> dict: """Gets a session from the API. Args: encoded_str: str - The string that contains username:password in base64. Returns: A dictionary with the session details. """ url_suffix = "/session" self.headers["NSM-SDK-API"] = encoded_str return self._http_request(method="GET", url_suffix=url_suffix) def list_domain_firewall_policy_request(self, domain_id: int) -> dict: """Gets the list of Firewall Policies defined in a particular domain. Args: domain_id: int - The id of the domain. Returns: A dictionary with the firewall policy list. """ url_suffix = f"/domain/{domain_id}/firewallpolicy" return self._http_request(method="GET", url_suffix=url_suffix) def get_firewall_policy_request(self, policy_id: int) -> dict: """Gets the Firewall Policy details. Args: policy_id: int - The id of the policy. Returns: A dictionary with the policy details. """ url_suffix = f"/firewallpolicy/{policy_id}" return self._http_request(method="GET", url_suffix=url_suffix) def create_firewall_policy_request(self, body: dict) -> dict: """Adds a new Firewall Policy and Access Rules. Args: body: Dict - The params to the API call. Returns: A dictionary with the id of the newly created policy. """ url_suffix = "/firewallpolicy" return self._http_request(method="POST", url_suffix=url_suffix, json_data=body) def update_firewall_policy_request(self, body: dict, policy_id: int) -> dict: """Updates an existing Firewall Policy and Access Rules. Args: body: Dict - The params to the API call. policy_id: int - The id of the updated policy. Returns: A dictionary with the request status, if it succeeded or not. """ url_suffix = f"/firewallpolicy/{policy_id}" return self._http_request(method="PUT", url_suffix=url_suffix, json_data=body) def delete_firewall_policy_request(self, policy_id: int) -> dict: """Updates an existing Firewall Policy and Access Rules. Args: policy_id: int - The id of the updated policy. Returns: A dictionary with the request status, if it succeeded or not. """ url_suffix = f"/firewallpolicy/{policy_id}" return self._http_request(method="DELETE", url_suffix=url_suffix) def list_domain_rule_objects_request(self, domain_id: int, rule_type: str) -> dict: """Gets the list of rule objects defined in a particular domain. Args: domain_id: int - The id of the domain. rule_type: str - The type of the rules to be returned. Returns: A dictionary with the rule objects list. """ url_suffix = f"/domain/{domain_id}/ruleobject?type={rule_type}" return self._http_request(method="GET", url_suffix=url_suffix) def get_rule_object_request(self, rule_id: int) -> dict: """Gets the list of rule objects defined in a particular domain. Args: rule_id: int - The id of the rule. Returns: A dictionary with the rule object information. """ url_suffix = f"/ruleobject/{rule_id}" return self._http_request(method="GET", url_suffix=url_suffix) def create_rule_object_request(self, body: dict) -> dict: """Gets the list of rule objects defined in a particular domain. Args: body: Dict - The params to the API call. Returns: A dictionary with the id of the new rule object. """ url_suffix = "/ruleobject" return self._http_request(method="POST", url_suffix=url_suffix, json_data=body) def update_rule_object_request(self, body: dict, rule_id: int) -> dict: """Updates a Rule Object. Args: body: Dict - The params to the API call. rule_id: int - The rule id. Returns: A dictionary with the status of the request. """ url_suffix = f"/ruleobject/{rule_id}" return self._http_request(method="PUT", url_suffix=url_suffix, json_data=body, resp_type="response") def delete_rule_object_request(self, rule_id: int) -> dict: """Updates a Rule Object. Args: rule_id: int - The rule id. Returns: A dictionary with the status of the request. """ url_suffix = f"/ruleobject/{rule_id}" return self._http_request(method="DELETE", url_suffix=url_suffix) def get_alerts_request( self, time_period: str, start_time: str, end_time: str, state: str, search: str, filter_arg: str, domain_id: int, page: str = None, ) -> dict: """Retrieves All Alerts. Args: time_period: str - The time period of the alert. start_time: str - The start time of the alert. end_time: str - The end time of the alert. state: str - The state of the alert. search: str - Search string in alert details. filter_arg: str - Filter alert by fields. page: str - Next/Previous page. domain_id: int - The id of the domain Returns: A dictionary with the list of alerts and info about the list. """ params = {} if time_period: params["timeperiod"] = time_period if time_period == "CUSTOM": params["starttime"] = start_time params["endtime"] = end_time if state: params["alertstate"] = state if search: params["search"] = search if filter_arg: params["filter"] = filter_arg if page: params["page"] = page if domain_id: params["domainId"] = f"{domain_id}" url_suffix = "/alerts" return self._http_request(method="GET", url_suffix=url_suffix, params=params) def get_alert_details_request(self, alert_id: int, sensor_id: int) -> dict: """Retrieves the alert details. Args: alert_id: int - The id of the relevant alert. sensor_id: int - The id of the relevant sensor. Returns: A dictionary with the alert details. """ url_suffix = f"/alerts/{alert_id}" params = {"sensorId": sensor_id} return self._http_request(method="GET", url_suffix=url_suffix, params=params) def get_attacks_request(self, attack_id: Optional[str]) -> dict: """If an attack id is given The command returns the details of the specific attack. Else, gets all available attack definitions in the Manager UI. Args: attack_id: str - The id of the relevant attack. Returns: A dictionary with the attack list of the specific attack details. """ if attack_id: url_suffix = f"/attack/{attack_id}" else: url_suffix = "/attacks" response = self._http_request(method="GET", timeout=5000, url_suffix=url_suffix) return response def get_domains_request(self, domain_id: Optional[int]) -> dict: """If a domain id is given The command returns the details of the specific domain. Else, gets all available domains. Args: domain_id: Optional[int] - The id of the relevant attack. Returns: A dictionary with the attack list of the specific attack details. """ url_suffix = "/domain" if domain_id: url_suffix = f"{url_suffix}/{domain_id}" return self._http_request(method="GET", url_suffix=url_suffix) def get_sensors_request(self, domain_id: Optional[int]) -> dict: """If a domain id is given The command returns the details of the sensors in the specific domain. Else, gets all available sensors. Args: domain_id: Optional[int] - The id of the relevant domain. Returns: A dictionary with the domains list of the specific domain details. """ url_suffix = "/sensors" params = {} if domain_id: params["domain"] = domain_id return self._http_request(method="GET", url_suffix=url_suffix, params=params) def get_ips_policies_request(self, domain_id: int) -> dict: """Gets all the IPS Policies defined in the specific domain. Args: domain_id: int - The id of the relevant domain. Returns: A dictionary with ips policies list of the specific domain details. """ url_suffix = f"/domain/{domain_id}/ipspolicies" return self._http_request(method="GET", url_suffix=url_suffix) def get_ips_policy_details_request(self, policy_id: int) -> dict: """Gets the policy details for the specific IPS policy. Args: policy_id: int - The id of the relevant ips policy. Returns: A dictionary with the ips policy details. """ url_suffix = f"/ipspolicy/{policy_id}" return self._http_request(method="GET", url_suffix=url_suffix) def update_alerts_request( self, time_period: str, start_time: str, end_time: str, state: str, search: str, filter_arg: str, body: dict ) -> dict: """Updates all relevant alerts. Args: time_period: str - The time period of the alert. start_time: str - The start time of the alert. end_time: str - The end time of the alert. state: str - The state of the alert. search: str - Search string in alert details. filter_arg: str - Filter alert by fields. body: Dict - The body of the request. Returns: A dictionary with the request status. """ params = {} if time_period: params["timeperiod"] = time_period if time_period == "CUSTOM": params["starttime"] = start_time params["endtime"] = end_time if state: params["alertstate"] = state if search: params["search"] = search if filter_arg: params["filter"] = filter_arg url_suffix = "/alerts" return self._http_request(method="PUT", url_suffix=url_suffix, params=params, json_data=body) def list_pcap_file_request(self, sensor_id: int) -> dict: """Retrieves the list of captured PCAP files. Args: sensor_id: int - the relevant sensor id. Returns: A dictionary with a list of PCAP file names. """ url_suffix = f"/sensor/{sensor_id}/packetcapturepcapfiles" return self._http_request(method="GET", url_suffix=url_suffix) def export_pcap_file_request(self, sensor_id: int, body: dict) -> Response: """Retrieves the list of captured PCAP files. Args: sensor_id: int - The relevant sensor id. body: Dict - The parameter for the http request (file name). Returns: A dictionary with a list of PCAP file names. """ url_suffix = f"/sensor/{sensor_id}/packetcapturepcapfile/export" self.headers["Accept"] = "application/octet-stream" return self._http_request(method="PUT", url_suffix=url_suffix, json_data=body, resp_type="response") def list_domain_device_request(self, domain_id: int) -> dict: """Retrieves the list of devices in a domain. Args: domain_id: int - The relevant domain id. Returns: A dictionary with a list of devices. """ url_suffix = f"/domain/{domain_id}/device" return self._http_request(method="GET", url_suffix=url_suffix) def list_device_interface_request(self, domain_id: int, device_id: int) -> dict[str, List]: """Retrieves the list of interfaces related to a device. Args: device_id: int - The relevant device id. domain_id: int - The relevant domain id. Returns: A dictionary with a list of interfaces. """ url_suffix = f"/domain/{domain_id}/sensor/{device_id}/allocatedinterfaces" return self._http_request(method="GET", url_suffix=url_suffix) def assign_device_policy_request( self, domain_id: int, device_id: int, pre_firewall_policy: Optional[str], post_firewall_policy: Optional[str] ) -> dict: """Assigns a policy to a device. Args: device_id: int - The relevant device id. domain_id: int - The relevant domain id. pre_firewall_policy: Optional[str] - The pre firewall policy. post_firewall_policy: Optional[str] - The post firewall policy. Returns: A success or failure code. """ url_suffix = f"/domain/{domain_id}/policyassignments/device/{device_id}" json_data = {"firewallPolicyLast": post_firewall_policy, "firewallPolicyFirst": pre_firewall_policy} return self._http_request(method="PUT", url_suffix=url_suffix, json_data=json_data) def list_device_policy_request(self, domain_id: int, device_id: Optional[int]) -> dict: """Retrieves the list of policies assigned to a device. Args: device_id: int - The relevant device id. domain_id: int - The relevant domain id. Returns: A dictionary with a list of policies. """ if device_id: url_suffix = f"/domain/{domain_id}/policyassignments/device/{device_id}" else: url_suffix = f"/domain/{domain_id}/policyassignments/device" return self._http_request(method="GET", url_suffix=url_suffix) def assign_interface_policy_request( self, domain_id: int, interface_id: int, firewall_policy: Optional[str], firewall_port_policy: Optional[str], ips_policy: Optional[str], custom_policy_json: Optional[dict], ) -> dict: """Assigns a policy to an interface. Args: domain_id: int - The relevant domain id. interface_id: int - The relevant interface id. firewall_policy: str - The firewall policy. firewall_port_policy: str - The firewall port policy. ips_policy: str - The IPS policy. custom_policy_json: Dict - A dict of custom policies. Returns: A success or failure code. """ url_suffix = f"/domain/{domain_id}/policyassignments/interface/{interface_id}" json_data = {"firewallPolicy": firewall_policy, "firewallPortPolicy": firewall_port_policy, "ipsPolicy": ips_policy} if custom_policy_json: json_data |= custom_policy_json return self._http_request(method="PUT", url_suffix=url_suffix, json_data=json_data) def list_interface_policy_request(self, domain_id: int, interface_id: Optional[int]) -> dict: """Retrieves the list of policies assigned to an interface. Args: domain_id: int - The relevant domain id. interface_id: int - The relevant interface id. Returns: A dictionary with a list of policies. """ if interface_id: url_suffix = f"/domain/{domain_id}/policyassignments/interface/{interface_id}" else: url_suffix = f"/domain/{domain_id}/policyassignments/interface" return self._http_request(method="GET", url_suffix=url_suffix) def get_device_configuration_request(self, device_id: int) -> dict: """Retrieves the configuration of a device. Args: device_id: int - The relevant device id. Returns: A dictionary with the device configuration. """ url_suffix = f"/sensor/{device_id}/action/update_sensor_config" return self._http_request(method="GET", url_suffix=url_suffix) def deploy_device_configuration_request( self, device_id: int, is_SSL_Push_Required: bool = False, is_GAM_Update_Required: bool = False, is_Sigset_Config_Push_Required: bool = False, is_Botnet_Push_Required: bool = False, ) -> dict: """Deploy a device configuration. Args: device_id: int - The relevant device id. is_SSL_Push_Required: bool - Is SSL push required. is_GAM_Update_Required: bool - Is GAM update required. is_Sigset_Config_Push_Required: bool - Is signature set configuration push required. is_Botnet_Push_Required: bool - Is botnet push required. Returns: A success or failure code. """ json_data = { "isSSLPushRequired": is_SSL_Push_Required, "isGAMUpdateRequired": is_GAM_Update_Required, "isSigsetConfigPushRequired": is_Sigset_Config_Push_Required, "isBotnetPushRequired": is_Botnet_Push_Required, } url_suffix = f"/sensor/{device_id}/action/update_sensor_config" return self._http_request(method="PUT", url_suffix=url_suffix, json_data=json_data) def check_deploy_device_configuration_request_status(self, device_id, request_id): """ Checks the status of a device configuration deployment. Args: device_id (int): The relevant device id. request_id (int): The relevant request id. Returns: A dictionary with the status of deployment for all optional deployment categories. """ url_suffix = f"/sensor/{device_id}/action/update_sensor_config/{request_id}" return self._http_request(method="GET", url_suffix=url_suffix) """ HELPER FUNCTIONS """ def encode_to_base64(str_to_convert: str) -> str: """Converts a string to base64 string. Args: str_to_convert: str - The string that needs to be converted to base64. Returns: The converted string. """ b = base64.b64encode(bytes(str_to_convert, "utf-8")) # bytes base64_str = b.decode("utf-8") # convert bytes to string return base64_str def get_session(client: Client, user_name_n_password: str) -> str: """Gets the session string. Args: client: Client - A McAfeeNSM client. user_name_n_password: str - The username and password that needs to be encoded to base64 in order to get the session information. Returns: The converted string. """ user_name_n_password_encoded = encode_to_base64(user_name_n_password) session = client.get_session_request(user_name_n_password_encoded) return encode_to_base64(f'{session.get("session")}:{session.get("userId")}') def pagination(records_list: List, limit: int, page: Optional[int], page_size: Optional[int]) -> List[dict]: """Returns the wanted records. Args: records_list: List - The original list of objects. limit: str - The amount of records to be returned page: Optional[int] - The page of the results (The results in page 1, 2 ...) page_size: Optional[int] - the number of records that will be in the page. Returns: The wanted records. """ if page and page_size: num_rec_2_remove = page_size * (page - 1) results_list = records_list[num_rec_2_remove:] return results_list[:page_size] else: return records_list[:limit] def alerts_list_pagination( records_list: List, limit: int, page: Optional[int], page_size: Optional[int], time_period: str, start_time: str, end_time: str, state: str, search: str, filter_arg: str, client: Client, domain_id: int, ) -> List: """Returns the wanted records. Args: records_list: List - The original list of objects. limit: int - The amount of records to be returned page: Optional[int] - The page of the results (The results in page 1, 2 ...) page_size: Optional[int] - The number of records in a page. time_period: str - The time period of the alert. start_time: str - The start time of the alert. end_time: str - The end time of the alert. state: str - The state of the alert. search: str - Search string in alert details. filter_arg: str - Filter alert by fields. client: Client - McAfeeNSMv2 client domain_id: str - The id of the domain. Returns: The wanted records. """ if page and page_size: offset = page_size * (page - 1) results_list = [] while (offset + page_size > 1000) and (len(records_list) == 1000): records_list = records_list[offset:] results_list.extend(records_list) page_size = page_size - len(records_list) offset = 0 if offset <= 1000 else offset - 1000 response = client.get_alerts_request(time_period, start_time, end_time, state, search, filter_arg, domain_id, "next") records_list = response.get("alertsList", []) records_list = records_list[offset:] results_list.extend(records_list[:page_size]) return results_list else: results_list = [] while limit > 1000 and (len(records_list) == 1000): results_list.extend(records_list) limit = limit - len(records_list) response = client.get_alerts_request(time_period, start_time, end_time, state, search, filter_arg, domain_id, "next") records_list = response.get("alertsList", []) results_list.extend(records_list[:limit]) return results_list def response_cases(response_str: str) -> str: """Checks the response param and returns the correct response string. Args: response_str: str - The response string. Returns: The correct response string. Example: Scan -> SCAN Drop -> DROP Deny -> DENY Ignore -> IGNORE Stateless Ignore -> STATELESS_IGNORE Stateless Drop -> STATELESS_DROP Require Authentication-> REQUIRE_AUTHENTICATION """ split_str = response_str.upper().split() if len(split_str) == 1: return split_str[0] else: return "_".join(split_str) def rule_object_type_cases(str_type: str, case: str) -> str: """Checks the rule_object_type params and returns the correct format of them. Args: str_type: str - The type string. case: str - In what case should the letters be, upper or lower case. Returns: The correct rule_object_type string. Examples: - In list_domain_rule_objects_command the arguments should be in lower case and in this form: Endpoint IP V.4 -> hostipv4 Range IP V.4 -> ipv4addressrange Network IP V.4 -> networkipv4 Endpoint IP V.6 -> hostipv6 Range IP V.6 -> ipv6addressrange Network IP V.6 -> networkipv6 - In all the other commands that use this function, the arguments should be in upper case and in this form: Endpoint IP V.4 -> HOST_IPV_4 Range IP V.4 -> IPV_4_ADDRESS_RANGE Network IP V.4 -> NETWORK_IPV_4 Endpoint IP V.6 -> HOST_IPV_6 Range IP V.6 -> IPV_6_ADDRESS_RANGE Network IP V.6 -> NETWORK_IPV_6 """ type_split = str_type.upper().replace(".", " ").split() if "ENDPOINT" in type_split[0]: r_type = f"HOST_IPV_{type_split[-1]}" elif "RANGE" in type_split[0]: r_type = f"IPV_{type_split[-1]}_ADDRESS_RANGE" else: r_type = f"NETWORK_IPV_{type_split[-1]}" if case == "low": return r_type.lower().replace("_", "") return r_type def reverse_rule_object_type_cases(rule_type: str) -> str: """Checks the rule_object_type params that return from the API call and returns the matching string in the UI. Args: rule_type: str - The type string. Returns: The matching string. Example: HOST_IPV_4 -> Endpoint IP V.4 IPV_4_ADDRESS_RANGE -> Range IP V.4 NETWORK_IPV_4 -> Network IP V.4 HOST_IPV_6 -> Endpoint IP V.6 IPV_6_ADDRESS_RANGE -> Range IP V.6 NETWORK_IPV_6 -> Network IP V.6 """ number = "4" if ("4" in rule_type) else "6" if HOST in rule_type: return f"Endpoint IP V.{number}" elif ADDRESS_RANGE in rule_type: return f"Range IP V.{number}" else: return f"Network IP V.{number}" def check_source_and_destination( source_rule_object_id: Optional[int], source_rule_object_type: Optional[str], destination_rule_object_id: Optional[int], destination_rule_object_type: Optional[str], create_or_update: str, ): """Checks the source and destination objects. Args: source_rule_object_id: Optional[int] - Unique Rule Object ID. source_rule_object_type: Optional[str] - Source / Destination Mode. destination_rule_object_id: Optional[int] - Unique Rule Object ID. destination_rule_object_type: Optional[str] - Source / Destination Mode. create_or_update: str - From what function it was called. Returns: Throws exception . """ if (source_rule_object_id and not source_rule_object_type and source_rule_object_id != -1) or ( not source_rule_object_id and source_rule_object_type ): # If the user provides source_rule_object_id he must provide source_rule_object_type and vice versa raise Exception("Please provide both source_rule_object_id and source_rule_object_type.") if (destination_rule_object_id and not destination_rule_object_type and destination_rule_object_id != -1) or ( not destination_rule_object_id and destination_rule_object_type ): # If the user provides destination_rule_object_id he must provide destination_rule_object_type and vice versa raise Exception("Please provide both destination_rule_object_id and destination_rule_object_type.") if create_or_update == "create": # noqa: SIM102 # if the user wants to create a new firewall policy, he must provide a source rule or destination rule or both. if source_rule_object_id == -1 and destination_rule_object_id == -1: raise Exception("You must provide the source fields or destination fields or both.") def create_body_firewall_policy( domain: int, name: str, visible_to_child: bool, description: str, is_editable: bool, policy_type: str, rule_description: str, response_param: str, rule_enabled: bool, direction: str, source_object: List, destination_object: List, ) -> dict: """ Args: domain: int - The id of the domain. name: str - The name of the policy. visible_to_child: bool - Will the policy be visible to the child domain. description: str - the policy description. is_editable: bool - Is the policy editable. policy_type: str - The type of the policy. rule_description: str - The description of the rule. response_param: str - Action to be performed if the traffic matches this rule. rule_enabled: bool - Is Rule Enabled or not. direction: str - The rule direction. source_object: List - Information about the source addresses. destination_object: List - Information about the destination addresses. Returns: Returns the body for the request. """ return { "Name": name, "DomainId": domain, "VisibleToChild": visible_to_child, "Description": description, "IsEditable": is_editable, "PolicyType": policy_type, "MemberDetails": { "MemberRuleList": [ { "Description": rule_description, "Enabled": rule_enabled, "Response": response_param, "Direction": direction, "SourceAddressObjectList": source_object, "DestinationAddressObjectList": destination_object, "SourceUserObjectList": [{"RuleObjectId": "-1", "Name": "Any", "RuleObjectType": "USER"}], "ServiceObjectList": [{"RuleObjectId": "-1", "Name": "Any", "RuleObjectType": None, "ApplicationType": None}], "ApplicationObjectList": [], "TimeObjectList": [{"RuleObjectId": "-1", "Name": "Always", "RuleObjectType": None}], } ] }, } def create_body_create_rule(rule_type: str, address: List, number: int, from_to_list: list[dict[str, Optional[Any]]]) -> tuple: """create part of the body for the command create_rule_object Args: rule_type: str - The type of the rule. address: List - A list of addresses, if relevant. number: int - The number of the IPV. from_to_list: List - A list that contains dictionaries with from and to addresses. Returns: Returns the body for the request. """ if HOST in rule_type: return f"HostIPv{number}", {f"hostIPv{number}AddressList": address} elif ADDRESS_RANGE in rule_type: return f"IPv{number}AddressRange", {f"IPV{number}RangeList": from_to_list} else: return f"Network_IPV_{number}", {f"networkIPV{number}List": address} def create_body_create_rule_for_v10( rule_type: str, address: List, number: int, from_to_list: List[dict[str, Optional[Any]]], state: str = "Enabled" ) -> tuple: """create part of the body for the command create_rule_object for v10 Args: rule_type: str - The type of the rule. address: List - A list of addresses, if relevant. number: int - The number of the IPV. from_to_list: List - A list that contains dictionaries with from and to addresses. state: str - An Enabled or Disabled state. Returns: Returns the body for the request. """ # build a list of dictionaries with the state and the address list_to_send: list[dict] = [{"value": single_address, "state": STATE_TO_NUMBER.get(state)} for single_address in address] # for parameters with a range, we need to add the state to the dictionary if from_to_list: from_to_list[0].update({"state": STATE_TO_NUMBER.get(state)}) if HOST in rule_type: return f"HostIPv{number}", {f"hostIPv{number}AddressList": list_to_send} elif ADDRESS_RANGE in rule_type: return f"IPv{number}AddressRange", {f"IPV{number}RangeList": from_to_list} else: return f"Network_IPV_{number}", {f"networkIPV{number}List": list_to_send} def create_body_update_rule_for_v10( rule_type: str, address: List, number: int, from_to_list: List[dict[str, Optional[Any]]], state: str = "Enabled" ) -> tuple: """create part of the body for the command update_rule_object for v10 Args: rule_type: str - The type of the rule. address: List - A list of addresses, if relevant. number: int - The number of the IPV. from_to_list: List - A list that contains dictionaries with from and to addresses. state: str - An Enabled or Disabled state. Returns: Returns the body for the request. """ # build a list of dictionaries with the state, the address, and changedState for update or delete # code explanations: # changedState: 1 = add, 3 = delete, depends on the choice of the user to overwrite or not # AS you can tell from the 'update_rule_object_command', address is a list of dictionaries or strings. # The existing addresses are dictionaries and the upcoming addresses are strings # if the address is a dictionary, the user wants to delete and overwrite that's the reason we kept that address in the list. list_to_send: list[dict] = [] for single_address in address: if type(single_address) is dict: # if its a dict == its an existing address to overwrite, we saved from the 'get' call list_to_send.append({"value": single_address.get("value"), "state": STATE_TO_NUMBER.get(state), "changedState": 3}) else: # its a new address the user wants to add list_to_send.append({"value": single_address, "state": STATE_TO_NUMBER.get(state), "changedState": 1}) # for parameters with a range, we need to add the state and the changeState to the dictionary # Similar logic to above, if "state" is in the dictionary, the user wants to delete and overwrite that's the reason # we kept that range in the list. if from_to_list: for dictionary in from_to_list: if "state" in dictionary: # if the state is in the dictionary, it means the user wants to delete that range. dictionary.update({"changedState": 3}) else: # if the state is not in the dictionary, it means the user wants to add that range of addresses dictionary.update({"state": STATE_TO_NUMBER.get(state), "changedState": 1}) if HOST in rule_type: return f"HostIPv{number}", {f"hostIPv{number}AddressList": list_to_send} elif ADDRESS_RANGE in rule_type: return f"IPv{number}AddressRange", {f"IPV{number}RangeList": from_to_list} else: return f"Network_IPV_{number}", {f"networkIPV{number}List": list_to_send} def modify_v10_results_to_v9_format(response: List[dict[Any, Any]]) -> List[dict[Any, Any]]: """ Modify the response of v10 to be in the same format as in v9. The main difference is that in v10 the API returns the addresses in a list of dictionaries, A dictionary for each address with extra information, and in v9 all the addresses are in one list. This function takes a v10 response and returns a v9 response (to maintain backward compatibility). Args: response: List[Dict[Any, Any]] - The response of the command of v10. Returns: A list of dictionaries in the same format as in v9. """ key_list = ["IPv6AddressRange", "HostIPv6", "Network_IPV_6", "Network_IPV_4", "HostIPv4", "IPv4AddressRange"] for record in response: for key, value in record.items(): if key in key_list and value: # find the key that its value is the dict contains the addresses address_list: list = [] my_key = key # The value of the first (and only) key is a list containing dict with addresses addresses = value[ADDRESS_LIST_MAP.get(key)] for inner_dict in addresses: temp_dict = {} for key in inner_dict: # choose the relevant keys and values and saves them in a temp dict if key == "value": address_list.append(inner_dict[key]) elif key in ["FromAddress", "ToAddress"]: temp_dict[key] = inner_dict[key] address_list.append(temp_dict) if temp_dict else None if address_list: # replace the list of dicts in the original record with a list of strings containing the addresses record[my_key] = {ADDRESS_LIST_MAP.get(my_key): address_list} return response def capitalize_key_first_letter(input_lst: List[dict], check_lst: List = []) -> List[dict]: """ Capitalize the first letter of all keys in all given dictionaries, while keeping the rest of the key as it is.(can't use 'capitalize()'). Args: input_lst: List - A list of dictionaries. check_lst: List - A list of keys to check if they exist in the dictionary. Returns: Returns the dict with the first letter of all keys capitalized. """ capitalize_lst = [] for my_dict in input_lst: my_dict = ( {k[:1].upper() + k[1:]: v for k, v in my_dict.items() if k in check_lst} if check_lst else {k[:1].upper() + k[1:]: v for k, v in my_dict.items()} ) capitalize_lst.append(my_dict) if my_dict else None return capitalize_lst def flatten_and_capitalize(main_dict: dict, inner_dict_key: str, check_lst: List = []) -> dict: """ Flatten a nested dictionary and capitalize the first letter of all the nested dictionary's key Args: main_dict: Dict - A dictionary with a nested dict. inner_dict_key: str - The key of the nested dictionary. check_lst: List - A list of keys to check if they exist in the dictionary. Returns: Returns a flat dict with the first letter of all keys capitalized. """ if inner_dict := main_dict.pop(inner_dict_key, None): capitalized_inner = capitalize_key_first_letter(input_lst=[inner_dict], check_lst=check_lst)[0] main_dict |= capitalized_inner return main_dict def deploy_polling_message(status: dict, args: dict): """ Builds a message and a fail or success list for the polling command Args: status: the status of the deployment args: the arguments of the deployment command Returns: fail_or_success_list: a list of 0 or 1, 0 for failure and 1 for success message: a message to be printed to the user """ fail_or_success_list = [] build_a_massage = "" for k, v in args.items(): if v == "true": # if the value is true that is one of the arguments to deploy and we need to check its status current_percentage_status = status.get(DEPLOY_ARGUMENT_MAPPER.get(str(k))) current_message_status = status.get(MESSAGE_MAP.get(str(k))) if current_percentage_status != 100 or current_message_status != "DOWNLOAD COMPLETE": fail_or_success_list.append(0) build_a_massage += f"""\nThe current percentage of deployment for '{k}' is: {current_percentage_status}% \nAnd the current message is: {current_message_status}\n""" else: fail_or_success_list.append(1) return fail_or_success_list, build_a_massage def check_required_arg(arg_name: str, arg_value: int | None) -> int: """Check if the required arguments are present in the command. Args: arg_value: int - The expected value for the argument. arg_name: str - The name of the argument. """ if not arg_value and arg_value != 0: raise DemistoException(f"Please provide a {arg_name} argument.") return arg_value def check_args_create_rule(rule_type: str, address: List, from_address: str, to_address: str, number: int): """Validate the arguments of the function Args: rule_type: str - The type of the rule. address: List - A list of addresses, if relevant. from_address: str - The from address, if relevant. to_address: str - The to address, if relevant. number: int - The number of the addresses IP V. """ if not address and not from_address and not to_address: raise Exception("Please enter a matching address.") if ("4" in rule_type and number == 6) or ("6" in rule_type and number == 4): raise Exception('The version of the IP in "rule_object_type" should match the addresses version.') if (HOST in rule_type or "NETWORK" in rule_type) and (not address or from_address or to_address): raise Exception( f'If the "rule_object_type" is “Endpoint IP V.{number}” or “Network IP V.{number}” than only' f" the argument “address_ip_v.{number}” must contain a value. The other address arguments " f"should be empty." ) if ADDRESS_RANGE in rule_type and (not to_address or not from_address or address): raise Exception( f'If the "rule_object_type" is “Range IP V.{number}” than only the arguments ' f"“from_address_ip_v.{number}” and “to_address_ip_v.{number}” must contain a value, the other" f" address arguments should be empty." ) def h_r_get_domains(children: List[dict], contents: List): """Creates the human readable for the command get_domains. Args: children: List[Dict] - A list of the children. contents: List - The human readable object. Returns: The human readable contains the relevant values. """ for child in children: child["ID"] = child.get("id") del child["id"] child["Name"] = child.get("name") del child["name"] d = {"ID": child.get("ID"), "Name": child.get("Name")} contents.append(d) if child.get("childdomains", []): h_r_get_domains(child.get("childdomains", []), contents) def update_source_destination_object( obj: List[dict], rule_object_id: Optional[int], rule_object_type: Optional[str] ) -> List[dict]: """Updates the source and destination objects in the command update_firewall_policy. Args: obj: List[Dict] - The relevant object. rule_object_id: Optional[int] - The id of the rule. rule_object_type: Optional[str] - The type of the rule Returns: The updated object. """ if rule_object_id: if rule_object_id == -1: raise Exception( "If you want to delete an address please provide is_overwrite=true and the relevant rule_object_id=-1." ) new_object = {"RuleObjectId": rule_object_id, "RuleObjectType": rule_object_type} old_id = obj[0].get("RuleObjectId") # if the old id is -1, it means that there wasn't any specific rule before, and we need to overwrite the # "placeholder" rule. if old_id == "-1": obj = [new_object] else: obj.append(new_object) return obj def overwrite_source_destination_object( rule_object_id: Optional[int], rule_object_type: Optional[str], dest_or_src: str, member_rule_list: dict ) -> List: """overwrite the source and destination objects in the command update_firewall_policy. Args: rule_object_id: Optional [int] - The id of the rule. rule_object_type: Optional[str] - The type of the rule. dest_or_src: str - Overwrite the destination or source object. member_rule_list: Dict - The first object in MemberRuleList in the API response. Returns: The overwrite object. """ if rule_object_id: if rule_object_id == -1: return [{"RuleObjectId": -1, "RuleObjectType": None}] else: return [{"RuleObjectId": rule_object_id, "RuleObjectType": rule_object_type}] else: return member_rule_list.get(f"{dest_or_src}AddressObjectList", [dict]) def update_filter(filter_arg: str) -> str: """Removes the special characters from the name argument in filter, because tha api do not work with special characters. Args: filter_arg: str - The original filter Returns: The updated filter, without special chars. Example: - name:HTTP: IIS 6.0 (CVE-0000-0000) -> name:HTTP IIS 6 0 CVE 0000 0000 """ split_filter = filter_arg.split(";") for index, s in enumerate(split_filter): if "name" in s: s = s.replace("name:", "") s = re.sub("[^a-zA-Z0-9]", " ", s) s = f"name:{s}" split_filter[index] = s break return ";".join(split_filter) def get_addresses_from_response(response: dict) -> List: """Returns the addresses from the response, for the human-readable in the command get_rule_object. Args: response: Dict - The response from the API. Returns: The list of addresses. """ rule_type = response.get("ruleobjType", "") number = 4 if "4" in rule_type else 6 if HOST in rule_type: return response.get(f"HostIPv{number}", {}).get(f"hostIPv{number}AddressList", []) elif ADDRESS_RANGE in rule_type: return response.get(f"IPv{number}AddressRange", {}).get(f"IPV{number}RangeList", [dict]) else: # 'NETWORK' return response.get(f"Network_IPV_{number}", {}).get(f"networkIPV{number}List", []) """ COMMAND FUNCTIONS """ def test_module(client: Client, username_n_password: str) -> str: """Test the connection to McAfee NSM. Args: client: Client - A McAfeeNSM client. username_n_password: str - The string that contains username:password to be encoded. Returns: 'ok' if the connection was successful, else throws exception. """ try: get_session(client, username_n_password) return "ok" except DemistoException as e: raise Exception(e.message) def list_domain_firewall_policy_command(client: Client, args: dict) -> CommandResults: """Gets the list of Firewall Policies defined in a particular domain. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with the list of Firewall Policies defined in a particular domain. """ domain_id = int(args.get("domain_id", 0)) limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT page = arg_to_number(args.get("page")) page_size = arg_to_number(args.get("page_size")) if (page and not page_size) or (not page and page_size): raise Exception("Please provide both page and page_size arguments.") response = client.list_domain_firewall_policy_request(domain_id) result = sorted(response.get("FirewallPoliciesForDomainResponseList", []), key=lambda k: k["policyId"], reverse=True) result = pagination(result, limit, page, page_size) contents = [] for value in result: d = { "policyId": value.get("policyId"), "policyName": value.get("policyName"), "domainId": value.get("domainId"), "visibleToChild": value.get("visibleToChild"), "description": value.get("description"), "isEditable": value.get("isEditable"), "policyType": value.get("policyType"), "policyVersion": value.get("policyVersion"), "lastModUser": value.get("lastModUser"), } contents.append(d) headers = [ "policyId", "policyName", "domainId", "visibleToChild", "description", "isEditable", "policyType", "policyVersion", "lastModUser", ] readable_output = tableToMarkdown(name="Firewall Policies List", t=contents, removeNull=True, headers=headers) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.Policy", outputs_key_field="policyId", outputs=result, raw_response=result, ) def get_firewall_policy_command(client: Client, args: dict) -> CommandResults: """Gets the Firewall Policy details. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with the Firewall Policy details. """ policy_id = int(args.get("policy_id", "")) include_rule_objects = argToBoolean(args.get("include_rule_objects", False)) response = client.get_firewall_policy_request(policy_id) if not include_rule_objects: member_rule_list = response.get("MemberDetails", {}).get("MemberRuleList", [dict]) updated_member_rule_list = [] for member in member_rule_list: d = { "Description": member.get("Description"), "Direction": member.get("Direction"), "Enabled": member.get("Enabled"), "Response": member.get("Response"), "IsLogging": member.get("IsLogging"), } updated_member_rule_list.append(d) response.get("MemberDetails", {})["MemberRuleList"] = updated_member_rule_list contents = { "FirewallPolicyId": response.get("FirewallPolicyId"), "Name": response.get("Name"), "Description": response.get("Description"), "VisibleToChild": response.get("VisibleToChild"), "IsEditable": response.get("IsEditable"), "PolicyType": response.get("PolicyType"), "PolicyVersion": response.get("PolicyVersion"), "LastModifiedUser": response.get("LastModifiedUser"), "LastModifiedTime": response.get("LastModifiedTime"), } headers = [ "PolicyId", "Name", "Description", "VisibleToChild", "IsEditable", "PolicyType", "PolicyVersion", "LastModifiedUser", "LastModifiedTime", ] readable_output = tableToMarkdown(name=f"Firewall Policy {policy_id}", t=contents, removeNull=True, headers=headers) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.Policy", outputs=response, raw_response=response, outputs_key_field="FirewallPolicyId", ) def create_firewall_policy_command(client: Client, args: dict) -> CommandResults: """Adds a new Firewall Policy and Access Rules. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with a success message. """ domain = arg_to_number(args.get("domain", "0"), required=True) or 0 name = args.get("name", "") visible_to_child = argToBoolean(args.get("visible_to_child", True)) description = args.get("description", "") is_editable = argToBoolean(args.get("is_editable", True)) or True policy_type = args.get("policy_type", "").upper() rule_description = args.get("rule_description", "") rule_enabled = argToBoolean(args.get("rule_enabled", True)) response_param = response_cases(args.get("response", "")) direction = args.get("direction", "").upper() source_rule_object_id = arg_to_number(args.get("source_rule_object_id", -1)) source_rule_object_type = args.get("source_rule_object_type", None) destination_rule_object_id = arg_to_number(args.get("destination_rule_object_id", -1)) destination_rule_object_type = args.get("destination_rule_object_type", None) check_source_and_destination( source_rule_object_id, source_rule_object_type, destination_rule_object_id, destination_rule_object_type, "create" ) source_rule_object_type = rule_object_type_cases(source_rule_object_type, "up") if source_rule_object_type else None destination_rule_object_type = ( rule_object_type_cases(destination_rule_object_type, "up") if destination_rule_object_type else None ) source_object = overwrite_source_destination_object(source_rule_object_id, source_rule_object_type, "", {}) destination_object = overwrite_source_destination_object(destination_rule_object_id, destination_rule_object_type, "", {}) body = create_body_firewall_policy( domain, name, visible_to_child, description, is_editable, policy_type, rule_description, response_param, rule_enabled, direction, source_object, destination_object, ) response = client.create_firewall_policy_request(body) response = {"FirewallPolicyId": response.get("createdResourceId")} new_firewall_policy_id = response.get("FirewallPolicyId") return CommandResults( readable_output=f"The firewall policy no.{new_firewall_policy_id} was created successfully", outputs_prefix="NSM.Policy", outputs=response, raw_response=response, outputs_key_field="FirewallPolicyId", ) def update_firewall_policy_command(client: Client, args: dict) -> CommandResults: """Updates the Firewall Policy details. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with a success message. """ policy_id = int(args.get("policy_id", "")) domain = args.get("domain") name = args.get("name") visible_to_child = args.get("visible_to_child") description = args.get("description") is_editable = args.get("is_editable") policy_type = args.get("policy_type") rule_description = args.get("rule_description") response_param = args.get("response") rule_enabled = args.get("rule_enabled") direction = args.get("direction") source_rule_object_id = arg_to_number(args.get("source_rule_object_id", None)) source_rule_object_type = args.get("source_rule_object_type", None) source_rule_object_type = rule_object_type_cases(source_rule_object_type, "up") if source_rule_object_type else None destination_rule_object_id = arg_to_number(args.get("destination_rule_object_id", None)) destination_rule_object_type = args.get("destination_rule_object_type") destination_rule_object_type = ( rule_object_type_cases(destination_rule_object_type, "up") if destination_rule_object_type else None ) is_overwrite = argToBoolean(args.get("is_overwrite", False)) if is_overwrite and (not source_rule_object_id and not destination_rule_object_id): raise Exception("If is_overwrite=true than at least one of the rules (source or destination) must be provided.") check_source_and_destination( source_rule_object_id, source_rule_object_type, destination_rule_object_id, destination_rule_object_type, "update" ) policy_get_details = client.get_firewall_policy_request(policy_id) if not policy_get_details.get("IsEditable"): raise Exception(f"The policy no.{policy_id} can't be edited") member_rule_list = policy_get_details.get("MemberDetails", {}).get("MemberRuleList", [dict])[0] domain = domain if domain else policy_get_details.get("DomainId") name = name if name else policy_get_details.get("Name") visible_to_child = policy_get_details.get("VisibleToChild") if not visible_to_child else argToBoolean(visible_to_child) description = description if description else policy_get_details.get("Description") is_editable = policy_get_details.get("IsEditable") if not is_editable else argToBoolean(is_editable) policy_type = policy_get_details.get("PolicyType") if not policy_type else policy_type.upper() rule_description = member_rule_list.get("Description") if not rule_description else argToBoolean(rule_description) response_param = member_rule_list.get("Response") if not response_param else response_cases(response_param) rule_enabled = member_rule_list.get("Enabled") if not rule_enabled else argToBoolean(rule_enabled) direction = member_rule_list.get("Direction") if not direction else direction.upper() if is_overwrite: source_object = overwrite_source_destination_object( source_rule_object_id, source_rule_object_type, "Source", member_rule_list ) destination_object = overwrite_source_destination_object( destination_rule_object_id, destination_rule_object_type, "Destination", member_rule_list ) else: source_object = member_rule_list.get("SourceAddressObjectList", [dict]) source_object = update_source_destination_object(source_object, source_rule_object_id, source_rule_object_type) destination_object = member_rule_list.get("DestinationAddressObjectList", []) destination_object = update_source_destination_object( destination_object, destination_rule_object_id, destination_rule_object_type ) body = create_body_firewall_policy( domain, # type: ignore[arg-type] name, # type: ignore[arg-type] visible_to_child, # type: ignore[arg-type] description, # type: ignore[arg-type] is_editable, # type: ignore[arg-type] policy_type, # type: ignore[arg-type] rule_description, response_param, rule_enabled, direction, source_object, destination_object, ) client.update_firewall_policy_request(body, policy_id) return CommandResults(readable_output=f"The firewall policy no.{policy_id} was updated successfully") def delete_firewall_policy_command(client: Client, args: dict) -> CommandResults: """Deletes the specified Firewall Policy. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with a success message. """ policy_id = int(args.get("policy_id", "")) client.delete_firewall_policy_request(policy_id) return CommandResults(readable_output=f"The firewall policy no.{policy_id} was deleted successfully") def list_domain_rule_objects_command(client: Client, args: dict) -> CommandResults: """Gets the list of rule objects defined in a particular domain. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with the list. """ domain_id = arg_to_number(args.get("domain_id"), required=True) or 0 rule_type = args.get("type", "All") limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT page = arg_to_number(args.get("page")) page_size = arg_to_number(args.get("page_size")) if (page and not page_size) or (not page and page_size): raise Exception("Please provide both page and page_size arguments.") if rule_type == "All": rule_type = "hostipv4,hostipv6,ipv4addressrange,ipv6addressrange,networkipv4,networkipv6" else: rule_type = rule_object_type_cases(rule_type, "low") response = client.list_domain_rule_objects_request(domain_id, rule_type) results = pagination(response.get("RuleObjDef", []), limit, page, page_size) # modify the results in v10 to match the v9 pattern if VERSION == V10: results = modify_v10_results_to_v9_format(results) contents = [] for record in results: record["ruleobjType"] = reverse_rule_object_type_cases(record.get("ruleobjType", None)) d = { "RuleId": record.get("ruleobjId"), "Name": record.get("name"), "Description": record.get("description"), "VisibleToChild": record.get("visibleToChild"), "RuleType": record.get("ruleobjType"), } contents.append(d) headers = ["RuleId", "Name", "Description", "VisibleToChild", "RuleType"] readable_output = tableToMarkdown(name="List of Rule Objects", t=contents, removeNull=True, headers=headers) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.Rule", outputs=results, raw_response=results, outputs_key_field="ruleobjId", ) def get_rule_object_command(client: Client, args: dict) -> CommandResults: """Gets the details of a Rule Object. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with information about the rule object. """ rule_id = int(args.get("rule_id", "")) response = client.get_rule_object_request(rule_id) response = response.get("RuleObjDef", {}) addresses = get_addresses_from_response(response) # modify the results in v10 to match the v9 pattern if VERSION == V10: response = modify_v10_results_to_v9_format([response])[0] addresses = get_addresses_from_response(response) response["ruleobjType"] = reverse_rule_object_type_cases(response.get("ruleobjType")) contents = { "RuleId": response.get("ruleobjId"), "Name": response.get("name"), "Description": response.get("description"), "VisibleToChild": response.get("visibleToChild"), "RuleType": response.get("ruleobjType"), "Addresses": addresses, } headers = ["RuleId", "Name", "Description", "VisibleToChild", "RuleType", "Addresses"] readable_output = tableToMarkdown(name=f"Rule Objects {rule_id}", t=contents, removeNull=True, headers=headers) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.Rule", outputs=response, raw_response=response, outputs_key_field="ruleobjId", ) def create_rule_object_command(client: Client, args: dict) -> CommandResults: """Adds a new Rule Object. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with a success message. """ domain = arg_to_number(args.get("domain", 0)) rule_type = rule_object_type_cases(args.get("rule_object_type", ""), "up") name = args.get("name") visible_to_child = argToBoolean(args.get("visible_to_child", True)) description = args.get("description") address_ip_v_4 = argToList(args.get("address_ip_v.4", None)) from_address_ip_v_4 = args.get("from_address_ip_v.4") to_address_ip_v_4 = args.get("to_address_ip_v.4") address_ip_v_6 = argToList(args.get("address_ip_v.6")) from_address_ip_v_6 = args.get("from_address_ip_v.6") to_address_ip_v_6 = args.get("to_address_ip_v.6") state: str = args.get("state", "Enabled") if ( (address_ip_v_4 and address_ip_v_6) or (from_address_ip_v_4 and from_address_ip_v_6) or (to_address_ip_v_4 and to_address_ip_v_6) ): raise Exception( "Those pairs of arguments (address_ip_v_4 and address_ip_v_6) or " "(from_address_ip_v_4 and from_address_ip_v_6) or (to_address_ip_v_4 and to_address_ip_v_6)" "should not have values in parallel, only one at a time." ) address = address_ip_v_4 if address_ip_v_4 else address_ip_v_6 number = 4 if (address_ip_v_4 or from_address_ip_v_4) else 6 from_address = from_address_ip_v_4 if from_address_ip_v_4 else from_address_ip_v_6 to_address = to_address_ip_v_4 if to_address_ip_v_4 else to_address_ip_v_6 check_args_create_rule(rule_type, address, from_address, to_address, number) # type: ignore[arg-type] body = { "RuleObjDef": { "domain": domain, "ruleobjType": rule_type, "visibleToChild": visible_to_child, "description": description, "name": name, } } from_to_list = [{"FromAddress": from_address, "ToAddress": to_address}] # create the body according to the version of the NSM if VERSION == V10: d_name, extra_body = create_body_create_rule_for_v10( rule_type=rule_type, address=address, number=number, from_to_list=from_to_list, state=state ) else: d_name, extra_body = create_body_create_rule(rule_type, address, number, from_to_list) rule_obj_def = body.get("RuleObjDef", {}) rule_obj_def[d_name] = extra_body response = client.create_rule_object_request(body) response = {"ruleobjId": response.get("createdResourceId")} return CommandResults( readable_output=f'The rule object no.{response.get("ruleobjId")} was created successfully', outputs_prefix="NSM.Rule", outputs=response, raw_response=response, outputs_key_field="ruleobjId", ) def update_rule_object_command(client: Client, args: dict) -> CommandResults: """Updates a Rule Object. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with a success message. """ domain = arg_to_number(args.get("domain", 0)) or 0 rule_id = int(args.get("rule_id", "")) name = args.get("name") visible_to_child = args.get("visible_to_child") description = args.get("description") address_ip_v_4 = argToList(args.get("address_ip_v.4", None)) from_address_ip_v_4 = args.get("from_address_ip_v.4") to_address_ip_v_4 = args.get("to_address_ip_v.4") address_ip_v_6 = argToList(args.get("address_ip_v.6")) from_address_ip_v_6 = args.get("from_address_ip_v.6") to_address_ip_v_6 = args.get("to_address_ip_v.6") is_overwrite = argToBoolean(args.get("is_overwrite", False)) state: str = args.get("state", "Enabled") response_get = client.get_rule_object_request(rule_id) response_get = response_get.get("RuleObjDef", {}) rule_type = response_get.get("ruleobjType") if (rule_type == "HOST_IPV_4" or rule_type == "NETWORK_IPV_4") and ( from_address_ip_v_4 or to_address_ip_v_4 or address_ip_v_6 or from_address_ip_v_6 or to_address_ip_v_6 ): raise Exception( "If the rule object type is Endpoint IP V.4 or Network IP V.4 than only the argument " '"address_ip_v_4" should contain a value' ) elif (rule_type == "IPV_4_ADDRESS_RANGE") and ( (from_address_ip_v_4 and not to_address_ip_v_4) or (not from_address_ip_v_4 and to_address_ip_v_4) ): raise Exception( 'If the rule object type is Range IP V.4 than both "from_address_ip_v_4" and ' '"to_address_ip_v_4" must contain a value or be empty.' ) elif (rule_type == "IPV_4_ADDRESS_RANGE") and (address_ip_v_4 or address_ip_v_6 or from_address_ip_v_6 or to_address_ip_v_6): raise Exception( 'If the rule object type is Range IP V.4 than only the arguments "from_address_ip_v_4" and ' '"to_address_ip_v_4" should contain a value' ) elif (rule_type == "HOST_IPV_6" or rule_type == "NETWORK_IPV_6") and ( address_ip_v_4 or from_address_ip_v_4 or to_address_ip_v_4 or from_address_ip_v_6 or to_address_ip_v_6 ): raise Exception( "If the rule object type is Endpoint IP V.6 or Network IP V.6 than only the argument " '"address_ip_v_6" should contain a value' ) elif (rule_type == "IPV_6_ADDRESS_RANGE") and ( (from_address_ip_v_6 and not to_address_ip_v_6) or (not from_address_ip_v_6 and to_address_ip_v_6) ): raise Exception( 'If the rule object type is Range IP V.6 than both "from_address_ip_v_6" and ' '"to_address_ip_v_6" must contain a value or be empty.' ) elif (rule_type == "IPV_6_ADDRESS_RANGE") and (address_ip_v_4 or address_ip_v_6 or from_address_ip_v_4 or to_address_ip_v_4): raise Exception( 'If the rule object type is Range IP V.6 than only the arguments "from_address_ip_v_6" and ' '"to_address_ip_v_6" should contain a value' ) name = name if name else response_get.get("name") visible_to_child = argToBoolean(visible_to_child) if visible_to_child else response_get.get("visibleToChild") description = description if description else response_get.get("description") from_to_address_ip_v_6 = [] from_to_address_ip_v_4 = [] # in v9 if the user wants to overwrite the addresses we send only the new values, # in v10 we do the same thing if the user dose not want to overwrite the addresses if (VERSION == V9 and is_overwrite) or (VERSION == V10 and not is_overwrite): if rule_type == "HOST_IPV_4": address_ip_v_4 = address_ip_v_4 if address_ip_v_4 else response_get.get("HostIPv4", {}).get("hostIPv4AddressList") if rule_type == "NETWORK_IPV_4": address_ip_v_4 = address_ip_v_4 if address_ip_v_4 else response_get.get("Network_IPV_4", {}).get("networkIPV4List") if from_address_ip_v_4: from_to_address_ip_v_4 = [{"FromAddress": from_address_ip_v_4, "ToAddress": to_address_ip_v_4}] elif not from_address_ip_v_4 and rule_type == "IPV_4_ADDRESS_RANGE": from_to_address_ip_v_4 = response_get.get("IPv4AddressRange", {}).get("IPV4RangeList") if rule_type == "HOST_IPV_6": address_ip_v_6 = address_ip_v_6 if address_ip_v_6 else response_get.get("HostIPv6", {}).get("hostIPv6AddressList") if rule_type == "NETWORK_IPV_6": address_ip_v_6 = address_ip_v_6 if address_ip_v_6 else response_get.get("Network_IPV_6", {}).get("networkIPV6List") if from_address_ip_v_6: from_to_address_ip_v_6 = [{"FromAddress": from_address_ip_v_6, "ToAddress": to_address_ip_v_6}] elif not from_address_ip_v_6 and rule_type == "IPV_6_ADDRESS_RANGE": from_to_address_ip_v_6 = response_get.get("IPv6AddressRange", {}).get("IPV6RangeList") # in v9 if the user wants to add new addresses we send the old values and the new addresses, # in v10 we do the same thing if the user wants to overwrite the addresses elif (VERSION == V9 and not is_overwrite) or (VERSION == V10 and is_overwrite): if rule_type == "HOST_IPV_4": old_address_ip_v_4 = response_get.get("HostIPv4", {}).get("hostIPv4AddressList", []) if address_ip_v_4: old_address_ip_v_4.extend(address_ip_v_4) address_ip_v_4 = old_address_ip_v_4 elif rule_type == "NETWORK_IPV_4": old_address_ip_v_4 = response_get.get("Network_IPV_4", {}).get("networkIPV4List", []) if address_ip_v_4: old_address_ip_v_4.extend(address_ip_v_4) address_ip_v_4 = old_address_ip_v_4 elif rule_type == "IPV_4_ADDRESS_RANGE": from_to_address_ip_v_4 = response_get.get("IPv4AddressRange", {}).get("IPV4RangeList", []) if from_address_ip_v_4 and to_address_ip_v_4: from_to_address_ip_v_4.append({"FromAddress": from_address_ip_v_4, "ToAddress": to_address_ip_v_4}) elif rule_type == "HOST_IPV_6": old_address_ip_v_6 = response_get.get("HostIPv6", {}).get("hostIPv6AddressList", []) if address_ip_v_6: old_address_ip_v_6.extend(address_ip_v_6) address_ip_v_6 = old_address_ip_v_6 elif rule_type == "NETWORK_IPV_6": old_address_ip_v_6 = response_get.get("Network_IPV_6", {}).get("hostIPv6AddressList", []) if address_ip_v_6: old_address_ip_v_6.extend(address_ip_v_6) address_ip_v_6 = old_address_ip_v_6 elif rule_type == "IPV_6_ADDRESS_RANGE": from_to_address_ip_v_6 = response_get.get("IPv6AddressRange", {}).get("networkIPV6List", []) if from_address_ip_v_6 and to_address_ip_v_6: from_to_address_ip_v_6.append({"FromAddress": from_address_ip_v_6, "ToAddress": to_address_ip_v_6}) body = { "RuleObjDef": { "domain": domain, "ruleobjType": rule_type, "visibleToChild": visible_to_child, "description": description, "name": name, } } address = address_ip_v_4 if address_ip_v_4 else address_ip_v_6 number = 4 if (address_ip_v_4 or from_to_address_ip_v_4) else 6 from_to_list = from_to_address_ip_v_4 if from_to_address_ip_v_4 else from_to_address_ip_v_6 # create the body according to the version of the NSM if VERSION == V10: d_name, extra_body = create_body_update_rule_for_v10( rule_type=rule_type, address=address, number=number, from_to_list=from_to_list, state=state ) else: d_name, extra_body = create_body_create_rule(rule_type, address, number, from_to_list) rule_obj_def = body.get("RuleObjDef", {}) rule_obj_def[d_name] = extra_body client.update_rule_object_request(body, rule_id) return CommandResults(readable_output=f"The rule object no.{rule_id} was updated successfully.") def delete_rule_object_command(client: Client, args: dict) -> CommandResults: """Deletes a Rule Object. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with a success message. """ rule_id = int(args.get("rule_id", "")) client.delete_rule_object_request(rule_id) return CommandResults(readable_output=f"The rule object no.{rule_id} was deleted successfully") def get_alerts_command(client: Client, args: dict) -> CommandResults: """Retrieves All Alerts. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with a list of alerts. """ limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT page = arg_to_number(args.get("page")) page_size = arg_to_number(args.get("page_size")) time_period = args.get("time_period", "LAST_7_DAYS") start_time = args.get("start_time", None) end_time = args.get("end_time", None) state = args.get("state", None) search = args.get("search", None) filter_arg = args.get("filter", None) domain_id = arg_to_number(args.get("domain_id")) or 0 if args.get("new_state"): state = args.get("new_state") if (page and not page_size) or (not page and page_size): raise Exception("Please provide both page and page_size arguments.") if (start_time and not end_time) or (not start_time and end_time): raise Exception("If you provide one of the time parameters, you must provide the other as well.") if start_time and time_period != "CUSTOM": time_period = "CUSTOM" if time_period == "CUSTOM" and not start_time: raise Exception('If you enter "time_period=CUSTOM" please enter start_time and end_time as well.') if filter_arg and "name" in filter_arg: filter_arg = update_filter(filter_arg) response = client.get_alerts_request(time_period, start_time, end_time, state, search, filter_arg, domain_id) total_alerts_count = response.get("totalAlertsCount", 0) alerts_list = alerts_list_pagination( response.get("alertsList", []), limit, page, page_size, time_period, start_time, end_time, state, search, filter_arg, client, domain_id, ) result_list = [] for alert in alerts_list: record = { "ID": alert.get("event", {}).get("alertId"), "Name": alert.get("name"), "State": alert.get("alertState"), "CreatedTime": alert.get("event", {}).get("time"), "Assignee": alert.get("assignTo"), "AttackSeverity": alert.get("attackSeverity"), "Application": alert.get("application"), "EventResult": alert.get("event", {}).get("result"), "SensorID": alert.get("detection", {}).get("deviceId"), "uniqueAlertId": alert.get("uniqueAlertId"), "Event": alert.get("event"), "Attack": alert.get("attack"), "Attacker": alert.get("attacker"), "Target": alert.get("target"), "MalwareFile": alert.get("malwareFile"), "endpointExcutable": alert.get("endpointExcutable"), "detection": alert.get("detection"), "layer7Data": alert.get("layer7Data"), } event_obj = record.get("Event", {}) event_obj["domain"] = alert.get("detection", {}).get("domain") event_obj["interface"] = alert.get("detection", {}).get("interface") event_obj["device"] = alert.get("detection", {}).get("device") result_list.append(record) alerts_list = result_list contents = [] for alert_info in alerts_list: d = { "ID": alert_info.get("ID"), "Name": alert_info.get("Name"), "Event Time": alert_info.get("CreatedTime"), "Severity": alert_info.get("AttackSeverity"), "State": alert_info.get("State"), "Direction": alert_info.get("Event", {}).get("direction"), "Result": alert_info.get("Event.result"), "Attack Count": alert_info.get("EventResult"), "Attacker IP": alert_info.get("Attacker", {}).get("ipAddrs"), "Target IP": alert_info.get("Target", {}).get("ipAddrs"), } contents.append(d) headers = ["ID", "Name", "Event Time", "Severity", "State", "Direction", "Result", "Attack Count", "Attacker IP", "Target IP"] if args.get("new_state"): title = f"Updated Alerts list. Showing {len(alerts_list)} of {total_alerts_count}" else: title = f"Alerts list. Showing {len(alerts_list)} of {total_alerts_count}" readable_output = tableToMarkdown(name=title, t=contents, removeNull=True, headers=headers) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.Alerts", outputs=alerts_list, raw_response=response, outputs_key_field="ID", ) def get_alert_details_command(client: Client, args: dict) -> CommandResults: """Retrieves the relevant alert. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with the alert details. """ alert_id = int(args.get("alert_id", "")) sensor_id = int(args.get("sensor_id", "")) response = client.get_alert_details_request(alert_id, sensor_id) response = { "ID": response.get("summary", {}).get("event", {}).get("alertId"), "Name": response.get("name"), "State": response.get("alertState"), "CreatedTime": response.get("summary", {}).get("event", {}).get("time"), "Assignee": response.get("assignTo"), "Description": response.get("description", {}).get("definition"), "EventResult": response.get("summary", {}).get("event", {}).get("result"), "Attack": { "attackCategory": response.get("description", {}).get("attackCategory"), "attackSubCategory": response.get("description", {}).get("attackSubCategory"), "nspId": response.get("description", {}).get("reference", {}).get("nspId"), }, "Protocols": response.get("description", {}).get("protocols"), "SensorID": response.get("summary", {}).get("event", {}).get("deviceId"), "Event": response.get("summary", {}).get("event"), "Attacker": response.get("summary", {}).get("attacker"), "Target": response.get("summary", {}).get("target"), "MalwareFile": response.get("details", {}).get("malwareFile"), "Details": response.get("details"), "uniqueAlertId": response.get("uniqueAlertId"), "summary": response.get("summary"), "description": response.get("description"), } summary_obj = response.get("summary", {}) del summary_obj["event"] del summary_obj["attacker"] del summary_obj["target"] contents = { "ID": response.get("ID"), "Name": response.get("Name"), "Event Time": response.get("CreatedTime"), "State": response.get("State"), "Direction": response.get("Event", {}).get("direction"), "Result": response.get("EventResult"), "Attack Count": response.get("Event", {}).get("attackCount"), "Attacker IP": response.get("Attacker", {}).get("ipAddrs"), "Target IP": response.get("Target", {}).get("ipAddrs"), } headers = ["ID", "Name", "Event Time", "State", "Direction", "Result", "Attack Count", "Attacker IP", "Target IP"] readable_output = tableToMarkdown(name=f"Alert no.{alert_id}", t=contents, removeNull=True, headers=headers) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.Alerts", outputs=response, raw_response=response, outputs_key_field="uniqueAlertId", ) def get_attacks_command(client: Client, args: dict) -> List: """If an attack id is given The command returns the details for the specific attack. Else, gets all available attack definitions in the Manager UI. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with The attack details or attacks list. """ attack_id = args.get("attack_id") if attack_id and not re.match("^0x[0-9A-Fa-f]{8}$", attack_id): raise Exception("Error! Attack ID must be formatted as 32-bit hexadecimal number. for example: 0x1234BEEF") response = client.get_attacks_request(attack_id) if not attack_id: title = "Attacks List" attacks_list = response.get("AttackDescriptorDetailsList", []) else: title = f"Attack no.{attack_id}" attacks_list = [response.get("AttackDescriptor", {})] result_list = [] for attack in attacks_list: record = { "ID": attack.get("attackId"), "Name": attack.get("name"), "Direction": attack.get("DosDirection"), "Category": attack.get("description", {}).get("attackCategory"), "Severity": attack.get("Severity"), "description": attack.get("description"), } result_list.append(record) attacks_list = result_list contents = [] for attack in attacks_list: d = { "ID": attack.get("ID"), "Name": attack.get("Name"), "Direction": attack.get("Direction"), "Severity": attack.get("Severity"), "Category": attack.get("Category"), } contents.append(d) headers = ["ID", "Name", "Direction", "Severity", "Category"] readable_outputs = tableToMarkdown(name=title, t=contents, removeNull=True, headers=headers) if not attack_id: file_ = fileResult(filename="get-attacks-file-result", data=readable_outputs, file_type=entryTypes["entryInfoFile"]) return [file_] else: return [ CommandResults( readable_output=readable_outputs, outputs_prefix="NSM.Attacks", outputs=attacks_list, raw_response=attacks_list, outputs_key_field="ID", ) ] def get_domains_command(client: Client, args: dict) -> CommandResults: """If a domain id is given The command returns the details for the specific domain. Else, gets all available domains. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with The domain details or domains list. """ domain_id = arg_to_number(args.get("domain_id", None)) limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT page = arg_to_number(args.get("page")) page_size = arg_to_number(args.get("page_size")) if (page and not page_size) or (not page and page_size): raise Exception("Please provide both page and page_size arguments.") response = client.get_domains_request(domain_id) results = response.get("DomainDescriptor", {}) contents = [] if domain_id is not None: title = f"Domain no.{domain_id}" results = {"ID": results.get("id"), "Name": results.get("name"), "childdomains": results.get("childdomains")} contents = [{"ID": results.get("ID"), "Name": results.get("Name")}] else: title = "List of Domains" children = [results] h_r_get_domains(children, contents) contents = pagination(contents, limit, page, page_size) readable_outputs = tableToMarkdown(name=title, t=contents, removeNull=True) return CommandResults( readable_output=readable_outputs, outputs_prefix="NSM.Domains", outputs=results, raw_response=results, outputs_key_field="ID", ) def get_sensors_command(client: Client, args: dict) -> CommandResults: """Gets the list of sensors available in the specified domain. If the domain is not specified, details of all the sensors in all domains will be provided. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with The relevant sensors. """ domain_id = arg_to_number(args.get("domain_id")) limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT page = arg_to_number(args.get("page")) page_size = arg_to_number(args.get("page_size")) if (page and not page_size) or (not page and page_size): raise Exception("Please provide both page and page_size arguments.") response = client.get_sensors_request(domain_id) sensors_list = pagination(response.get("SensorDescriptor", [dict]), limit, page, page_size) result_list = [] for sensor in sensors_list: record = { "ID": sensor.get("sensorId"), "Name": sensor.get("name"), "Description": sensor.get("Description"), "DomainID": sensor.get("DomainID"), "IPSPolicyID": sensor.get("IPSPolicyID"), "IP Address": sensor.get("sensorIPAddress"), "model": sensor.get("model"), "isFailOver": sensor.get("isFailOver"), "isNTBA": sensor.get("isNTBA"), "isLoadBalancer": sensor.get("isLoadBalancer"), "SerialNumber": sensor.get("SerialNumber"), "SigsetVersion": sensor.get("SigsetVersion"), "DATVersion": sensor.get("DATVersion"), "SoftwareVersion": sensor.get("SoftwareVersion"), "LastSignatureUpdateTs": sensor.get("LastSignatureUpdateTs"), "ReconPolicyID": sensor.get("ReconPolicyID"), "LastModTs": sensor.get("LastModTs"), "nsmVersion": sensor.get("nsmVersion"), "MemberSensors": sensor.get("MemberSensors"), } result_list.append(record) sensors_list = result_list contents = [] for sensor in sensors_list: d = { "ID": sensor.get("ID"), "Name": sensor.get("Name"), "Description": sensor.get("Description"), "DomainID": sensor.get("DomainID"), "IPSPolicyID": sensor.get("IPSPolicyID"), "IP Address": sensor.get("IP Address"), } contents.append(d) headers = ["ID", "Name", "Description", "DomainID", "IPSPolicyID", "IP Address"] if domain_id: title = f"The Sensors of Domain no.{domain_id}" else: title = "Sensors List" readable_output = tableToMarkdown(name=title, t=contents, removeNull=True, headers=headers) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.Sensors", outputs=sensors_list, raw_response=sensors_list, outputs_key_field="ID", ) def get_ips_policies_command(client: Client, args: dict) -> CommandResults: """Gets all the IPS Policies defined in the specific domain. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with The relevant ips policies. """ domain_id = arg_to_number(args.get("domain_id")) or 0 limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT page = arg_to_number(args.get("page")) page_size = arg_to_number(args.get("page_size")) if (page and not page_size) or (not page and page_size): raise Exception("Please provide both page and page_size arguments.") response = client.get_ips_policies_request(domain_id) policies_list = pagination(response.get("PolicyDescriptorDetailsList", [dict]), limit, page, page_size) result_list = [] for policy in policies_list: record = { "ID": policy.get("policyId"), "Name": policy.get("name"), "DomainID": policy.get("DomainId"), "VisibleToChildren": policy.get("VisibleToChild"), "IsEditable": policy.get("IsEditable"), } result_list.append(record) policies_list = result_list contents = [] for policy in policies_list: d = { "ID": policy.get("ID"), "Name": policy.get("Name"), "DomainID": policy.get("DomainID"), "IsEditable": policy.get("IsEditable"), "VisibleToChildren": policy.get("VisibleToChildren"), } contents.append(d) headers = ["ID", "Name", "DomainID", "IsEditable", "VisibleToChildren"] readable_output = tableToMarkdown( name=f"IPS Policies List of Domain no.{domain_id}", t=contents, removeNull=True, headers=headers ) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.IPSPolicies", outputs=policies_list, raw_response=policies_list, outputs_key_field="ID", ) def get_ips_policy_details_command(client: Client, args: dict) -> CommandResults: """gets the policy details for the specific IPS policy. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with The relevant ips policy details. """ policy_id = int(args.get("policy_id", "")) response = client.get_ips_policy_details_request(policy_id) policy_details = response.get("PolicyDescriptor", {}) policy_details = { "ID": policy_id, "Name": policy_details.get("PolicyName"), "CreatedTime": policy_details.get("Timestamp"), "VisibleToChildren": policy_details.get("IsVisibleToChildren"), "Version": policy_details.get("VersionNum"), "ExploitAttacks": policy_details.get("AttackCategory", {}).get("ExpolitAttackList"), "Description": policy_details.get("Description"), "InboundRuleSet": policy_details.get("InboundRuleSet"), "OutboundRuleSet": policy_details.get("OutboundRuleSet"), "OutboundAttackCategory": policy_details.get("OutboundAttackCategory"), "DosPolicy": policy_details.get("DosPolicy"), "DosResponseSensitivityLevel": policy_details.get("DosResponseSensitivityLevel"), "IsEditable": policy_details.get("IsEditable"), "IsLightWeightPolicy": policy_details.get("IsLightWeightPolicy"), } contents = { "ID": policy_details.get("ID"), "Name": policy_details.get("Name"), "Description": policy_details.get("Description"), "CreatedTime": policy_details.get("CreatedTime"), "IsEditable": policy_details.get("IsEditable"), "VisibleToChildren": policy_details.get("VisibleToChildren"), "Version": policy_details.get("Version"), "InboundRuleSet": policy_details.get("InboundRuleSet"), "OutboundRuleSet": policy_details.get("OutboundRuleSet"), } headers = [ "ID", "Name", "Description", "CreatedTime", "IsEditable", "VisibleToChildren", "Version", "InboundRuleSet", "OutboundRuleSet", ] readable_output = tableToMarkdown(name=f"IPS Policy no.{policy_id} Details", t=contents, removeNull=True, headers=headers) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.IPSPolicies", outputs=policy_details, raw_response=policy_details, outputs_key_field="ID", ) def update_alerts_command(client: Client, args: dict) -> CommandResults: """Updates all the relevant alerts. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with the list of the changed alerts. """ state = args.get("state", "Any") time_period = args.get("time_period", None) start_time = args.get("start_time", None) end_time = args.get("end_time", None) new_state = args.get("new_state", None) new_assignee = args.get("new_assignee", None) search = args.get("search", None) filter_arg = args.get("filter", None) if not new_state and not new_assignee: raise Exception("Error! You must specify a new alert state or a new assignee") if (start_time and not end_time) or (not start_time and end_time): raise Exception("If you provide one of the time parameters, you must provide the other as well") if start_time and time_period != "CUSTOM": time_period = "CUSTOM" if filter_arg and "name" in filter_arg: filter_arg = update_filter(filter_arg) body = {"alertState": new_state, "assignTo": new_assignee} response = client.update_alerts_request(time_period, start_time, end_time, state, search, filter_arg, body) if response.get("status") != 1: raise Exception("Error! Failed to update alerts.") return get_alerts_command(client, args) def list_pcap_file_command(client: Client, args: dict) -> CommandResults: """Retrieves the list of captured PCAP files. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with a list of captured PCAP files. """ sensor_id = int(args.get("sensor_id", "")) limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT page = arg_to_number(args.get("page")) page_size = arg_to_number(args.get("page_size")) if (page and not page_size) or (not page and page_size): raise Exception("Please provide both page and page_size arguments.") response = client.list_pcap_file_request(sensor_id) files_list = pagination(response.get("files", []), limit, page, page_size) contents = [] for file_name in files_list: d = {"FileName": file_name} contents.append(d) readable_output = tableToMarkdown(name="PCAP files List", t=contents, removeNull=True) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.PcapFile", outputs=files_list, raw_response=files_list ) def export_pcap_file_command(client: Client, args: dict) -> List: """Exports the captured PCAP file. Args: client: client - A McAfeeNSM client. args: Dict - The function arguments. Returns: A CommandResult object with a list of captured PCAP files. """ sensor_id = int(args.get("sensor_id", "")) file_name = args.get("file_name") body = {"fileName": file_name} response = client.export_pcap_file_request(sensor_id, body) file_ = fileResult(filename=file_name, data=response.content, file_type=EntryType.ENTRY_INFO_FILE) return [file_] def list_domain_device_command(client: Client, args: dict) -> CommandResults: """ Retrieves the list of devices related to a given domain. Args: client(Client): client - A McAfeeNSM client. args(Dict): - The function arguments. Returns: A CommandResult object with a list of domain devices. """ domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True) domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id) limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) all_results = argToBoolean(args.get("all_results", False)) response = client.list_domain_device_request(domain_id) devices: List = response.get("DeviceResponseList", []) capitalize_devices = capitalize_key_first_letter(devices) if all_results else capitalize_key_first_letter(devices)[:limit] readable_output = tableToMarkdown(name="Domain devices List", t=capitalize_devices, removeNull=True) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.Device", outputs=capitalize_devices, raw_response=response, ) def list_device_interface_command(client: Client, args: dict) -> CommandResults: """ Retrieves the list of interfaces related to a given device. Args: client(Client): client - A McAfeeNSM client. args(Dict): - The function arguments. Returns: A CommandResult object with a list of device interfaces. """ device_id = arg_to_number(args.get("device_id"), arg_name="device_id", required=True) device_id = check_required_arg(arg_name="device_id", arg_value=device_id) domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True) domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id) limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) all_results = argToBoolean(args.get("all_results", False)) response = client.list_device_interface_request(domain_id=domain_id, device_id=device_id) interfaces = response.get("allocatedInterfaceList", []) key_list = ["interfaceId", "interfaceName", "interfaceType"] capitalize_interfaces = ( capitalize_key_first_letter(interfaces, key_list) if all_results else capitalize_key_first_letter(interfaces, key_list)[:limit] ) readable_output = tableToMarkdown(name="Device interfaces List", t=capitalize_interfaces, removeNull=True) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.Interface", outputs=capitalize_interfaces, raw_response=response ) def assign_device_policy_command(client: Client, args: dict) -> CommandResults: """ Assigns a policy to a device. Args: client(Client): client - A McAfeeNSM client. args(Dict): - The function arguments. Returns: A CommandResult object with a success or failure message. """ device_id = arg_to_number(args.get("device_id"), arg_name="device_id", required=True) device_id = check_required_arg(arg_name="device_id", arg_value=device_id) domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True) domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id) pre_firewall_policy = args.get("pre_firewall_policy_name") post_firewall_policy = args.get("post_firewall_policy_name") response = client.assign_device_policy_request( domain_id=domain_id, device_id=device_id, pre_firewall_policy=pre_firewall_policy, post_firewall_policy=post_firewall_policy, ) readable_output = "Policy assigned successfully." if response.get("status") == 1 else "Policy assignment failed." return CommandResults(readable_output=readable_output, raw_response=response) def list_device_policy_command(client: Client, args: dict) -> CommandResults: """ Retrieves a list of policies related to the domain or a specific device. Args: client(Client): client - A McAfeeNSM client. args(Dict): - The function arguments. Returns: A CommandResult object with a list of device policies. """ device_id = arg_to_number(args.get("device_id")) domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True) domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id) limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) all_results = argToBoolean(args.get("all_results", False)) response = client.list_device_policy_request(domain_id=domain_id, device_id=device_id) all_policies = response.get("policyAssignmentsList", []) capitalize_policies = ( capitalize_key_first_letter(all_policies) if all_results else capitalize_key_first_letter(all_policies)[:limit] ) readable_output = tableToMarkdown(name="Device policy List", t=capitalize_policies, removeNull=True) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.DevicePolicy", outputs=capitalize_policies, raw_response=response ) def assign_interface_policy_command(client: Client, args: dict) -> CommandResults: """ Assigns an existing policy to an interface. Args: client(Client): - A McAfeeNSM client. args(Dict): - The function arguments. Returns: A CommandResult object with a success or failure message. """ domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True) domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id) interface_id = arg_to_number(args.get("interface_id"), arg_name="interface_id", required=True) interface_id = check_required_arg(arg_name="interface_id", arg_value=interface_id) firewall_policy = args.get("firewall_policy_name") firewall_port_policy = args.get("firewall_port_policy_name") ips_policy = args.get("ips_policy_name") custom_policy_json: str = args.get("custom_policy_json") or "" custom_policy_json = json.loads(custom_policy_json) if custom_policy_json else {} # Check if at least one policy was provided if not firewall_policy and not firewall_port_policy and not ips_policy and not custom_policy_json: raise DemistoException("Please provide at least one policy to assign.") response = client.assign_interface_policy_request( domain_id=domain_id, interface_id=interface_id, firewall_policy=firewall_policy, firewall_port_policy=firewall_port_policy, ips_policy=ips_policy, custom_policy_json=custom_policy_json, ) readable_output = "Policy assigned successfully." if response.get("status") == 1 else "Policy assignment failed." return CommandResults(readable_output=readable_output, raw_response=response) def list_interface_policy_command(client: Client, args: dict) -> CommandResults: """ Retrieves a list of policies related to the domain or a specific interface. Args: client (Client): - A McAfeeNSM client. args (Dict): - The function arguments. Returns: A CommandResult object with a list of policies. """ domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True) domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id) interface_id = arg_to_number(args.get("interface_id")) limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) all_results = argToBoolean(args.get("all_results", False)) response = client.list_interface_policy_request(domain_id=domain_id, interface_id=interface_id) all_policies: list = [response] if interface_id else response.get("policyAssignmentsList") or [] capitalize_policies = ( capitalize_key_first_letter(all_policies) if all_results else capitalize_key_first_letter(all_policies)[:limit] ) return CommandResults( readable_output=tableToMarkdown(name="Interface policy List", t=capitalize_policies, removeNull=True), outputs_prefix="NSM.InterfacePolicy", outputs=capitalize_policies, raw_response=response, ) def get_device_configuration_command(client: Client, args: dict) -> CommandResults: """ Retrieves the configuration of a device(e.g pending changes). Args: client (Client): - A McAfeeNSM client. args (Dict): - The function arguments. Returns: A CommandResult object with the device configuration information. """ device_id = arg_to_number(args.get("device_id"), arg_name="device_id", required=True) device_id = check_required_arg(arg_name="device_id", arg_value=device_id) response = client.get_device_configuration_request(device_id=device_id) capitalize_response = capitalize_key_first_letter([response])[0] flattened_response = flatten_and_capitalize(main_dict=capitalize_response, inner_dict_key="PendingChanges") readable_output = tableToMarkdown(name="Device Configuration", t=flattened_response, removeNull=True) return CommandResults( readable_output=readable_output, outputs_prefix="NSM.DeviceConfiguration", outputs=flattened_response, raw_response=response, ) @polling_function(name="nsm-deploy-device-configuration", interval=INTERVAL, requires_polling_arg=False) def deploy_device_configuration_command(args: dict, client: Client) -> PollResult: """ Deploy the configuration of a device.(e.g activate pending changes). Args: args (Dict): - The function arguments. client (Client): - A McAfeeNSM client. Returns: A PollResult object with a success or failure message. """ request_id = arg_to_number(args.get("request_id")) device_id = arg_to_number(args.get("device_id"), arg_name="device_id", required=True) device_id = check_required_arg(arg_name="device_id", arg_value=device_id) if not request_id: # if this is the first time the function is called is_ssl_push_required = argToBoolean(args.get("push_ssl_key", False)) is_gam_update_required = argToBoolean(args.get("push_gam_updates", False)) is_sigset_config_push_required = argToBoolean(args.get("push_configuration_signature_set", False)) is_botnet_push_required = argToBoolean(args.get("push_botnet", False)) if not any([is_ssl_push_required, is_gam_update_required, is_sigset_config_push_required, is_botnet_push_required]): raise DemistoException("Please provide at least one argument to deploy.") if requests_id := client.deploy_device_configuration_request( device_id=device_id, is_SSL_Push_Required=is_ssl_push_required, is_GAM_Update_Required=is_gam_update_required, is_Sigset_Config_Push_Required=is_sigset_config_push_required, is_Botnet_Push_Required=is_botnet_push_required, ).get("RequestId"): args["request_id"] = requests_id else: raise DemistoException("Failed to deploy the device configuration.") status = client.check_deploy_device_configuration_request_status(device_id=device_id, request_id=request_id) fail_or_success_list, message_to_return = deploy_polling_message(args=args, status=status) message = CommandResults(readable_output=f"{message_to_return}\n\nChecking again in {INTERVAL} seconds...") if not all(fail_or_success_list): # if one of the arguments was not fully deployed yet, the polling will continue return PollResult( partial_result=message, response=None, continue_to_poll=True, args_for_next_run={"request_id": request_id, "device_id": device_id, **args}, ) message = CommandResults(readable_output="The device configuration has been deployed successfully.") return PollResult(response=message, continue_to_poll=False) """ MAIN FUNCTION """ def main() -> None: # pragma: no cover args = demisto.args() command = demisto.command() params = demisto.params() url = f"{params.get('url')}/sdkapi" user_name = params.get("credentials", {}).get("identifier", "") password = params.get("credentials", {}).get("password", "") verify_certificate = not params.get("insecure", False) proxy = params.get("proxy", False) auth = (user_name, password) demisto.debug(f"Command being called is {command}") try: headers: dict = {"Accept": "application/vnd.nsm.v1.0+json", "Content-Type": "application/json"} client = Client(url=url, auth=auth, headers=headers, proxy=proxy, verify=verify_certificate) if command != "test-module": session_str = get_session(client, f"{user_name}:{password}") headers["NSM-SDK-API"] = session_str client = Client(url=url, auth=auth, headers=headers, proxy=proxy, verify=verify_certificate) results: Union[CommandResults, list[CommandResults], str] if command == "test-module": # This is the call made when pressing the integration Test button. results = test_module(client, f"{user_name}:{password}") # return_results(str_results) elif command == "nsm-list-domain-firewall-policy": results = list_domain_firewall_policy_command(client, args) elif command == "nsm-get-firewall-policy": results = get_firewall_policy_command(client, args) elif command == "nsm-create-firewall-policy": results = create_firewall_policy_command(client, args) elif command == "nsm-update-firewall-policy": results = update_firewall_policy_command(client, args) elif command == "nsm-delete-firewall-policy": results = delete_firewall_policy_command(client, args) elif command == "nsm-list-domain-rule-object": results = list_domain_rule_objects_command(client, args) elif command == "nsm-get-rule-object": results = get_rule_object_command(client, args) elif command == "nsm-create-rule-object": results = create_rule_object_command(client, args) elif command == "nsm-update-rule-object": results = update_rule_object_command(client, args) elif command == "nsm-delete-rule-object": results = delete_rule_object_command(client, args) elif command == "nsm-get-alerts": results = get_alerts_command(client, args) elif command == "nsm-get-alert-details": results = get_alert_details_command(client, args) elif command == "nsm-get-attacks": results = get_attacks_command(client, args) elif command == "nsm-get-domains": results = get_domains_command(client, args) elif command == "nsm-get-sensors": results = get_sensors_command(client, args) elif command == "nsm-get-ips-policies": results = get_ips_policies_command(client, args) elif command == "nsm-get-ips-policy-details": results = get_ips_policy_details_command(client, args) elif command == "nsm-update-alerts": results = update_alerts_command(client, args) elif command == "nsm-list-pcap-file": results = list_pcap_file_command(client, args) elif command == "nsm-export-pcap-file": results = export_pcap_file_command(client, args) elif command == "nsm-list-device-interface": results = list_device_interface_command(client, args) elif command == "nsm-list-domain-device": results = list_domain_device_command(client, args) elif command == "nsm-assign-device-policy": results = assign_device_policy_command(client, args) elif command == "nsm-list-device-policy": results = list_device_policy_command(client, args) elif command == "nsm-assign-interface-policy": results = assign_interface_policy_command(client, args) elif command == "nsm-list-interface-policy": results = list_interface_policy_command(client, args) elif command == "nsm-get-device-configuration": results = get_device_configuration_command(client, args) elif command == "nsm-deploy-device-configuration": results = deploy_device_configuration_command(args, client) else: raise NotImplementedError("This command is not implemented yet.") return_results(results) # Log exceptions and return errors except Exception as e: return_error(f"Failed to execute {command} command.\nError:\n{e!s}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()