InfobloxBloxOneThreatDefense

Infoblox Threat Defense with DDI integration leverages DNS as the first line of defense to detect and block cyber threats, while also using threat intelligence to manage SOC Insight incident response and enrich indicators.

Data Enrichment & Threat Intelligence · Infoblox Threat Defense with DDI

Details

IDInfobloxBloxOneThreatDefense
ProviderInfoblox
CategoryData Enrichment & Threat Intelligence
From Version6.5.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Infoblox Threat Defense with DDI integration leverages DNS as the first line of defense to detect and block cyber threats, while also using threat intelligence to manage insight incident response and enrich indicators.
This integration was integrated and tested with version 1.0.0 of Infoblox Threat Defense with DDI.

Configure Infoblox Threat Defense with DDI in Cortex

Parameter Description Required
Service API Key   True
Source Reliability Reliability of the source providing the intelligence data. False
Create relationships Create relationships between indicators as part of Enrichment. False
Fetch incidents   False
Incident type   False
Ingestion Type Select the ingestion type to fetch as XSOAR incident. Default is SOC Insight. False
SOC Insight Status Retrieve the SOC Insights as specified status. False
SOC Insight Threat Type Retrieve the SOC Insights as specified threat type. False
SOC Insight Priority Level Retrieve the SOC Insights as specified priority level. False
DNS Security Event Feed Name Retrieve the DNS Security Events as specified feed name or custom list name. False
DNS Security Event Network Retrieve the DNS Security Events as specified network name. False
DNS Security Event Policy Action Retrieve the DNS Security Events as specified policy action. False
DNS Security Event Policy Name Retrieve the DNS Security Events as specified policy name. False
DNS Security Event Queried Name Retrieve the DNS Security Events as specified queried name. False
DNS Security Event Threat Class Retrieve the DNS Security Events as specified threat class. False
DNS Security Event Threat Family Retrieve the DNS Security Events as specified threat family. False
DNS Security Event Threat Indicator Retrieve the DNS Security Events as specified threat indicator. False
DNS Security Event Threat Level Retrieve the DNS Security Events as specified threat level. False
Max Fetch The maximum number of SOC Insights or DNS Security Events to fetch each time. If the value is greater than 200, it will be considered as 200. The maximum is 200. False
First fetch timestamp The date or relative timestamp from which to begin fetching incidents. Note: This parameter is only applicable for DNS Security Events.

Supported formats: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 May 2025, 01 May 2025 04:45:33, 2025-05-17T14:05:44Z.
False
Incidents Fetch Interval   False
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.

bloxone-td-dossier-lookup-get


The Dossier Lookup API returns detailed information on the specified indicator from the requested sources.

Base Command

bloxone-td-dossier-lookup-get

Input

Argument Name Description Required
indicator_type The type of indcator to search by. Possible values are: host, ip, url, hash, email. Required
value The indicator to search on. Required
sources The sources to query. Multiple sources can be specified. If no source is specified, the call will search on all available sources. (You can see the list of the available sources by running bloxone-td-dossier-source-list). Optional
interval_in_seconds The interval in seconds between each poll. Default is 10. Optional
timeout The timeout in seconds until polling ends. Default is 600. Optional
job_id used for polling. Optional

Context Output

Path Type Description
BloxOneTD.DossierLookup.source String The Dossier source.
BloxOneTD.DossierLookup.target String The targeted indicator.
BloxOneTD.DossierLookup.task_id String The Dossier task ID.
BloxOneTD.DossierLookup.type String The indicator type.

Command example

!bloxone-td-dossier-lookup-get indicator_type="ip" value="11.22.33.44" sources="activity,threatfox,ccb"

Context Example

{
    "BloxOneTD": {
        "DossierLookup": [
            {
                "params": {
                    "source": "ccb",
                    "target": "11.22.33.44",
                    "type": "ip"
                },
                "status": "success",
                "task_id": "97bdeca2-b66d-47b1-b1ef-9e4833654df2",
                "time": 6401,
                "v": "3.0.0"
            },
            {
                "data": {
                    "impacted_devices": [],
                    "requests_by_day": []
                },
                "params": {
                    "source": "activity",
                    "target": "11.22.33.44",
                    "type": "ip"
                },
                "status": "success",
                "task_id": "4074cb34-2bec-485d-8d6d-9e9cc88d5229",
                "time": 1708,
                "v": "3.0.0"
            },
            {
                "data": {
                    "matches": []
                },
                "params": {
                    "source": "threatfox",
                    "target": "11.22.33.44",
                    "type": "ip"
                },
                "status": "success",
                "task_id": "73892ea3-1e22-433f-bc74-f59133b914d0",
                "time": 8,
                "v": "3.0.0"
            }
        ]
    }
}

Human Readable Output

Lookalike Domain List

Task Id Type Target Source
d418b8d6-831c-4f6f-a31a-6d48995d2267 ip 11.22.33.44 threatfox
91945be3-0cef-4d03-afd7-e4f25864553d ip 11.22.33.44 ccb
7145a1ca-40a9-43df-b0a3-c4281e5abd7e ip 11.22.33.44 activity

bloxone-td-dossier-source-list


Get available Dossier sources.

Base Command

bloxone-td-dossier-source-list

Input

There are no input arguments for this command.

Context Output

Path Type Description
BloxOneTD.DossierSource String Available Dossier sources.

Command example


#### Context Example

```json
{
    "BloxOneTD": {
        "DossierSource": [
            "ccb",
            "activity",
            "geo",
            "threatfox"
        ]
    }
}

Human Readable Output

Results

DossierSource
activity
ccb
geo
threatfox

bloxone-td-lookalike-domain-list


Get lookalike domain lists.

Notice: Submitting indicators using this command might make the indicator data publicly available. See the vendor’s documentation for more details.

Base Command

bloxone-td-lookalike-domain-list

Input

Argument Name Description Required
filter The free query filter argument. Optional
target_domain Filter by target domain. Optional
detected_at Filter by values that are greater than or equal to the given value. You can use ISO format (e.g. ‘2023-02-14T00:11:22Z’) or use a relative time (e.g. “3 days”). Optional
limit Maximum number of results to return from the query. Default is 50. Optional
offset Return results starting at this offset. Should be an integer. Default is 0. Optional

Context Output

Path Type Description
BloxOneTD.LookalikeDomain.detected_at Date The date of the lookalike detection.
BloxOneTD.LookalikeDomain.lookalike_domain String The lookalike domain.
BloxOneTD.LookalikeDomain.lookalike_host String The lookalike host.
BloxOneTD.LookalikeDomain.reason String The reason for the detection.
BloxOneTD.LookalikeDomain.target_domain String The domain that was targeted by the lookalike domain.

Command example

!bloxone-td-lookalike-domain-list detected_at="1y"

Context Example

{
    "BloxOneTD": {
        "LookalikeDomain": [
            {
                "detected_at": "2023-01-27T18:43:01Z",
                "lookalike_domain": "test.a.com",
                "lookalike_host": "test.a.com",
                "reason": "Domain is a lookalike to test.com. The creation date is 2023-01-22.",
                "target_domain": "test.com"
            },
            {
                "detected_at": "2023-01-28T18:36:27Z",
                "lookalike_domain": "test.b.com",
                "lookalike_host": "test.b.com",
                "reason": "Domain is a lookalike to test.com and has suspicious registration, behavior, or associations with known threats. The creation date is 2022-11-30.",
                "suspicious": true,
                "target_domain": "test.com"
            },
            {
                "detected_at": "2023-01-28T18:37:03Z",
                "lookalike_domain": "test.c.com",
                "lookalike_host": "test.c.com",
                "reason": "Domain is a lookalike to test.com. The creation date is 2022-09-18.",
                "target_domain": "test.com"
            }
        ]
    }
}

Human Readable Output

Results

Detected At Lookalike Domain Lookalike Host Reason Target Domain
2023-01-27T18:43:01Z test.a.com test.a.com Domain is a lookalike to test.com. The creation date is 2023-01-22. test.com
2023-01-28T18:36:27Z test.b.com test.b.com Domain is a lookalike to test.com and has suspicious registration, behavior, or associations with known threats. The creation date is 2022-11-30. test.com
2023-01-28T18:37:03Z test.c.com test.c.com Domain is a lookalike to test.com. The creation date is 2022-09-18. test.com

infobloxcloud-block-ip


The given IP addresses will be added to the provided block list.

Base Command

infobloxcloud-block-ip

Input

Argument Name Description Required
ip Specify the IP addresses to block. Supports comma-separated values. Required
custom_list_name Specify the name of the custom list to add the given IP addresses to. Default is Default Block. Optional
custom_list_type Specify the type of the custom list to add the given IP addresses to. Possible values are: default_block, custom_list, threat_insight, dga, dnsm, zero_day_dns, threat_insight_nde. Default is default_block. Optional

Context Output

Path Type Description
InfobloxCloud.CustomList.id String The ID of the custom list.
InfobloxCloud.CustomList.name String The name of the custom list.
InfobloxCloud.CustomList.type String The type of the custom list.
InfobloxCloud.CustomList.items String The items in the custom list.
InfobloxCloud.CustomList.items_described Array The items described in the custom list.
InfobloxCloud.CustomList.item_count Number The number of items in the custom list.
InfobloxCloud.CustomList.confidence_level String The confidence level of the custom list.
InfobloxCloud.CustomList.created_time String The time the custom list was created.
InfobloxCloud.CustomList.last_updated_time String The time the custom list was last updated.
InfobloxCloud.CustomList.description String The description of the custom list.
InfobloxCloud.CustomList.policies String The policies of the custom list.
InfobloxCloud.CustomList.tags String The tags of the custom list.
InfobloxCloud.CustomList.type String The type of the custom list.
InfobloxCloud.CustomList.threat_level String The threat level of the custom list.

Command example

!infobloxcloud-block-ip ip=0.0.0.0

Context Example

{
    "InfobloxCloud": {
        "CustomList": {
            "confidence_level": "HIGH",
            "created_time": "2024-04-01T18:24:37Z",
            "description": "Auto-generated",
            "id": 456789,
            "item_count": 2,
            "items": [
                "0.0.0.0/32",
                "0.0.0.1/32"
            ],
            "items_described": [
                {
                    "description": "",
                    "item": "0.0.0.0/32",
                    "status": "ACTIVE",
                    "status_details": ""
                },
                {
                    "description": "",
                    "item": "0.0.0.1/32",
                    "status": "ACTIVE",
                    "status_details": ""
                }
            ],
            "name": "Test Block",
            "policies": [
                "Test Policy"
            ],
            "tags": {
                "test_key": "test_value"
            },
            "threat_level": "MEDIUM",
            "type": "test_block",
            "updated_time": "2025-07-29T08:47:54Z"
        }
    }
}

Human Readable Output

‘0.0.0.0’ indicators added to the ‘Test Block’ list

ID Name Type Description Items Confidence Level Threat Level Tags Created Time Updated Time
792594 Test Block test_block Auto-generated 0.0.0.0/32,
0.0.0.1/32
HIGH MEDIUM test_key: test_value 2024-04-01T18:24:37Z 2025-07-29T08:47:54Z

infobloxcloud-unblock-ip


The given IP addresses will be added to the provided allow list.

Base Command

infobloxcloud-unblock-ip

Input

Argument Name Description Required
ip Specify the IP addresses to unblock. Supports comma-separated values. Required
custom_list_name Specify the name of the custom list to add the given IP addresses to. Default is Default Allow. Optional
custom_list_type Specify the type of the custom list to add the given IP addresses to. Possible values are: default_allow, custom_list, threat_insight, threat_insight_nde. Default is default_allow. Optional

Context Output

Path Type Description
InfobloxCloud.CustomList.id String The ID of the custom list.
InfobloxCloud.CustomList.name String The name of the custom list.
InfobloxCloud.CustomList.type String The type of the custom list.
InfobloxCloud.CustomList.items String The items in the custom list.
InfobloxCloud.CustomList.items_described Array The items described in the custom list.
InfobloxCloud.CustomList.item_count Number The number of items in the custom list.
InfobloxCloud.CustomList.confidence_level String The confidence level of the custom list.
InfobloxCloud.CustomList.created_time String The time the custom list was created.
InfobloxCloud.CustomList.last_updated_time String The time the custom list was last updated.
InfobloxCloud.CustomList.description String The description of the custom list.
InfobloxCloud.CustomList.policies String The policies of the custom list.
InfobloxCloud.CustomList.tags String The tags of the custom list.
InfobloxCloud.CustomList.type String The type of the custom list.
InfobloxCloud.CustomList.threat_level String The threat level of the custom list.

Command example

!infobloxcloud-unblock-ip ip=0.0.0.0

Context Example

{
    "InfobloxCloud": {
        "CustomList": {
            "confidence_level": "HIGH",
            "created_time": "2024-04-01T18:24:37Z",
            "description": "Auto-generated",
            "id": 123456,
            "item_count": 2,
            "items": [
                "0.0.0.0/32",
                "0.0.0.1/32"
            ],
            "items_described": [
                {
                    "description": "",
                    "item": "0.0.0.0/32",
                    "status": "ACTIVE",
                    "status_details": ""
                },
                {
                    "description": "",
                    "item": "0.0.0.1/32",
                    "status": "ACTIVE",
                    "status_details": ""
                }
            ],
            "name": "Test Allow",
            "policies": [
                "Test Policy"
            ],
            "tags": {
                "test_key": "test_value"
            },
            "threat_level": "MEDIUM",
            "type": "test_allow",
            "updated_time": "2025-07-29T08:48:02Z"
        }
    }
}

Human Readable Output

‘0.0.0.0’ indicators added to the ‘Test Allow’ list

ID Name Type Description Items Confidence Level Threat Level Tags Created Time Updated Time
123456 Test Allow test_allow Auto-generated 0.0.0.0/32,
0.0.0.1/32
HIGH MEDIUM test_key: test_value 2024-04-01T18:24:37Z 2025-07-29T08:48:02Z

infobloxcloud-block-domain


The given domains will be added to the provided block list.

Base Command

infobloxcloud-block-domain

Input

Argument Name Description Required
domain Specify the Domains to block. Supports comma-separated values. Required
custom_list_name Specify the name of the custom list to add the given domains to. Default is Default Block. Optional
custom_list_type Specify the type of the custom list to add the given domains to. Possible values are: default_block, custom_list, threat_insight, dga, dnsm, zero_day_dns, threat_insight_nde. Default is default_block. Optional

Context Output

Path Type Description
InfobloxCloud.CustomList.id String The ID of the custom list.
InfobloxCloud.CustomList.name String The name of the custom list.
InfobloxCloud.CustomList.type String The type of the custom list.
InfobloxCloud.CustomList.items String The items in the custom list.
InfobloxCloud.CustomList.items_described Array The items described in the custom list.
InfobloxCloud.CustomList.item_count Number The number of items in the custom list.
InfobloxCloud.CustomList.confidence_level String The confidence level of the custom list.
InfobloxCloud.CustomList.created_time String The time the custom list was created.
InfobloxCloud.CustomList.last_updated_time String The time the custom list was last updated.
InfobloxCloud.CustomList.description String The description of the custom list.
InfobloxCloud.CustomList.policies String The policies of the custom list.
InfobloxCloud.CustomList.tags String The tags of the custom list.
InfobloxCloud.CustomList.type String The type of the custom list.
InfobloxCloud.CustomList.threat_level String The threat level of the custom list.

Command example

!infobloxcloud-block-domain domain="test.com"

Context Example

{
    "InfobloxCloud": {
        "CustomList": {
            "confidence_level": "HIGH",
            "created_time": "2024-04-01T18:24:37Z",
            "description": "Auto-generated",
            "id": 456789,
            "item_count": 2,
            "items": [
                "test.com",
                "test.org"
            ],
            "items_described": [
                {
                    "description": "",
                    "item": "test.com",
                    "status": "ACTIVE",
                    "status_details": ""
                },
                {
                    "description": "",
                    "item": "test.org",
                    "status": "ACTIVE",
                    "status_details": ""
                }
            ],
            "name": "Test Block",
            "policies": [
                "Test Policy"
            ],
            "tags": null,
            "threat_level": "MEDIUM",
            "type": "test_block",
            "updated_time": "2025-07-29T10:27:49Z"
        }
    }
}

Human Readable Output

‘test.com’ indicator added to the ‘Test Block’ list

ID Name Type Description Items Confidence Level Threat Level Created Time Updated Time
456789 Test Block test_block Auto-generated test.com,
test.org
HIGH MEDIUM 2024-04-01T18:24:37Z 2025-07-29T10:27:49Z

infobloxcloud-unblock-domain


The given domains will be added to the provided allow list.

Base Command

infobloxcloud-unblock-domain

Input

Argument Name Description Required
domain Specify the Domains to unblock. Supports comma-separated values. Required
custom_list_name Specify the name of the custom list to add the given domains to. Default is Default Allow. Optional
custom_list_type Specify the type of the custom list to add the given domains to. Possible values are: default_allow, custom_list, threat_insight, threat_insight_nde. Default is default_allow. Optional

Context Output

Path Type Description
InfobloxCloud.CustomList.id String The ID of the custom list.
InfobloxCloud.CustomList.name String The name of the custom list.
InfobloxCloud.CustomList.type String The type of the custom list.
InfobloxCloud.CustomList.items String The items in the custom list.
InfobloxCloud.CustomList.items_described Array The items described in the custom list.
InfobloxCloud.CustomList.item_count Number The number of items in the custom list.
InfobloxCloud.CustomList.confidence_level String The confidence level of the custom list.
InfobloxCloud.CustomList.created_time String The time the custom list was created.
InfobloxCloud.CustomList.last_updated_time String The time the custom list was last updated.
InfobloxCloud.CustomList.description String The description of the custom list.
InfobloxCloud.CustomList.policies String The policies of the custom list.
InfobloxCloud.CustomList.tags String The tags of the custom list.
InfobloxCloud.CustomList.type String The type of the custom list.
InfobloxCloud.CustomList.threat_level String The threat level of the custom list.

Command example

!infobloxcloud-unblock-domain domain="test.com"

Context Example

{
    "InfobloxCloud": {
        "CustomList": {
            "confidence_level": "HIGH",
            "created_time": "2024-04-01T18:24:37Z",
            "description": "Auto-generated",
            "id": 123456,
            "item_count": 2,
            "items": [
                "test.com",
                "test.org"
            ],
            "items_described": [
                {
                    "description": "",
                    "item": "test.com",
                    "status": "ACTIVE",
                    "status_details": ""
                },
                {
                    "description": "",
                    "item": "test.org",
                    "status": "ACTIVE",
                    "status_details": ""
                }
            ],
            "name": "Test Allow",
            "policies": [
                "Test Policy"
            ],
            "tags": {
                "test_key": "test_value"
            },
            "threat_level": "MEDIUM",
            "type": "test_allow",
            "updated_time": "2025-07-29T10:27:56Z"
        }
    }
}

Human Readable Output

‘test.com’ indicator added to the ‘Test Allow’ list

ID Name Type Description Items Confidence Level Threat Level Tags Created Time Updated Time
123456 Test Allow test_allow Auto-generated test.com,
test.org
HIGH MEDIUM test_key: test_value 2024-04-01T18:24:37Z 2025-07-29T10:27:56Z

infobloxcloud-customlist-indicator-remove


The given indicators will be removed from the provided custom list.

Base Command

infobloxcloud-customlist-indicator-remove

Input

Argument Name Description Required
indicators Specify the indicators to remove from the custom list. Format accepted is: “0.0.0.0, example.com”. Required
custom_list_name Specify the name of the custom list to remove the given indicators from. Required
custom_list_type Specify the type of the custom list to remove the given indicators from. Possible values are: default_allow, default_block, custom_list, threat_insight, dga, dnsm, zero_day_dns, threat_insight_nde. Required

Context Output

Path Type Description
InfobloxCloud.CustomList.id String The ID of the custom list.
InfobloxCloud.CustomList.name String The name of the custom list.
InfobloxCloud.CustomList.type String The type of the custom list.
InfobloxCloud.CustomList.items String The items in the custom list.
InfobloxCloud.CustomList.items_described Array The items described in the custom list.
InfobloxCloud.CustomList.item_count Number The number of items in the custom list.
InfobloxCloud.CustomList.confidence_level String The confidence level of the custom list.
InfobloxCloud.CustomList.created_time String The time the custom list was created.
InfobloxCloud.CustomList.last_updated_time String The time the custom list was last updated.
InfobloxCloud.CustomList.description String The description of the custom list.
InfobloxCloud.CustomList.policies String The policies of the custom list.
InfobloxCloud.CustomList.tags String The tags of the custom list.
InfobloxCloud.CustomList.type String The type of the custom list.
InfobloxCloud.CustomList.threat_level String The threat level of the custom list.

Command example

!infobloxcloud-customlist-indicator-remove indicators="0.0.0.0" custom_list_name="Test Allow" custom_list_type="test_allow"

Context Example

{
    "InfobloxCloud": {
        "CustomList": {
            "confidence_level": "HIGH",
            "created_time": "2024-04-01T18:24:37Z",
            "description": "Auto-generated",
            "id": 123456,
            "item_count": 1,
            "items": [
                "example.com"
            ],
            "items_described": [
                {
                    "description": "",
                    "item": "example.com",
                    "status": "ACTIVE",
                    "status_details": ""
                }
            ],
            "name": "Test Allow",
            "policies": [
                "Test Policy",
            ],
            "tags": {
                "test_key": "test_value"
            },
            "threat_level": "MEDIUM",
            "type": "test_allow",
            "updated_time": "2025-07-31T11:07:41Z"
        }
    }
}

Human Readable Output

‘0.0.0.0’ indicators removed from the ‘Test Allow’ list

ID Name Type Description Items Confidence Level Threat Level Tags Created Time Updated Time
123456 Test Allow test_allow Auto-generated example.com HIGH MEDIUM test_key: test_value 2024-04-01T18:24:37Z 2025-07-31T11:07:41Z

ip


Gets the comprehensive IP reputation and threat intelligence from Infoblox Threat Defense, including threat indicators, IPAM address information, and standard IP reputation data.

Base Command

ip

Input

Argument Name Description Required
ip IP(s) for which to retrieve reputation and threat intelligence. Supports comma-separated values. Required

Context Output

Path Type Description
InfobloxCloud.IP.ip String The requested IP address.
IP.Address String IP address.
IP.Relationships.EntityA String The source of the relationship.
IP.Relationships.EntityB String The destination of the relationship.
IP.Relationships.Relationship String The name of the relationship.
IP.Relationships.EntityAType String The type of the source of the relationship.
IP.Relationships.EntityBType String The type of the destination of the relationship.
IP.ASN String The autonomous system name for the IP address, for example: “AS8948”.
IP.Hostname String The hostname that is mapped to this IP address.
IP.Geo.Location String The geolocation where the IP address is located, in the format: latitude:longitude.
IP.Geo.Country String The country in which the IP address is located.
IP.Geo.Description String Additional information about the location.
IP.DetectionEngines Number The total number of engines that checked the indicator.
IP.PositiveDetections Number The number of engines that positively detected the indicator as malicious.
IP.Malicious.Vendor String The vendor reporting the IP address as malicious.
IP.Malicious.Description String A description explaining why the IP address was reported as malicious.
IP.Tags Unknown (List) Tags of the IP address.
IP.FeedRelatedIndicators.value String Indicators that are associated with the IP address.
IP.FeedRelatedIndicators.type String The type of the indicators that are associated with the IP address.
IP.FeedRelatedIndicators.description String The description of the indicators that are associated with the IP address.
IP.MalwareFamily String The malware family associated with the IP address.
IP.Organization.Name String The organization of the IP address.
IP.Organization.Type String The organization type of the IP address.
IP.ASOwner String The autonomous system owner of the IP address.
IP.Region String The region in which the IP address is located.
IP.Port String Ports that are associated with the IP address.
IP.Internal Boolean Whether the IP address is internal or external.
IP.UpdatedDate Date The date that the IP address was last updated.
IP.Registrar.Abuse.Name String The name of the contact for reporting abuse.
IP.Registrar.Abuse.Address String The address of the contact for reporting abuse.
IP.Registrar.Abuse.Country String The country of the contact for reporting abuse.
IP.Registrar.Abuse.Network String The network of the contact for reporting abuse.
IP.Registrar.Abuse.Phone String The phone number of the contact for reporting abuse.
IP.Registrar.Abuse.Email String The email address of the contact for reporting abuse.
IP.Campaign String The campaign associated with the IP address.
IP.TrafficLightProtocol String The Traffic Light Protocol (TLP) color that is suitable for the IP address.
IP.CommunityNotes.note String Notes on the IP address that were given by the community.
IP.CommunityNotes.timestamp Date The time in which the note was published.
IP.Publications.source String The source in which the article was published.
IP.Publications.title String The name of the article.
IP.Publications.link String A link to the original article.
IP.Publications.timestamp Date The time in which the article was published.
IP.ThreatTypes.threatcategory String The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc.
IP.ThreatTypes.threatcategoryconfidence String The confidence level provided by the vendor for the threat type category For example, a confidence of 90 for the threat type category ‘malware’ means that the vendor rates that this is 90% confidence of being a malware.
DBotScore.Indicator String The indicator that was tested.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
DBotScore.Score Number The actual score.
DBotScore.Reliability String Reliability of the source providing the intelligence data.
InfobloxCloud.IP.Threat.id String The unique identifier for the threat indicator.
InfobloxCloud.IP.Threat.type String The type of threat indicator.
InfobloxCloud.IP.Threat.ip String The IP address identified as a threat indicator.
InfobloxCloud.IP.Threat.profile String The threat profile or classification source.
InfobloxCloud.IP.Threat.property String The specific property or category of the threat.
InfobloxCloud.IP.Threat.class String The classification of the threat.
InfobloxCloud.IP.Threat.threat_level Number The numeric threat level score.
InfobloxCloud.IP.Threat.threat_label String The textual threat level label.
InfobloxCloud.IP.Threat.expiration Date The timestamp when the threat indicator will expire.
InfobloxCloud.IP.Threat.detected Date The timestamp when the threat activity was first detected.
InfobloxCloud.IP.Threat.received Date The timestamp when the threat indicator was received by the system.
InfobloxCloud.IP.Threat.imported Date The timestamp when the threat indicator was imported into the system.
InfobloxCloud.IP.Threat.up String The boolean status flag indicating whether the threat indicator is currently active.
InfobloxCloud.IP.Threat.batch_id String The batch ID of the threat indicator.
InfobloxCloud.IP.Threat.confidence Number The numeric confidence score representing the reliability of the threat indicator.
InfobloxCloud.IP.Threat.extended.notes String The additional notes or information about the threat indicator.
InfobloxCloud.IP.Threat.threat_score Number The numeric score representing the calculated threat severity.
InfobloxCloud.IP.Threat.threat_score_rating String The textual rating of the threat score.
InfobloxCloud.IP.Threat.threat_score_vector String The vector string representing threat scoring details.
InfobloxCloud.IP.Threat.risk_score Number The numeric risk score assigned to the threat indicator.
InfobloxCloud.IP.Threat.risk_score_rating String The textual rating of the risk score.
InfobloxCloud.IP.Threat.risk_score_vector String The vector string representing risk scoring details.
InfobloxCloud.IP.Threat.confidence_score Number The numeric confidence score for the threat assessment.
InfobloxCloud.IP.Threat.confidence_score_rating String The textual rating of the confidence score.
InfobloxCloud.IP.Threat.confidence_score_vector String The vector string representing confidence scoring details.
InfobloxCloud.IP.Threat.extended.cyberint_guid String The unique identifier for the threat indicator.
InfobloxCloud.IP.Threat.extended.attack_chain String The attack chain associated with the threat indicator.
InfobloxCloud.IP.Threat.extended.extended String The additional information or metadata associated with the threat indicator.
InfobloxCloud.IP.Threat.extended.protocol String The protocol associated with the threat indicator.
InfobloxCloud.IP.Threat.extended.references String The references associated with the threat indicator.
InfobloxCloud.IP.Threat.extended.threat_actor String The threat actor associated with the threat indicator.
InfobloxCloud.IP.Threat.extended.threat_actor_vector String The vector string representing threat actor details.
InfobloxCloud.IP.Threat.extended.risk_score String The numeric risk score assigned to the threat indicator.
InfobloxCloud.IP.Threat.extended.threat_score String The numeric threat score assigned to the threat indicator.
InfobloxCloud.IP.Threat.extended.sample_sha256 String The SHA-256 hash of the sample associated with the threat.
InfobloxCloud.IP.Threat.extended.original_profile String The original profile or classification source of the threat.
InfobloxCloud.IP.Address.address String The IP address assigned to the resource.
InfobloxCloud.IP.Address.comment String A user-provided comment or annotation for the address record.
InfobloxCloud.IP.Address.compartment_id String The compartment ID of the IP address.
InfobloxCloud.IP.Address.created_at Date The timestamp when the IP address was created.
InfobloxCloud.IP.Address.dhcp_info Unknown The DHCP information associated with the IP address.
InfobloxCloud.IP.Address.disable_dhcp Boolean A boolean flag indicating whether DHCP is disabled for the IP address.
InfobloxCloud.IP.Address.discovery_attrs Unknown The discovery attributes associated with the IP address.
InfobloxCloud.IP.Address.discovery_metadata Unknown The discovery metadata associated with the IP address.
InfobloxCloud.IP.Address.external_keys Unknown External keys associated with the IP address.
InfobloxCloud.IP.Address.host Unknown The host name of the IP address.
InfobloxCloud.IP.Address.hwaddr String The hardware address of the IP address.
InfobloxCloud.IP.Address.id String The unique identifier of the IP address.
InfobloxCloud.IP.Address.interface String The interface of the IP address.
InfobloxCloud.IP.Address.names Unknown The names associated with the IP address.
InfobloxCloud.IP.Address.parent String The parent of the IP address.
InfobloxCloud.IP.Address.protocol String The protocol of the IP address.
InfobloxCloud.IP.Address.range String The range of the IP address.
InfobloxCloud.IP.Address.space String The space of the IP address.
InfobloxCloud.IP.Address.state String The state of the IP address.
InfobloxCloud.IP.Address.tags Unknown The tags associated with the IP address.
InfobloxCloud.IP.Address.updated_at Date The timestamp when the IP address was last updated.
InfobloxCloud.IP.Address.usage String The usage of the IP address.
InfobloxCloud.IP.Address.names.name String The name of the IP address.
InfobloxCloud.IP.Address.names.type Unknown The type of the IP address.

Command example

!ip ip="0.0.0.1"

Context Example

{
    "DBotScore": {
        "Indicator": "0.0.0.1",
        "Reliability": "A - Completely reliable",
        "Score": 3,
        "Type": "ip",
        "Vendor": "InfobloxThreatDefensewithDDI"
    },
    "IP": {
        "Address": "0.0.0.1",
        "Description": "Malware Download associated with the APT group",
        "ThreatTypes": [
            {
                "threatcategory": "IP",
                "threatcategoryconfidence": "100"
            }
        ],
        "Hostname": "name",
        "DetectionEngines": 1,
        "Tags": [
            "cyberint_guid: simple_cyberint_guid",
            "notes: Malware Download associated with the APT group",
            "Protocol: ip4",
            "State: used",
            "temp: true"
        ],
        "MalwareFamily": "APT",
        "Malicious": {
            "Vendor": "InfobloxThreatDefensewithDDI",
            "Description": "Malware Download associated with the APT group"
        }
    },
    "InfobloxCloud": {
        "IP": {
            "ip": "0.0.0.1",
            "Threat": {
                "id": "00000000-0000-0000-0000-000000000000",
                "type": "IP",
                "ip": "0.0.0.1",
                "profile": "IID",
                "property": "APT_Malware",
                "class": "APT",
                "threat_level": 100,
                "expiration": "2042-11-01T09:29:18.721Z",
                "detected": "2025-07-29T09:29:18.721Z",
                "received": "2025-07-29T09:31:39.329Z",
                "imported": "2025-07-29T09:31:39.329Z",
                "up": "true",
                "confidence": 100,
                "batch_id": "00000000-0000-0000-0000-000000000000",
                "threat_score": 10,
                "threat_score_rating": "Critical",
                "threat_score_vector": "simple_threat_vector",
                "risk_score": 9.9,
                "risk_score_rating": "Critical",
                "risk_score_vector": "simple_risk_vector",
                "confidence_score": 0.1,
                "confidence_score_rating": "Unconfirmed",
                "confidence_score_vector": "simple_confidence_vector",
                "extended": {
                    "cyberint_guid": "simple_cyberint_guid",
                    "notes": "Malware Download associated with the APT group"
                }
            },
            "Address": {
                "address": "0.0.0.1",
                "comment": "comment",
                "compartment_id": "00000000-0000-0000-0000-000000000000",
                "created_at": "2025-06-27T13:07:21.476126Z",
                "disable_dhcp": false,
                "external_keys": {
                    "e3": "3e3"
                },
                "host": "ipam/host/00000000-0000-0000-0000-000000000000",
                "hwaddr": "00:00:00:00:00:00",
                "id": "ipam/address/00000000-0000-0000-0000-000000000000",
                "interface": "interface",
                "names": [
                    {
                        "name": "name",
                        "type": "user"
                    }
                ],
                "parent": "ipam/subnet/00000000-0000-0000-0000-000000000000",
                "protocol": "ip4",
                "range": "ipam/range/00000000-0000-0000-0000-000000000000",
                "space": "ipam/ip_space/00000000-0000-0000-0000-000000000000",
                "state": "used",
                "tags": {
                    "temp": "true"
                },
                "updated_at": "2025-06-27T13:07:21.429056Z",
                "usage": [
                    "IPAM RESERVED"
                ]
            }
        }
    }
}

Human Readable Output

Information for the given Bad IP: 0.0.0.1

Threat Intelligence Summary

Batch Id Class Confidence Confidence Score Confidence Score Rating Confidence Score Vector Detected Expiration Extended Id Imported IP Profile Property Received Risk Score Risk Score Rating Risk Score Vector Threat Level Threat Score Threat Score Rating Threat Score Vector Type Up
00000000-0000-0000-0000-000000000000 APT 100 0.1 Unconfirmed simple_confidence_vector 2025-07-29T09:29:18.721Z 2042-11-01T09:29:18.721Z cyberint_guid: simple_cyberint_guid
notes: Malware Download associated with the APT group
00000000-0000-0000-0000-000000000000 2025-07-29T09:31:39.329Z 0.0.0.1 IID APT_Malware 2025-07-29T09:31:39.329Z 9.9 Critical simple_risk_vector 100 10 Critical simple_threat_vector IP true

Address Information

Address Comment Compartment Id Created At Disable Dhcp External Keys Host Hwaddr Id Interface Names Parent Protocol Range Space State Tags Updated At Usage
0.0.0.1 comment 00000000-0000-0000-0000-000000000000 2025-06-27T13:07:21.476126Z False e3: 3e3 ipam/host/00000000-0000-0000-0000-000000000000 00:00:00:00:00:00 ipam/address/00000000-0000-0000-0000-000000000000 interface - name: name
type: user
ipam/subnet/00000000-0000-0000-0000-000000000000 ip4 ipam/range/00000000-0000-0000-0000-000000000000 ipam/ip_space/00000000-0000-0000-0000-000000000000 used temp: true 2025-06-27T13:07:21.429056Z values: IPAM RESERVED

domain


Gets the comprehensive domain/host reputation and threat intelligence from Infoblox Threat Defense, including threat indicators, IPAM address information and standard domain reputation data.

Base Command

domain

Input

Argument Name Description Required
domain Domain(s) or Hosts(s) for which to retrieve reputation and threat intelligence. Supports comma-separated values. Required

Context Output

Path Type Description
InfobloxCloud.Domain.domain String The requested domain.
Domain.Name String The domain name, for example: “google.com”.
Domain.Relationships.EntityA string The source of the relationship.
Domain.Relationships.EntityB string The destination of the relationship.
Domain.Relationships.Relationship string The name of the relationship.
Domain.Relationships.EntityAType string The type of the source of the relationship.
Domain.Relationships.EntityBType string The type of the destination of the relationship.
Domain.DNS String A list of IP objects resolved by DNS.
Domain.DetectionEngines Number The total number of engines that checked the indicator.
Domain.PositiveDetections Number The number of engines that positively detected the indicator as malicious.
Domain.CreationDate Date The date that the domain was created.
Domain.UpdatedDate String The date that the domain was last updated.
Domain.ExpirationDate Date The expiration date of the domain.
Domain.DomainStatus Datte The status of the domain.
Domain.NameServers Unknown (List<String>) Name servers of the domain.
Domain.Organization String The organization of the domain.
Domain.Subdomains Unknown (List<String>) Subdomains of the domain.
Domain.Admin.Country String The country of the domain administrator.
Domain.Admin.Email String The email address of the domain administrator.
Domain.Admin.Name String The name of the domain administrator.
Domain.Admin.Phone String The phone number of the domain administrator.
Domain.Registrant.Country String The country of the registrant.
Domain.Registrant.Email String The email address of the registrant.
Domain.Registrant.Name String The name of the registrant.
Domain.Registrant.Phone String The phone number for receiving abuse reports.
Domain.Tags Unknown (List) Tags of the domain.
Domain.FeedRelatedIndicators.value String Indicators that are associated with the domain.
Domain.FeedRelatedIndicators.type String The type of the indicators that are associated with the domain.
Domain.FeedRelatedIndicators.description String The description of the indicators that are associated with the domain.
Domain.MalwareFamily String The malware family associated with the domain.
Domain.WHOIS.DomainStatus String The status of the domain.
Domain.WHOIS.NameServers String (List<String>) Name servers of the domain.
Domain.WHOIS.CreationDate Date The date that the domain was created.
Domain.WHOIS.UpdatedDate Date The date that the domain was last updated.
Domain.WHOIS.ExpirationDate Date The expiration date of the domain.
Domain.WHOIS.Registrant.Name String The name of the registrant.
Domain.WHOIS.Registrant.Email String The email address of the registrant.
Domain.WHOIS.Registrant.Phone String The phone number of the registrant.
Domain.WHOIS.Registrar.Name String The name of the registrar.
Domain.WHOIS.Registrar.AbuseEmail String The email address of the contact for reporting abuse.
Domain.WHOIS.Registrar.AbusePhone String The phone number of contact for reporting abuse.
Domain.WHOIS.Admin.Name String The name of the domain administrator.
Domain.WHOIS.Admin.Email String The email address of the domain administrator.
Domain.WHOIS.Admin.Phone String The phone number of the domain administrator.
Domain.WHOIS/History String List of Whois objects.
Domain.Malicious.Vendor String The vendor reporting the domain as malicious.
Domain.Malicious.Description String A description explaining why the domain was reported as malicious.
Domain.DomainIDNName String The internationalized domain name (IDN) of the domain.
Domain.Port String Ports that are associated with the domain.
Domain.Internal Bool Whether or not the domain is internal or external.
Domain.Category String The category associated with the indicator.
Domain.Campaign String The campaign associated with the domain.
Domain.TrafficLightProtocol String The Traffic Light Protocol (TLP) color that is suitable for the domain.
Domain.ThreatTypes.threatcategory String The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc.
Domain.ThreatTypes.threatcategoryconfidence String Threat Category Confidence is the confidence level provided by the vendor for the threat type category For example a confidence of 90 for threat type category ‘malware’ means that the vendor rates that this is 90% confidence of being a malware.
Domain.Geo.Location String The geolocation where the domain address is located, in the format: latitude:longitude.
Domain.Geo.Country String The country in which the domain address is located.
Domain.Geo.Description String Additional information about the location.
Domain.Tech.Country String The country of the domain technical contact.
Domain.Tech.Name String The name of the domain technical contact.
Domain.Tech.Organization String The organization of the domain technical contact.
Domain.Tech.Email String The email address of the domain technical contact.
Domain.CommunityNotes.note String Notes on the domain that were given by the community.
Domain.CommunityNotes.timestamp Date The time in which the note was published.
Domain.Publications.source String The source in which the article was published.
Domain.Publications.title String The name of the article.
Domain.Publications.link String A link to the original article.
Domain.Publications.timestamp Date The time in which the article was published.
Domain.Billing String The billing address of the domain.
DBotScore.Indicator String The indicator that was tested.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
DBotScore.Score Number The actual score.
DBotScore.Reliability String Reliability of the source providing the intelligence data.
InfobloxCloud.Domain.Threat.id String The unique identifier for the threat indicator.
InfobloxCloud.Domain.Threat.type String The type of threat indicator.
InfobloxCloud.Domain.Threat.domain String The domain identified as a threat indicator.
InfobloxCloud.Domain.Threat.profile String The threat profile or classification source.
InfobloxCloud.Domain.Threat.property String The specific property or category of the threat.
InfobloxCloud.Domain.Threat.class String The classification of the threat.
InfobloxCloud.Domain.Threat.threat_level Number The numeric threat level score.
InfobloxCloud.Domain.Threat.threat_label String The textual threat level label.
InfobloxCloud.Domain.Threat.expiration Date The timestamp when the threat indicator will expire.
InfobloxCloud.Domain.Threat.detected Date The timestamp when the threat activity was first detected.
InfobloxCloud.Domain.Threat.received Date The timestamp when the threat indicator was received by the system.
InfobloxCloud.Domain.Threat.imported Date The timestamp when the threat indicator was imported into the system.
InfobloxCloud.Domain.Threat.up String The boolean status flag indicating whether the threat indicator is currently active.
InfobloxCloud.Domain.Threat.batch_id String The batch ID of the threat indicator.
InfobloxCloud.Domain.Threat.confidence Number The numeric confidence score representing the reliability of the threat indicator.
InfobloxCloud.Domain.Threat.extended.notes String The additional notes or information about the threat indicator.
InfobloxCloud.Domain.Threat.threat_score Number The numeric score representing the calculated threat severity.
InfobloxCloud.Domain.Threat.threat_score_rating String The textual rating of the threat score.
InfobloxCloud.Domain.Threat.threat_score_vector String The vector string representing threat scoring details.
InfobloxCloud.Domain.Threat.risk_score Number The numeric risk score assigned to the threat indicator.
InfobloxCloud.Domain.Threat.risk_score_rating String The textual rating of the risk score.
InfobloxCloud.Domain.Threat.risk_score_vector String The vector string representing risk scoring details.
InfobloxCloud.Domain.Threat.confidence_score Number The numeric confidence score for the threat assessment.
InfobloxCloud.Domain.Threat.confidence_score_rating String The textual rating of the confidence score.
InfobloxCloud.Domain.Threat.confidence_score_vector String The vector string representing confidence scoring details.
InfobloxCloud.Domain.Threat.extended.cyberint_guid String The unique identifier for the threat indicator.
InfobloxCloud.Domain.Threat.extended.attack_chain String The attack chain associated with the threat indicator.
InfobloxCloud.Domain.Threat.extended.extended String The additional information or metadata associated with the threat indicator.
InfobloxCloud.Domain.Threat.extended.protocol String The protocol associated with the threat indicator.
InfobloxCloud.Domain.Threat.extended.references String The references associated with the threat indicator.
InfobloxCloud.Domain.Threat.extended.threat_actor String The threat actor associated with the threat indicator.
InfobloxCloud.Domain.Threat.extended.threat_actor_vector String The vector string representing threat actor details.
InfobloxCloud.Domain.Threat.extended.risk_score String The numeric risk score assigned to the threat indicator.
InfobloxCloud.Domain.Threat.extended.threat_score String The numeric threat score assigned to the threat indicator.
InfobloxCloud.Domain.Threat.extended.sample_sha256 String The SHA-256 hash of the sample associated with the threat.
InfobloxCloud.Domain.Threat.extended.original_profile String The original profile or classification source of the threat.
InfobloxCloud.Domain.Threat.dga String The domain name generated by a DGA (Domain Generation Algorithm).
InfobloxCloud.Domain.Threat.host String The host name of the domain.
InfobloxCloud.Domain.Threat.tld String The top-level domain (TLD) of the threat.
InfobloxCloud.Domain.Address.addresses.address String The address of the IP address.
InfobloxCloud.Domain.Address.addresses.ref String The reference of the IP address.
InfobloxCloud.Domain.Address.addresses.space String The space of the IP address.
InfobloxCloud.Domain.Address.auto_generate_records Boolean A boolean flag indicating whether auto generate records is enabled for the IP address.
InfobloxCloud.Domain.Address.comment String The description for the IPAM host.
InfobloxCloud.Domain.Address.created_at Date Time when the object has been created.
InfobloxCloud.Domain.Address.host_names Unknown The name records to be generated for the host.
InfobloxCloud.Domain.Address.id String The resource identifier.
InfobloxCloud.Domain.Address.name String The name of the IPAM host.
InfobloxCloud.Domain.Address.host_names.alias Boolean A boolean flag indicating whether the name record is an alias.
InfobloxCloud.Domain.Address.host_names.name String The name of the host.
InfobloxCloud.Domain.Address.host_names.primary_name Boolean A boolean flag indicating whether the name record is the primary name.
InfobloxCloud.Domain.Address.host_names.zone String The zone of the host.
InfobloxCloud.Domain.Address.tags Unknown The tags associated with the IP address.
InfobloxCloud.Domain.Address.addresses Unknown The IP address assigned to the resource.

Command example

!domain domain=test.com

Context Example

{
    "DBotScore": {
        "Indicator": "test.com",
        "Reliability": "A - Completely reliable",
        "Score": 3,
        "Type": "domain",
        "Vendor": "InfobloxBloxOneThreatDefense"
    },
    "Domain": {
        "Description": "cyber actors, possibly associated with the APT group Agent Serpens, created a fake website mimicking a modeling agency to collect detailed visitor.",
        "DetectionEngines": 1,
        "Malicious": {
            "Description": "cyber actors, possibly associated with the APT group Agent Serpens, created a fake website mimicking a modeling agency to collect detailed visitor.",
            "Vendor": "InfobloxThreatDefensewithDDI"
        },
        "MalwareFamily": "Phishing",
        "Name": "test.com",
        "Relationships": [
            {
                "EntityA": "test.com",
                "EntityAType": "Domain",
                "EntityB": "0.0.0.1",
                "EntityBType": "IP",
                "Relationship": "resolves-to"
            }
        ],
        "Tags": [
            "cyberint_guid: simple_cyberint_guid",
            "notes: cyber actors, possibly associated with the APT group Agent Serpens, created a fake website mimicking a modeling agency to collect detailed visitor."
        ],
        "ThreatTypes": [
            {
                "threatcategory": "HOST",
                "threatcategoryconfidence": "100"
            }
        ]
    },
    "InfobloxCloud": {
        "Domain": {
            "Address": {
                "addresses": [
                    {
                        "address": "0.0.0.1",
                        "ref": "ipam/address/00000000-0000-0000-0000-000000000000",
                        "space": "ipam/ip_space/00000000-0000-0000-0000-000000000000"
                    }
                ],
                "auto_generate_records": true,
                "comment": "comment",
                "created_at": "2025-07-22T05:26:46.834693Z",
                "host_names": [
                    {
                        "alias": false,
                        "name": "test.com",
                        "primary_name": true,
                        "zone": "dns/auth_zone/8ce66502-8d4b-439e-8690-0c59d3122b9f"
                    }
                ],
                "id": "ipam/host/00000000-0000-0000-0000-000000000000",
                "name": "test.com",
                "updated_at": "2025-07-22T05:26:57.219235Z"
            },
            "domain": "test.com",
            "Threat": {
                "batch_id": "00000000-0000-0000-0000-000000000001",
                "class": "Phishing",
                "confidence": 100,
                "detected": "2025-05-08T16:39:38.959Z",
                "dga": "false",
                "domain": "test.com",
                "expiration": "2025-09-05T16:39:38.959Z",
                "extended": {
                    "cyberint_guid": "simple_cyberint_guid",
                    "notes": "cyber actors, possibly associated with the APT group Agent Serpens, created a fake website mimicking a modeling agency to collect detailed visitor."
                },
                "host": "test.com",
                "id": "00000000-0000-0000-0000-000000000001",
                "imported": "2025-05-08T16:41:37.894Z",
                "profile": "IID",
                "property": "Phishing_Lookalike",
                "received": "2025-05-08T16:41:37.894Z",
                "threat_level": 100,
                "tld": "com",
                "type": "HOST",
                "up": "true"
            }
        }
    }
}

Human Readable Output

Information for the given Bad Domain: test.com

Threat Intelligence Summary

Batch Id Class Confidence Detected Dga Domain Expiration Extended Host Id Imported Profile Property Received Threat Level Tld Type Up
00000000-0000-0000-0000-000000000001 Phishing 100 2025-05-08T16:39:38.959Z false test.com 2025-09-05T16:39:38.959Z cyberint_guid: simple_cyberint_guid
notes: cyber actors, possibly associated with the APT group Agent Serpens, created a fake website mimicking a modeling agency to collect detailed visitor.
test.com 00000000-0000-0000-0000-000000000001 2025-05-08T16:41:37.894Z IID Phishing_Lookalike 2025-05-08T16:41:37.894Z 100 com HOST true

Address Information

Addresses Auto Generate Records Comment Created At Host Names Id Name Updated At
- address: 0.0.0.1
ref: ipam/address/00000000-0000-0000-0000-000000000000
space: ipam/ip_space/00000000-0000-0000-0000-000000000000
True comment 2025-07-22T05:26:46.834693Z - alias: False
name: test.com
primary_name: True
zone: dns/auth_zone/8ce66502-8d4b-439e-8690-0c59d3122b9f
ipam/host/00000000-0000-0000-0000-000000000000 test.com 2025-07-22T05:26:57.219235Z

url


Gets the comprehensive URL reputation and threat intelligence from Infoblox Threat Defense, including threat indicators, and standard URL reputation data.

Base Command

url

Input

Argument Name Description Required
url URL(s) for which to retrieve reputation and threat intelligence. Supports comma-separated values. Required

Context Output

Path Type Description
InfobloxCloud.URL.url String The requested URL.
URL.Data String The URL.
URL.Relationships.EntityA string The source of the relationship.
URL.Relationships.EntityB string The destination of the relationship.
URL.Relationships.Relationship string The name of the relationship.
URL.Relationships.EntityAType string The type of the source of the relationship.
URL.Relationships.EntityBType string The type of the destination of the relationship.
URL.DetectionEngines String The total number of engines that checked the indicator.
URL.PositiveDetections String The number of engines that positively detected the indicator as malicious.
URL.Category String The category associated with the indicator.
URL.Malicious.Vendor String The vendor reporting the URL as malicious.
URL.Malicious.Description String A description of the malicious URL.
URL.Tags Unknown (List) Tags of the URL.
URL.FeedRelatedIndicators.value String Indicators that are associated with the URL.
URL.FeedRelatedIndicators.type String The type of the indicators that are associated with the URL.
URL.FeedRelatedIndicators.description String The description of the indicators that are associated with the URL.
URL.MalwareFamily String The malware family associated with the URL.
URL.Port String Ports that are associated with the URL.
URL.Internal Bool Whether or not the URL is internal or external.
URL.Campaign String The campaign associated with the URL.
URL.TrafficLightProtocol String The Traffic Light Protocol (TLP) color that is suitable for the URL.
URL.ThreatTypes.threatcategory String The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc.
URL.ThreatTypes.threatcategoryconfidence String Threat Category Confidence is the confidence level provided by the vendor for the threat type category For example a confidence of 90 for threat type category ‘malware’ means that the vendor rates that this is 90% confidence of being a malware.
URL.ASN String The autonomous system name for the URL, for example: ‘AS8948’.
URL.ASOwner String The autonomous system owner of the URL.
URL.GeoCountry String The country in which the URL is located.
URL.Organization String The organization of the URL.
URL.CommunityNotes.note String Notes on the URL that were given by the community.
URL.CommunityNotes.timestamp Date The time in which the note was published.
URL.Publications.source String The source in which the article was published.
URL.Publications.title String The name of the article.
URL.Publications.link String A link to the original article.
URL.Publications.timestamp Date The time in which the article was published.
DBotScore.Indicator String The indicator that was tested.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
DBotScore.Score Number The actual score.
DBotScore.Reliability String Reliability of the source providing the intelligence data.
InfobloxCloud.URL.Threat.id String The unique identifier for the threat indicator.
InfobloxCloud.URL.Threat.type String The type of threat indicator.
InfobloxCloud.URL.Threat.url String The URL identified as a threat indicator.
InfobloxCloud.URL.Threat.profile String The threat profile or classification source.
InfobloxCloud.URL.Threat.property String The specific property or category of the threat.
InfobloxCloud.URL.Threat.class String The classification of the threat.
InfobloxCloud.URL.Threat.threat_level Number The numeric threat level score.
InfobloxCloud.URL.Threat.threat_label String The textual threat level label.
InfobloxCloud.URL.Threat.expiration Date The timestamp when the threat indicator will expire.
InfobloxCloud.URL.Threat.detected Date The timestamp when the threat activity was first detected.
InfobloxCloud.URL.Threat.received Date The timestamp when the threat indicator was received by the system.
InfobloxCloud.URL.Threat.imported Date The timestamp when the threat indicator was imported into the system.
InfobloxCloud.URL.Threat.up String The boolean status flag indicating whether the threat indicator is currently active.
InfobloxCloud.URL.Threat.batch_id String The batch ID of the threat indicator.
InfobloxCloud.URL.Threat.confidence Number The numeric confidence score representing the reliability of the threat indicator.
InfobloxCloud.URL.Threat.extended.notes String The additional notes or information about the threat indicator.
InfobloxCloud.URL.Threat.threat_score Number The numeric score representing the calculated threat severity.
InfobloxCloud.URL.Threat.threat_score_rating String The textual rating of the threat score.
InfobloxCloud.URL.Threat.threat_score_vector String The vector string representing threat scoring details.
InfobloxCloud.URL.Threat.risk_score Number The numeric risk score assigned to the threat indicator.
InfobloxCloud.URL.Threat.risk_score_rating String The textual rating of the risk score.
InfobloxCloud.URL.Threat.risk_score_vector String The vector string representing risk scoring details.
InfobloxCloud.URL.Threat.confidence_score Number The numeric confidence score for the threat assessment.
InfobloxCloud.URL.Threat.confidence_score_rating String The textual rating of the confidence score.
InfobloxCloud.URL.Threat.confidence_score_vector String The vector string representing confidence scoring details.
InfobloxCloud.URL.Threat.extended.cyberint_guid String The unique identifier for the threat indicator.
InfobloxCloud.URL.Threat.extended.attack_chain String The attack chain associated with the threat indicator.
InfobloxCloud.URL.Threat.extended.extended String The additional information or metadata associated with the threat indicator.
InfobloxCloud.URL.Threat.extended.protocol String The protocol associated with the threat indicator.
InfobloxCloud.URL.Threat.extended.references String The references associated with the threat indicator.
InfobloxCloud.URL.Threat.extended.threat_actor String The threat actor associated with the threat indicator.
InfobloxCloud.URL.Threat.extended.threat_actor_vector String The vector string representing threat actor details.
InfobloxCloud.URL.Threat.extended.risk_score String The numeric risk score assigned to the threat indicator.
InfobloxCloud.URL.Threat.extended.threat_score String The numeric threat score assigned to the threat indicator.
InfobloxCloud.URL.Threat.extended.sample_sha256 String The SHA-256 hash of the sample associated with the threat.
InfobloxCloud.URL.Threat.extended.original_profile String The original profile or classification source of the threat.

Command example

!url url=https://test.com

Context Example

{
    "DBotScore": {
        "Indicator": "https://test.com",
        "Reliability": "A - Completely reliable",
        "Score": 3,
        "Type": "url",
        "Vendor": "InfobloxBloxOneThreatDefense"
    },
    "InfobloxCloud": {
        "URL": {
            "Threat": {
                "id": "00000000-0000-0000-0000-000000000001",
                "type": "URL",
                "host": "test.com",
                "url": "https://test.com",
                "domain": "test.com",
                "tld": "com",
                "profile": "IID",
                "property": "Scam_Generic",
                "class": "Scam",
                "threat_level": 100,
                "expiration": "2025-10-05T12:12:00.22Z",
                "detected": "2025-06-07T12:12:00.22Z",
                "received": "2025-06-07T12:16:32.337Z",
                "imported": "2025-06-07T12:16:32.337Z",
                "up": "true",
                "confidence": 100,
                "batch_id": "00000000-0000-0000-0000-000000000000",
                "extended": {
                    "cyberint_guid": "simple_cyberint_guid",
                    "notes": "Scam advertised. Lures victims to put their money into fake investments.",
                    "protocol": "https",
                    "references": "https://test.com"
                }
            },
            "url": "https://test.com"
        }
    },
    "URL": {
        "Data": "https://test.com",
        "Description": "Scam advertised. Lures victims to put their money into fake investments.",
        "DetectionEngines": 1,
        "Malicious": {
            "Description": "Scam advertised. Lures victims to put their money into fake investments.",
            "Vendor": "InfobloxThreatDefensewithDDI"
        },
        "MalwareFamily": "Scam",
        "Tags": [
            "cyberint_guid: simple_cyberint_guid",
            "notes: Scam advertised. Lures victims to put their money into fake investments.",
            "protocol: https",
            "references: https://test.com"
        ],
        "ThreatTypes": [
            {
                "threatcategory": "URL",
                "threatcategoryconfidence": "100"
            }
        ]
    }
}

Human Readable Output

Information for the given Bad URL: https://test.com

Threat Intelligence Summary

Batch Id Class Confidence Detected Domain Expiration Extended Host Id Imported Profile Property Received Threat Level Tld Type Up URL
00000000-0000-0000-0000-000000000000 Scam 100 2025-06-07T12:12:00.22Z test.com 2025-10-05T12:12:00.22Z cyberint_guid: simple_cyberint_guid
notes: Scam advertised. Lures victims to put their money into fake investments.
protocol: https
references: https://test.com
test.com 00000000-0000-0000-0000-000000000001 2025-06-07T12:16:32.337Z IID Scam_Generic 2025-06-07T12:16:32.337Z 100 com URL true https://test.com

infobloxcloud-mac-enrich


Enrich a MAC address with DHCP lease information.

Base Command

infobloxcloud-mac-enrich

Input

Argument Name Description Required
mac Specify the MAC Address to enrich. Required

Context Output

Path Type Description
InfobloxCloud.DHCPLease.address String The IP address assigned in the DHCP lease.
InfobloxCloud.DHCPLease.client_id String The identifier of the DHCP client.
InfobloxCloud.DHCPLease.ends String The timestamp indicating when the DHCP lease ends.
InfobloxCloud.DHCPLease.fingerprint String The DHCP client fingerprint, indicating device type or OS.
InfobloxCloud.DHCPLease.fingerprint_processed String The processed fingerprint result, if available.
InfobloxCloud.DHCPLease.ha_group Unknown The high-availability group associated with the lease, if any.
InfobloxCloud.DHCPLease.hardware String The hardware (MAC) address of the DHCP client.
InfobloxCloud.DHCPLease.host String The reference or identifier for the host associated with this lease.
InfobloxCloud.DHCPLease.hostname String The hostname provided by the DHCP client.
InfobloxCloud.DHCPLease.iaid Number The Identity Association Identifier (IAID) for the DHCP lease.
InfobloxCloud.DHCPLease.last_updated String The timestamp when the lease was last updated.
InfobloxCloud.DHCPLease.options String The encoded DHCP options provided with the lease.
InfobloxCloud.DHCPLease.preferred_lifetime String The preferred lifetime of the lease.
InfobloxCloud.DHCPLease.protocol String The protocol used for the lease.
InfobloxCloud.DHCPLease.space String The identifier for the IP space to which this lease belongs.
InfobloxCloud.DHCPLease.starts String The timestamp indicating when the DHCP lease started.
InfobloxCloud.DHCPLease.state String The current state of the lease.
InfobloxCloud.DHCPLease.type String The type of DHCP lease.

Command example

!infobloxcloud-mac-enrich mac="00:00:00:00:00:01"

Context Example

{
    "InfobloxCloud": {
        "DHCPLease": {
            "address": "0.0.0.1",
            "client_id": "01:00:00:00:00:00:01",
            "ends": "2025-07-01T19:25:24Z",
            "fingerprint": "VMware:Virtual Machine:Windows:",
            "fingerprint_processed": "processed",
            "hardware": "00:00:00:00:00:01",
            "host": "dhcp/host/123456",
            "hostname": "test-host01",
            "iaid": 0,
            "last_updated": "2025-07-01T18:25:24.792Z",
            "options": "{\"Options\":[{\"Code\":\"57\",\"Value\":\"test\"},{\"Code\":\"61\",\"Value\":\"sample\"},{\"Code\":\"53\",\"Value\":\"world\"},{\"Code\":\"55\",\"Value\":\"bar\"}]}",
            "preferred_lifetime": "2025-07-01T18:25:24Z",
            "protocol": "",
            "space": "ipam/ip_space/12345678-1234-1234-1234-123456789012",
            "starts": "2025-07-01T18:25:24Z",
            "state": "used",
            "type": "DHCPv4"
        }
    }
}

Human Readable Output

DHCP Lease Information for MAC: 00:00:00:00:00:01

Address Client Id Ends Fingerprint Fingerprint Processed Hardware Host Hostname Iaid Last Updated Options Preferred Lifetime Space Starts State Type
0.0.0.1 01:00:00:00:00:00:01 2025-07-01T19:25:24Z VMware:Virtual Machine:Windows: processed 00:00:00:00:00:01 dhcp/host/123456 test-host01 0 2025-07-01T18:25:24.792Z - Code: 57
Value: test
- Code: 61
Value: sample
- Code: 53
Value: world
- Code: 55
Value: bar
2025-07-01T18:25:24Z ipam/ip_space/12345678-1234-1234-1234-123456789012 2025-07-01T18:25:24Z used DHCPv4

infobloxcloud-soc-insight-list


List SOC Insights from Infoblox Cloud.

Base Command

infobloxcloud-soc-insight-list

Input

Argument Name Description Required
status Specify the status of SOC Insights to fetch. Possible values are: Active, Closed. Optional
threat_type Specify the threat type of SOC Insights to fetch. Possible values are: DGA, Undefined, Malicious, Open Resolver, Phishing, DNS Tunneling, MalwareDownload, Sinkhole, Zero Day DNS, Notional Data Exfiltration, MalwareC2DGA, MalwareC2, Restricted Country Communications, Suspicious, CompromisedHost, CompromisedDomain, Lookalike Threat, Sanctioned Feed Disabled, DNSTunnel. Optional
priority Specify the priority level of SOC Insights to fetch. Possible values are: INFO, MEDIUM, HIGH, CRITICAL. Optional

Context Output

Path Type Description
InfobloxCloud.SOCInsight.insightId String The ID of the SOC Insight.
InfobloxCloud.SOCInsight.priorityText String The priority level of the SOC Insight.
InfobloxCloud.SOCInsight.tClass String The threat class of the SOC Insight.
InfobloxCloud.SOCInsight.tFamily String The threat family of the SOC Insight.
InfobloxCloud.SOCInsight.startedAt String The start time of the SOC Insight.
InfobloxCloud.SOCInsight.status String The status of the SOC Insight.
InfobloxCloud.SOCInsight.persistentDate String Timestamp when the threat was first observed as persistent.
InfobloxCloud.SOCInsight.spreadingDate String Timestamp when the threat was first observed as spreading.
InfobloxCloud.SOCInsight.dateChanged String Timestamp when the SOC Insight was last updated.
InfobloxCloud.SOCInsight.changer String The user or process that last changed the SOC Insight status or data.
InfobloxCloud.SOCInsight.feedSource String The source feed or provider of the SOC Insight.
InfobloxCloud.SOCInsight.threatType String The threat type of the SOC Insight.
InfobloxCloud.SOCInsight.numEvents String The number of events associated with the SOC Insight.
InfobloxCloud.SOCInsight.eventsNotBlockedCount String The number of events not blocked by the SOC Insight.
InfobloxCloud.SOCInsight.mostRecentAt String The most recent time the SOC Insight was updated.

Command example


#### Context Example

```json
{
    "InfobloxCloud": {
        "SOCInsight": [
            {
                "changer": "abc@xyz.com",
                "dateChanged": "2025-05-21T00:54:49.407214Z",
                "eventsBlockedCount": "3",
                "feedSource": "Insight Detection Framework",
                "insightId": "00000000-0000-0000-0000-000000000000",
                "mostRecentAt": "2025-07-19T19:25:11.723397Z",
                "numEvents": "3",
                "persistentDate": "2025-04-14T07:00:00Z",
                "priorityText": "HIGH",
                "spreadingDate": "2025-05-10T19:00:00Z",
                "startedAt": "2025-04-14T07:00:00Z",
                "status": "Active",
                "tClass": "Suspicious",
                "tFamily": "EmergentDomain",
                "threatType": "Suspicious"
            },
            {
                "tClass": "TI-RESTRICTED",
                "tFamily": "OFAC",
                "insightId": "00000000-0000-0000-0000-000000000001",
                "feedSource": "Insight Detection Framework",
                "startedAt": "2025-04-12T18:00:00Z",
                "threatType": "Sanctioned Feed Disabled",
                "status": "Active",
                "persistentDate": "2025-04-12T15:00:00Z",
                "numEvents": "246",
                "mostRecentAt": "2025-08-07T23:59:19Z",
                "eventsNotBlockedCount": "246",
                "changer": "abc@xyz.com",
                "dateChanged": "2025-08-06T13:58:01.050800Z",
                "priorityText": "INFO"
            }
        ]
    }
}

Human Readable Output

SOC Insights

ID Priority Class Threat Type Status Threat Family Feed Source Most Recent At
00000000-0000-0000-0000-000000000000 HIGH Suspicious Suspicious Active EmergentDomain Insight Detection Framework 2025-07-19T19:25:11.723397Z
00000000-0000-0000-0000-000000000001 INFO TI-RESTRICTED Sanctioned Feed Disabled Active OFAC Insight Detection Framework 2025-08-07T23:59:19Z

infobloxcloud-soc-insight-event-list


List events for a specific SOC Insight.

Base Command

infobloxcloud-soc-insight-event-list

Input

Argument Name Description Required
soc_insight_id Specify the SOC Insight ID to fetch events for. Required
limit Specify the maximum number of events to fetch. Default is 50. Optional
start_time Specify the start time for the events.

Format: YYYY-MM-DDTHH:MM:SSZ, YYYY-MM-DD, N days, N hours.

Example: 2025-04-25T00:00:00Z, 2025-04-25, 2 days, 5 hours, 01 Mar 2025, 01 Feb 2025 04:45:33, 15 Jun.
Optional
end_time Specify the end time for the events.

Format: YYYY-MM-DDTHH:MM:SSZ, YYYY-MM-DD, N days, N hours.

Example: 2025-04-25T00:00:00Z, 2025-04-25, 2 days, 5 hours, 01 Mar 2025, 01 Feb 2025 04:45:33, 15 Jun.
Optional
threat_level Specify the threat level of the events. Possible values are: High, Medium, Low, Info. Optional
confidence_level Specify the confidence level of the events. Possible values are: High, Medium, Low, Info. Optional
query Specify the query to search for events. Optional
query_type Specify the query type to search for events. Possible values are: A, AAAA, ANY, TXT, RRSIG, CNAME, MX, NS, PTR, SOA, SRV. Optional
source Specify the source of the events. Optional
device_ip Specify the device IP of the events. Optional
indicator Specify the indicator of the events. Optional

Context Output

Path Type Description
InfobloxCloud.Event.confidenceLevel String The confidence level of the threat detection.
InfobloxCloud.Event.deviceCountry String The country where the device is located.
InfobloxCloud.Event.deviceName String The name or identifier of the device.
InfobloxCloud.Event.deviceRegion String The region where the device is located.
InfobloxCloud.Event.dnsView String The DNS view used for the query.
InfobloxCloud.Event.feed String The feed that identified the threat.
InfobloxCloud.Event.source String The source of the threat detection.
InfobloxCloud.Event.action String The action taken on the detected threat.
InfobloxCloud.Event.policy String The policy applied to the detection.
InfobloxCloud.Event.deviceIp String The IP address of the device.
InfobloxCloud.Event.query String The DNS query that triggered the detection.
InfobloxCloud.Event.queryType String The type of DNS query.
InfobloxCloud.Event.response String The DNS response for the query.
InfobloxCloud.Event.class String The classification of the threat.
InfobloxCloud.Event.threatFamily String The family of the threat.
InfobloxCloud.Event.threatIndicator String The indicator of the threat.
InfobloxCloud.Event.detected String The timestamp when the event was detected.
InfobloxCloud.Event.property String The property of the event.
InfobloxCloud.Event.user String The user associated with the detection.
InfobloxCloud.Event.threatLevel String The severity level of the event.

Command example

!infobloxcloud-soc-insight-event-list soc_insight_id="00000000-0000-0000-0000-000000000000"

Context Example

{
    "InfobloxCloud": {
        "Event": [
            {
                "action": "Allow - No Log",
                "class": "TI-CONFIGURATIONISSUE",
                "confidenceLevel": "High",
                "detected": "2025-08-11 23:42:04 +0000 UTC",
                "deviceIp": "0.0.0.0",
                "deviceName": "0.0.0.0",
                "policy": "DoH",
                "property": "example.com",
                "query": "example.com",
                "queryType": "A",
                "source": "unknown",
                "threatFamily": "OPENRESOLVER",
                "threatLevel": "Low",
                "user": "unknown"
            },
            {
                "action": "Block",
                "class": "Suspicious",
                "confidenceLevel": "High",
                "detected": "2025-07-16 07:37:29 +0000 UTC",
                "deviceIp": "0.0.0.1",
                "deviceName": "0.0.0.1",
                "policy": "Default Policy",
                "property": "EmergentDomain",
                "query": "example.org",
                "queryType": "RRSIG",
                "source": "Endpoint",
                "threatFamily": "EmergentDomain",
                "threatLevel": "High",
                "user": "unknown"
            }
        ]
    }
}

Human Readable Output

Events for the given SOC Insight: 00000000-0000-0000-0000-000000000000

Confidence Level Threat Level Threat Family Action Class Detected
High Low OPENRESOLVER Allow - No Log TI-CONFIGURATIONISSUE 2025-08-11 23:42:04 +0000 UTC
High High EmergentDomain Block Suspicious 2025-07-16 07:37:29 +0000 UTC

infobloxcloud-soc-insight-indicator-list


List indicators for a specific SOC Insight.

Base Command

infobloxcloud-soc-insight-indicator-list

Input

Argument Name Description Required
soc_insight_id Specify the SOC Insight ID to fetch indicators for. Required
limit Specify the maximum number of indicators to fetch. Default is 50. Optional
start_time Specify the start time for the indicators.

Format: YYYY-MM-DDTHH:MM:SSZ, YYYY-MM-DD, N days, N hours.

Example: 2025-04-25T00:00:00Z, 2025-04-25, 2 days, 5 hours, 01 Mar 2025, 01 Feb 2025 04:45:33, 15 Jun.
Optional
end_time Specify the end time for the indicators.

Format: YYYY-MM-DDTHH:MM:SSZ, YYYY-MM-DD, N days, N hours.

Example: 2025-04-25T00:00:00Z, 2025-04-25, 2 days, 5 hours, 01 Mar 2025, 01 Feb 2025 04:45:33, 15 Jun.
Optional
confidence Specify the confidence of the indicators. Possible values are: 1, 2, 3. Optional
indicator Specify the indicator of the indicators. Optional
action Specify the action of the indicators. Possible values are: Blocked, Not Blocked. Optional
actor Specify the actor of the indicators. Optional

Context Output

Path Type Description
InfobloxCloud.Indicator.action String The action taken for the indicator.
InfobloxCloud.Indicator.confidence String The confidence level of the indicator.
InfobloxCloud.Indicator.count Number The number of occurrences of the indicator.
InfobloxCloud.Indicator.feedName String The feed name that identified the indicator.
InfobloxCloud.Indicator.threatLevelMax String The maximum threat level associated with the indicator.
InfobloxCloud.Indicator.indicator String The value of the indicator.
InfobloxCloud.Indicator.timeMax Date The latest time the indicator was observed.
InfobloxCloud.Indicator.timeMin Date The earliest time the indicator was observed.

Command example

!infobloxcloud-soc-insight-indicator-list soc_insight_id="00000000-0000-0000-0000-000000000000"

Context Example

{
    "InfobloxCloud": {
        "Indicator": [
            {
                "action": "Not Blocked",
                "confidence": "3",
                "count": 189,
                "indicator": "example.org",
                "threatLevelMax": "1",
                "timeMax": "2025-08-11T23:00:00.000",
                "timeMin": "2025-07-13T15:00:00.000"
            },
            {
                "action": "Blocked",
                "confidence": "1",
                "count": 5,
                "indicator": "example.com",
                "threatLevelMax": "3",
                "timeMax": "2025-08-11T12:00:00.000",
                "timeMin": "2025-07-14T10:00:00.000"
            }
        ]
    }
}

Human Readable Output

Indicators for the given SOC Insight: 00000000-0000-0000-0000-000000000000

Action Confidence Max Threat Level Indicator Count Max Time Min Time
Not Blocked 3 1 example.org 189 2025-08-11T23:00:00.000 2025-07-13T15:00:00.000
Blocked 1 3 example.com 5 2025-08-11T12:00:00.000 2025-07-14T10:00:00.000

infobloxcloud-soc-insight-asset-list


List assets for a specific SOC Insight.

Base Command

infobloxcloud-soc-insight-asset-list

Input

Argument Name Description Required
soc_insight_id Specify the SOC Insight ID to fetch assets for. Required
limit Specify the maximum number of assets to fetch. Default is 50. Optional
start_time Specify the start time for the assets.

Format: YYYY-MM-DDTHH:MM:SSZ, YYYY-MM-DD, N days, N hours.

Example: 2025-04-25T00:00:00Z, 2025-04-25, 2 days, 5 hours, 01 Mar 2025, 01 Feb 2025 04:45:33, 15 Jun.
Optional
end_time Specify the end time for the assets.

Format: YYYY-MM-DDTHH:MM:SSZ, YYYY-MM-DD, N days, N hours.

Example: 2025-04-25T00:00:00Z, 2025-04-25, 2 days, 5 hours, 01 Mar 2025, 01 Feb 2025 04:45:33, 15 Jun.
Optional
qip Specify the IP address of the assets. Optional
cmac Specify the MAC address of the assets. Optional
os_version Specify the OS version of the assets. Optional
user Specify the user of the assets. Optional

Context Output

Path Type Description
InfobloxCloud.Asset.count Number The number of occurrences associated with the asset.
InfobloxCloud.Asset.qip String The IP address of the asset.
InfobloxCloud.Asset.location String The geographical location of the asset.
InfobloxCloud.Asset.threatLevelMax String The maximum threat level associated with the asset.
InfobloxCloud.Asset.threatIndicatorDistinctCount String The number of distinct threat indicators associated with the asset.
InfobloxCloud.Asset.timeMax Date The latest time the asset was observed.
InfobloxCloud.Asset.timeMin Date The earliest time the asset was observed.
InfobloxCloud.Asset.mostRecentAction String The most recent action taken for the asset.

Command example

!infobloxcloud-soc-insight-asset-list soc_insight_id="00000000-0000-0000-0000-000000000000"

Context Example

{
    "InfobloxCloud": {
        "Asset": [
            {
                "count": 5,
                "location": "Leidschendam,Netherlands",
                "mostRecentAction": "Not Blocked",
                "qip": "0.0.0.0",
                "threatIndicatorDistinctCount": "1",
                "threatLevelMax": "1",
                "timeMax": "2025-08-11T12:00:00.000",
                "timeMin": "2025-07-14T10:00:00.000"
            },
            {
                "count": 1,
                "location": "Minneapolis,United States",
                "mostRecentAction": "Not Blocked",
                "qip": "0.0.0.1",
                "threatIndicatorDistinctCount": "1",
                "threatLevelMax": "1",
                "timeMax": "2025-08-07T12:00:00.000",
                "timeMin": "2025-08-07T12:00:00.000"
            }
        ]
    }
}

Human Readable Output

Assets for the given SOC Insight: 00000000-0000-0000-0000-000000000000

Count QIP Max Threat Level Location Threat Indicator Distinct Count Time Max Time Min Most Recent Action
5 0.0.0.0 1 Leidschendam,Netherlands 1 2025-08-11T12:00:00.000 2025-07-14T10:00:00.000 Not Blocked
1 0.0.0.1 1 Minneapolis,United States 1 2025-08-07T12:00:00.000 2025-08-07T12:00:00.000 Not Blocked

infobloxcloud-soc-insight-comment-list


List comments for a specific SOC Insight.

Base Command

infobloxcloud-soc-insight-comment-list

Input

Argument Name Description Required
soc_insight_id Specify the SOC Insight ID to fetch comments for. Required
start_time Specify the start time for the comments.

Format: YYYY-MM-DDTHH:MM:SSZ, YYYY-MM-DD, N days, N hours.

Example: 2025-04-25T00:00:00Z, 2025-04-25, 2 days, 5 hours, 01 Mar 2025, 01 Feb 2025 04:45:33, 15 Jun.
Optional
end_time Specify the end time for the comments.

Format: YYYY-MM-DDTHH:MM:SSZ, YYYY-MM-DD, N days, N hours.

Example: 2025-04-25T00:00:00Z, 2025-04-25, 2 days, 5 hours, 01 Mar 2025, 01 Feb 2025 04:45:33, 15 Jun.
Optional
limit Specify the maximum number of comments to fetch. Default is 50. Optional

Context Output

Path Type Description
InfobloxCloud.Comment.commentsChanger String The user who created or changed the comment.
InfobloxCloud.Comment.dateChanged Date The timestamp when the comment was created or modified.
InfobloxCloud.Comment.status String The status associated with the comment.
InfobloxCloud.Comment.newComment String The comment text.

Command example

!infobloxcloud-soc-insight-comment-list soc_insight_id="00000000-0000-0000-0000-000000000000"

Context Example

{
    "InfobloxCloud": {
        "Comment": [
            {
                "commentsChanger": "abc.zyx.com",
                "dateChanged": "2025-08-02T08:39:43.675",
                "newComment": "\nAsset IP: 0.0.0.0\nScan ID: None\nReference ID: None\nQualys Scan Report URL: https://example.com/fo/report/report_view.php?&id=None\n",
                "status": "Active"
            },
            {
                "commentsChanger": "abc.zyx.com",
                "dateChanged": "2025-07-15T05:24:29.803",
                "newComment": "\nAsset IP: 0.0.0.0\nScan ID: None\nReference ID: None\nQualys Scan Report URL: https://example.com/fo/report/report_view.php?&id=None\n",
                "status": "Active"
            }
        ]
    }
}

Human Readable Output

Comments for the given SOC Insight: 00000000-0000-0000-0000-000000000000

Comment Changer Date Changed Status Comment
abc.zyx.com 2025-08-02T08:39:43.675 Active
Asset IP: 0.0.0.0
Scan ID: None
Reference ID: None
Qualys Scan Report URL: https://example.com/fo/report/report_view.php?&id=None
abc.zyx.com 2025-07-15T05:24:29.803 Active
Asset IP: 0.0.0.0
Scan ID: None
Reference ID: None
Qualys Scan Report URL: https://example.com/fo/report/report_view.php?&id=None

Configuration parameters

  • credentials — (required)
  • integrationReliability — Source Reliability
  • create_relationships — Create relationships
  • isFetch — Fetch incidents
  • incidentType — Incident type
  • ingestion_type — Ingestion Type
  • soc_insight_status — SOC Insight Status
  • soc_insight_threat_type — SOC Insight Threat Type
  • soc_insight_priority_level — SOC Insight Priority Level
  • dns_events_feed_name — DNS Security Event Feed Name
  • dns_events_network — DNS Security Event Network
  • dns_events_policy_action — DNS Security Event Policy Action
  • dns_events_policy_name — DNS Security Event Policy Name
  • dns_events_queried_name — DNS Security Event Queried Name
  • dns_events_threat_class — DNS Security Event Threat Class
  • dns_events_threat_family — DNS Security Event Threat Family
  • dns_events_threat_indicator — DNS Security Event Threat Indicator
  • dns_events_threat_level — DNS Security Event Threat Level
  • max_fetch — Max Fetch
  • first_fetch — First fetch timestamp
  • incidentFetchInterval — Incidents Fetch Interval
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (17)

  • bloxone-td-dossier-lookup-get

    The Dossier Lookup API returns detailed information on the specified indicator from the requested sources.

  • bloxone-td-dossier-source-list

    Get available Dossier sources.

  • bloxone-td-lookalike-domain-list

    Get lookalike domain lists.

  • domain

    Gets the comprehensive domain/host reputation and threat intelligence from Infoblox Threat Defense, including threat indicators, IPAM address information and standard domain reputation data.

  • infobloxcloud-block-domain

    The given domains will be added to the provided block list.

  • infobloxcloud-block-ip

    The given IP addresses will be added to the provided block list.

  • infobloxcloud-customlist-indicator-remove

    The given indicators will be removed from the provided custom list.

  • infobloxcloud-mac-enrich

    Enrich a MAC address with DHCP lease information.

  • infobloxcloud-soc-insight-asset-list

    List assets for a specific SOC Insight.

  • infobloxcloud-soc-insight-comment-list

    List comments for a specific SOC Insight.

  • infobloxcloud-soc-insight-event-list

    List events for a specific SOC Insight.

  • infobloxcloud-soc-insight-indicator-list

    List indicators for a specific SOC Insight.

  • infobloxcloud-soc-insight-list

    List SOC Insights from Infoblox Cloud.

  • infobloxcloud-unblock-domain

    The given domains will be added to the provided allow list.

  • infobloxcloud-unblock-ip

    The given IP addresses will be added to the provided allow list.

  • ip

    Gets the comprehensive IP reputation and threat intelligence from Infoblox Threat Defense, including threat indicators, IPAM address information, and standard IP reputation data.

  • url

    Gets the comprehensive URL reputation and threat intelligence from Infoblox Threat Defense, including threat indicators, and standard URL reputation data.

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401
from CommonServerUserPython import *

import ipaddress

SEVERITY_MAP = {"INFO": 1, "MEDIUM": 2, "HIGH": 3, "CRITICAL": 4}
THREAT_LEVELS = ["LOW", "MEDIUM", "HIGH"]
INCIDENT_SEVERITY_MAP = {"INFO": "Info", "MEDIUM": "Medium", "HIGH": "High", "CRITICAL": "Critical"}
INCIDENT_LINK = "https://csp.infoblox.com/#/insights-console/insight/{}/summary"
ERRORS = {
    "INVALID_MAX_FETCH": "Invalid Max Fetch: {}. Max Fetch must be a positive integer ranging from 1 to 200.",
}
MAC_PATTERN = re.compile(
    r"^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})|([0-9a-fA-F]{4}\.[0-9a-fA-F]{4}\.[0-9a-fA-F]{4})|([0-9A-Fa-f]{12})$"
)
VENDOR_NAME = "InfobloxThreatDefense"
BASE_URL = "https://csp.infoblox.com"
DEFAULT_FIRST_FETCH = "24 hours"
MARKDOWN_CHARS = r"\*_{}[]()#+-!"
BACKOFF_FACTOR = 7.5  # Consider its double.
TOTAL_RETRIES = 4
TOTAL_RETRIES_ON_ENRICHMENT = 0
DEFAULT_TIMEOUT = 60
TIMEOUT_ON_ENRICHMENT = 15
STATUS_CODE_TO_RETRY = (429, *(status_code for status_code in requests.status_codes._codes if status_code >= 500))  # type: ignore
VALID_CODES = [
    status_code
    for status_code in requests.status_codes._codes  # type: ignore
    if status_code  # type: ignore[attr-defined]
    >= 200
    and status_code < 300
]
OK_CODES = (400, 401, 403, 404, 521, *VALID_CODES)  # type: ignore

OUTPUT_PREFIX = {
    "IP": "InfobloxCloud.IP",
    "Domain": "InfobloxCloud.Domain",
    "URL": "InfobloxCloud.URL",
}

MESSAGES = {
    "INVALID_JSON_OBJECT": "Failed to parse json object from response: {}.",
    "STATUS_CODE": "Error in API call [{}] - {}",
    "INVALID_ARGUMENT_RESPONSE": "Invalid argument value while trying to get information from Infoblox Cloud: ",
    "INVALID_API_KEY": "Encountered error while trying to get information from Infoblox Cloud: "
    "Invalid Service API Key configured.",
    "NO_RECORD_FOUND": "No record found for given argument(s): Not Found.",
    "TEST_CONNECTIVITY_FAILED": "Test connectivity failed. Please provide valid input parameters.",
    "REQUIRED_ARGUMENT": "The '{}' is a required argument.",
    "NO_INFO_FOUND": "No {} information found for {}: {}.",
    "KEY_NOT_FOUND": "Key {} not found in response.",
    "INVALID_VALUE": "The value '{}' is invalid for '{}'.",
    "INVALID_IP_ADDRESS": "The following IP Addresses were found invalid: {}",
    "INVALID_DNS_EVENT_THREAT_LEVEL": "Invalid threat level configured for parameter 'DNS Event Threat Level' with option: {}",
}


class BloxOneTDClient(BaseClient):
    def __init__(self, api_key, verify=True, proxy=False):
        integration_reliability = demisto.params().get("integrationReliability")
        self.integration_reliability = integration_reliability
        self.last_response = None
        super().__init__(headers={"Authorization": f"Token {api_key}"}, base_url=BASE_URL, verify=verify, proxy=proxy)

    def http_request(self, method, url_suffix, params=None, json_data=None):
        """
        Get http response based on url and given parameters.

        :param method: Specify http methods
        :param url_suffix: url encoded url suffix
        :param params: None
        :param json_data: None
        :return: http response on json
        """
        demisto.debug(f"Requesting Infoblox Cloud with method: {method}, url_suffix: {url_suffix} and params: {params}")
        # For reputation commands which run during an enrichment we limit the timeout and the retries
        retries = TOTAL_RETRIES_ON_ENRICHMENT if is_time_sensitive() else TOTAL_RETRIES
        timeout = TIMEOUT_ON_ENRICHMENT if is_time_sensitive() else DEFAULT_TIMEOUT

        resp = self._http_request(
            method=method,
            url_suffix=url_suffix,
            params=params,
            json_data=json_data,
            retries=retries,
            status_list_to_retry=STATUS_CODE_TO_RETRY,
            backoff_factor=BACKOFF_FACTOR,
            raise_on_redirect=False,
            raise_on_status=False,
            resp_type="response",
            ok_codes=OK_CODES,
            timeout=timeout,
        )  # type: ignore

        status_code = resp.status_code

        self.last_response = resp

        if status_code == 204:
            return None

        if status_code == 401:
            raise DemistoException(MESSAGES["STATUS_CODE"].format(status_code, MESSAGES["INVALID_API_KEY"]))

        try:
            resp_json = resp.json()
        except ValueError as exception:
            raise DemistoException(
                MESSAGES["STATUS_CODE"].format(status_code, MESSAGES["INVALID_JSON_OBJECT"].format(resp.text)), exception
            ) from exception

        if status_code not in VALID_CODES:
            if status_code == 400:
                raise DemistoException(
                    MESSAGES["STATUS_CODE"].format(
                        status_code,
                        MESSAGES["INVALID_ARGUMENT_RESPONSE"]
                        + str(resp_json.get("detail", resp_json.get("message", json.dumps(resp_json)))),
                    )
                )
            if status_code == 404:
                raise DemistoException(MESSAGES["STATUS_CODE"].format(status_code, MESSAGES["NO_RECORD_FOUND"]))
            if status_code in (521, 403):
                raise DemistoException(MESSAGES["STATUS_CODE"].format(status_code, MESSAGES["TEST_CONNECTIVITY_FAILED"]))
            self.client_error_handler(resp)

        return resp_json

    def dossier_source_list(self) -> list[str]:
        url_suffix = "/tide/api/services/intel/lookup/sources"
        res = self.http_request("GET", url_suffix=url_suffix)
        return [source for source, enabled in res.items() if enabled]

    def lookalike_domain_list(
        self,
        user_filter: Optional[str] = None,
        target_domain: Optional[str] = None,
        detected_at: Optional[str] = None,
        limit: int = 50,
        offset: Optional[int] = None,
    ) -> List[Dict]:
        url_suffix = "/api/tdlad/v1/lookalike_domains"
        filter_params: Dict[str, Any] = {key: val for key, val in [("_limit", limit), ("_offset", offset)] if val}

        # there is no reference in the docs but it seems that one of the following is correct
        # - the filters combination is OR
        # - we can't filter by more than filter
        # as a result we decided to allow just one filter at a time
        if user_filter:
            _filter = user_filter
        elif target_domain:
            _filter = f'target_domain=="{target_domain}"'
        else:  # detected_at != None
            _filter = f'detected_at>="{detected_at}"'

        filter_params["_filter"] = _filter

        return self.http_request("GET", url_suffix=url_suffix, params=filter_params)["results"]

    def dossier_lookup_get_create(self, indicator_type: str, value: str, sources: Optional[List[str]] = None) -> str:
        url_suffix = f"/tide/api/services/intel/lookup/indicator/{indicator_type}"
        params: Dict[str, Any] = {"value": value}
        if sources:
            params["source"] = sources

        data = self.http_request("GET", url_suffix=url_suffix, params=params)
        return data["job_id"]

    def dossier_lookup_get_is_done(self, job_id: str) -> bool:
        url_suffix = f"/tide/api/services/intel/lookup/jobs/{job_id}/pending"
        data = self.http_request("GET", url_suffix=url_suffix)
        if data["state"] == "completed":
            if data["status"] == "success":
                return True
            raise DemistoException(f"job {job_id} is completed with status: {data['status']}\ndetails: {data}")
        return False

    def dossier_lookup_get_results(self, job_id: str) -> Dict:
        url_suffix = f"/tide/api/services/intel/lookup/jobs/{job_id}/results"
        return self.http_request("GET", url_suffix=url_suffix)

    def soc_insights_list(self, params: dict) -> list[dict]:
        """
        :param params: Dictionary of parameters.
        :return: List of SOC insights.
        """
        url_suffix = "api/v1/insights"
        return self.http_request("GET", url_suffix=url_suffix, params=params)

    def soc_insight_indicators_list(self, params: dict, soc_insight_id: str) -> list[dict]:
        """
        :param params: Dictionary of parameters.
        :return: List of SOC insight indicators.
        """
        url_suffix = f"api/v1/insights/{soc_insight_id}/indicators"
        return self.http_request("GET", url_suffix=url_suffix, params=params)

    def soc_insight_events_list(self, params: dict, soc_insight_id: str) -> list[dict]:
        """
        :param params: Dictionary of parameters.
        :return: List of SOC insight events.
        """
        url_suffix = f"api/v1/insights/{soc_insight_id}/events"
        return self.http_request("GET", url_suffix=url_suffix, params=params)

    def soc_insight_assets_list(self, params: dict, soc_insight_id: str) -> list[dict]:
        """
        :param params: Dictionary of parameters.
        :return: List of SOC insight assets.
        """
        url_suffix = f"api/v1/insights/{soc_insight_id}/assets"
        return self.http_request("GET", url_suffix=url_suffix, params=params)

    def soc_insight_comments_list(self, params: dict, soc_insight_id: str) -> list[dict]:
        """
        :param params: Dictionary of parameters.
        :return: List of SOC insight comments.
        """
        url_suffix = f"api/v1/insights/{soc_insight_id}/comments"
        return self.http_request("GET", url_suffix=url_suffix, params=params)

    def get_named_list(self, params: Dict):
        """
        :param params: Dictionary of parameters.
        :return: Named list.
        """
        url_suffix = "/api/atcfw/v1/named_lists/0"
        response = self.http_request("GET", url_suffix=url_suffix, params=params)
        return response

    def remove_named_list_items(self, named_list_id: str, data: Dict):
        """
        :param named_list_id: ID of the named list.
        :param data: Dictionary of data to remove from the named list.
        """
        url_suffix = f"/api/atcfw/v1/named_lists/{named_list_id}/items"
        self.http_request("DELETE", url_suffix=url_suffix, json_data=data)

    def update_named_list(self, named_list_id: str, data: Dict):
        """
        :param named_list_id: ID of the named list.
        :param data: Dictionary of data to update the named list.
        :return: Updated named list.
        """
        url_suffix = f"/api/atcfw/v1/named_lists/{named_list_id}/items"
        response = self.http_request("POST", url_suffix=url_suffix, json_data=data)
        return response

    def get_indicator_threat_info(self, indicator_value: str, indicator_type: str) -> dict[str, Any]:
        """Gets the indicator threat information using the '/tide/api/data/threats' API endpoint.

        :type indicator_value: ``str``
        :param indicator_value: Indicator value to get the reputation for.

        :type indicator_type: ``str``
        :param indicator_type: Indicator type to get the reputation for.

        :return: dict containing the indicator threat information as returned from the API.
        :rtype: ``Dict[str, Any]``
        """
        params = {"type": indicator_type, indicator_type: indicator_value, "rlimit": 1}
        if indicator_type == "ip" and is_ipv6_valid(indicator_value):
            params["include_ipv6"] = "true"
        return self.http_request(method="GET", url_suffix="/tide/api/data/threats", params=params)

    def get_ip_address_info(self, ip: str) -> dict[str, Any]:
        """Gets IP address information from the address management API.

        :type ip: ``str``
        :param ip: IP address to get information for.

        :return: dict containing the IP address information.
        :rtype: ``Dict[str, Any]``
        """
        return self.http_request(
            method="GET", url_suffix="/api/ddi/v1/ipam/address", params={"_filter": f"address=='{ip}'", "_limit": 1}
        )

    def get_domain_address_info(self, domain: str) -> dict[str, Any]:
        """Gets domain address information from the address management API.

        :type domain: ``str``
        :param domain: Domain to get information for.

        :return: dict containing the domain address information.
        :rtype: ``Dict[str, Any]``
        """
        return self.http_request(
            method="GET", url_suffix="/api/ddi/v1/ipam/host", params={"_filter": f"name=='{domain}'", "_limit": 1}
        )

    def get_indicator_threat_info_text_search(self, indicator_value: str, indicator_type: str) -> dict[str, Any]:
        """Gets the indicator threat information using the '/tide/api/data/threats' API endpoint.

        :type indicator_value: ``str``
        :param indicator_value: Indicator value to get the reputation for.

        :type indicator_type: ``str``
        :param indicator_type: Indicator type to get the reputation for.

        :return: dict containing the indicator threat information as returned from the API.
        :rtype: ``Dict[str, Any]``
        """
        return self.http_request(
            method="GET",
            url_suffix="/tide/api/data/threats",
            params={"type": indicator_type, "text_search": indicator_value, "rlimit": 1},
        )

    def mac_enrich(self, mac: str) -> Dict[str, Any]:
        """Gets DHCP lease information for a specific MAC address.

        :type mac: ``str``
        :param mac: MAC address to lookup.

        :return: dict containing the DHCP lease information as returned from the API
        :rtype: ``Dict[str, Any]``
        """
        return self.http_request(
            method="GET", url_suffix="/api/ddi/v1/dhcp/lease", params={"_filter": f"hardware=='{mac}'", "_limit": 1}
        )

    def list_dns_security_events(self, params: dict) -> list[dict]:
        """
        List DNS security events from Infoblox Cloud.

        :param params: Dictionary of parameters for filtering DNS security events.
        :return: List of DNS security events.
        """
        url_suffix = "/api/dnsdata/v2/dns_event"
        return self.http_request("GET", url_suffix=url_suffix, params=params)


def check_empty(x: Any) -> bool:
    """
    Check if input is empty (None, empty dict, empty list, or empty string).

    :param x: Input to check.
    :type x: Any
    :return: True if x is empty, False otherwise.
    :rtype: bool
    """
    return x is None or x == {} or x == [] or x == ""


def string_escape_markdown(data: Any):
    """
    Escape any chars that might break a markdown string.
    :param data: The data to be modified (required).
    :return: A modified data.
    """
    if isinstance(data, str):
        data = "".join(["\\" + str(c) if c in MARKDOWN_CHARS else str(c) for c in data])
    elif isinstance(data, list):
        new_data = []
        for sub_data in data:
            if isinstance(sub_data, str):
                sub_data = "".join(["\\" + str(c) if c in MARKDOWN_CHARS else str(c) for c in sub_data])
            new_data.append(sub_data)
        data = new_data
    return data


def trim_args(args: Dict[str, Any]):
    """
    Trim the arguments for extra spaces.

    :type args: Dict
    :param args: it contains arguments of the command
    """
    for key, value in args.items():
        if isinstance(value, str):
            args[key] = value.strip()

    return args


def validate_argument(value: Any, name: str) -> str:
    """
    Check if empty value is passed as value for argument and raise appropriate ValueError.

    :type value: Any
    :param value: value of the argument.

    :type name: str
    :param name: name of the argument.
    """
    if not value:
        raise ValueError(MESSAGES["REQUIRED_ARGUMENT"].format(name))
    return value


def validate_key(response: dict, name: str):
    """
    Check if the given key exists in the response and raise appropriate ValueError.

    :type response: dict
    :param response: response of the command.

    :type name: str
    :param name: name of the key.
    """
    if not response or not response.get(name):
        raise ValueError(MESSAGES["KEY_NOT_FOUND"].format(name))
    return response.get(name)


def remove_empty_elements_for_hr(d: Any) -> Any:
    """
    Recursively remove empty lists, empty dicts, or None elements from a dictionary or list.
    :param d: Input dictionary or list.
    :return: Dictionary or list with all empty lists, and empty dictionaries removed.
    """
    if not isinstance(d, dict | list):
        return str(d) if isinstance(d, int | float) else d
    elif isinstance(d, list):
        return [v for v in (remove_empty_elements_for_hr(v) for v in d) if not check_empty(v)]
    return {k: v for k, v in ((k, remove_empty_elements_for_hr(v)) for k, v in d.items()) if not check_empty(v)}


def header_transformer_for_ip(header: str) -> str:
    """
    To transform the header for the markdown table.

    :type header: ``str``
    :param header: Header name.

    :return: The title cased header.
    :rtype: ``str``
    """
    return header.replace("_", " ").title().replace("Ip", "IP")


def header_transformer_for_url(header: str) -> str:
    """
    To transform the header for the markdown table.

    :type header: ``str``
    :param header: Header name.

    :return: The title cased header.
    :rtype: ``str``
    """
    return header.replace("_", " ").title().replace("Url", "URL")


def validate_ip_addresses(ips_list: list[str]) -> tuple[list[str], list[str]]:
    """
    Given a list of IP addresses, returns the invalid and valid ips.

    :type ips_list: ``List[str]``
    :param ips_list: List of ip addresses.

    :return: invalid_ip_addresses and valid_ip_addresses.
    :rtype: ``Tuple[List[str], List[str]]``
    """
    invalid_ip_addresses = []
    valid_ip_addresses = []
    for ip in ips_list:
        ip = ip.strip().strip('"')
        if ip:
            if is_ip_valid(ip, accept_v6_ips=True):
                valid_ip_addresses.append(ip)
            else:
                invalid_ip_addresses.append(ip)
    return invalid_ip_addresses, valid_ip_addresses


def get_dbot_score_from_threat_level(threat_level: int) -> int:
    """
    Return DBot score based on threat level.

    :param threat_level: Threat level score from 0 to 100.
    :type threat_level: ``int``

    :return: DBot score value.
    :rtype: ``int``
    """
    if threat_level is None:
        return Common.DBotScore.NONE

    if threat_level >= 80:
        return Common.DBotScore.BAD
    if threat_level >= 30:
        return Common.DBotScore.SUSPICIOUS
    if threat_level > 0:
        return Common.DBotScore.GOOD

    return Common.DBotScore.NONE


def prepare_hr_for_ip(
    ip: str, threat_data: dict[str, Any], address_data: dict[str, Any], dbot_score_obj: Common.DBotScore
) -> str:
    """
    Prepare Human Readable output for IP command.

    Args:
        ip: IP address being queried.
        threat_data: Threat intelligence data from API.
        address_data: Address information data from API.
        dbot_score: DBot score for the IP.

    Returns:
        Human readable markdown output.
    """
    # Main header
    readable_output = f"## Information for the given {dbot_score_obj.to_readable()} IP: {ip}\n\n"

    # Threat Intelligence Section
    if threat_data:
        # Clean threat data for display
        clean_threat_data = remove_empty_elements_for_hr(threat_data)

        readable_output += (
            tableToMarkdown(
                "Threat Intelligence Summary",
                clean_threat_data,
                headerTransform=header_transformer_for_ip,
                removeNull=True,
                is_auto_json_transform=True,
            )
            + "\n"
        )
    # Address Information Section
    if address_data:
        # Clean address data for display
        clean_address_data = remove_empty_elements_for_hr(address_data)

        readable_output += tableToMarkdown(
            "Address Information",
            clean_address_data,
            headerTransform=header_transformer_for_ip,
            removeNull=True,
            is_auto_json_transform=True,
        )

    return readable_output


def prepare_hr_for_named_list(json_data: Dict[str, Any], table_name: str = "Named List Details") -> str:
    """
    Prepare human-readable for ip block, ip unblock, domain block, domain unblock command.

    :type json_data: Dict[str, Any]
    :param json_data: Response of the command

    :type table_name: str
    :param table_name: Name of the table to display

    :rtype: str
    :return: Human readable string for the command
    """
    tags = json_data.get("tags")
    if tags:
        tags = [f"{k}: {v}" for k, v in tags.items()]
        tags = string_escape_markdown(tags)
    hr_output = {
        "ID": json_data.get("id"),
        "Name": json_data.get("name"),
        "Type": json_data.get("type"),
        "Description": json_data.get("description"),
        "Items": string_escape_markdown(json_data.get("items")),
        "Confidence Level": json_data.get("confidence_level"),
        "Threat Level": json_data.get("threat_level"),
        "Tags": tags,
        "Created Time": json_data.get("created_time"),
        "Updated Time": json_data.get("updated_time"),
    }

    headers = [
        "ID",
        "Name",
        "Type",
        "Description",
        "Items",
        "Confidence Level",
        "Threat Level",
        "Tags",
        "Created Time",
        "Updated Time",
    ]

    return tableToMarkdown(table_name, hr_output, headers=headers, removeNull=True)


def prepare_hr_for_soc_insights(insights: list[dict[str, Any]]) -> str:
    """
    Prepare human-readable for SOC insights command.

    :type insights: list[dict[str, Any]]
    :param insights: List of insights.

    :rtype: str
    :return: Human readable string for the command.
    """
    table_name = "SOC Insights"
    hr_output = []
    for insight in insights:
        hr_output.append(
            {
                "ID": insight.get("insightId"),
                "Priority": insight.get("priorityText"),
                "Class": insight.get("tClass"),
                "Threat Type": insight.get("threatType"),
                "Status": insight.get("status"),
                "Threat Family": insight.get("tFamily"),
                "Feed Source": insight.get("feedSource"),
                "Most Recent At": insight.get("mostRecentAt"),
            }
        )
    headers = [
        "ID",
        "Priority",
        "Class",
        "Threat Type",
        "Status",
        "Threat Family",
        "Feed Source",
        "Most Recent At",
    ]
    return tableToMarkdown(table_name, hr_output, headers=headers, removeNull=True)


def prepare_hr_for_soc_insight_indicators(indicators: list[dict[str, Any]], soc_insight_id: str) -> str:
    """
    Prepare human-readable for SOC insight indicators command.

    :type indicators: list[dict[str, Any]]
    :param indicators: List of indicators.

    :type soc_insight_id: str
    :param soc_insight_id: ID of the insight.

    :rtype: str
    :return: Human readable string for the command.
    """
    table_name = f"Indicators for the given SOC Insight: {soc_insight_id}"
    hr_output = []
    for indicator in indicators:
        hr_output.append(
            {
                "Action": indicator.get("action"),
                "Confidence": indicator.get("confidence"),
                "Max Threat Level": indicator.get("threatLevelMax"),
                "Indicator": indicator.get("indicator"),
                "Count": indicator.get("count"),
                "Max Time": indicator.get("timeMax"),
                "Min Time": indicator.get("timeMin"),
            }
        )
    headers = [
        "Action",
        "Confidence",
        "Max Threat Level",
        "Indicator",
        "Count",
        "Max Time",
        "Min Time",
    ]
    return tableToMarkdown(table_name, hr_output, headers=headers, removeNull=True)


def prepare_hr_for_soc_insight_events(events: list[dict[str, Any]], soc_insight_id: str) -> str:
    """
    Prepare human-readable for SOC insight events command.

    :type events: list[dict[str, Any]]
    :param events: List of events.

    :type soc_insight_id: str
    :param soc_insight_id: ID of the SOC insight.

    :rtype: str
    :return: Human readable string for the command.
    """
    table_name = f"Events for the given SOC Insight: {soc_insight_id}"
    hr_output = []
    for event in events:
        hr_output.append(
            {
                "Confidence Level": event.get("confidenceLevel"),
                "Threat Level": event.get("threatLevel"),
                "Threat Family": event.get("threatFamily"),
                "Action": event.get("action"),
                "Class": event.get("class"),
                "Detected": event.get("detected"),
            }
        )
    headers = [
        "Confidence Level",
        "Threat Level",
        "Threat Family",
        "Action",
        "Class",
        "Detected",
    ]
    return tableToMarkdown(table_name, hr_output, headers=headers, removeNull=True)


def prepare_hr_for_soc_insight_assets(assets: list[dict[str, Any]], soc_insight_id: str) -> str:
    """
    Prepare human-readable for SOC insight assets command.

    :type assets: list[dict[str, Any]]
    :param assets: List of assets.

    :type soc_insight_id: str
    :param soc_insight_id: ID of the insight.

    :rtype: str
    :return: Human readable string for the command.
    """
    table_name = f"Assets for the given SOC Insight: {soc_insight_id}"
    hr_output = []
    for asset in assets:
        hr_output.append(
            {
                "Count": asset.get("count"),
                "QIP": asset.get("qip"),
                "Max Threat Level": asset.get("threatLevelMax"),
                "Location": asset.get("location"),
                "Threat Indicator Distinct Count": asset.get("threatIndicatorDistinctCount"),
                "Time Max": asset.get("timeMax"),
                "Time Min": asset.get("timeMin"),
                "Most Recent Action": asset.get("mostRecentAction"),
            }
        )
    headers = [
        "Count",
        "QIP",
        "Max Threat Level",
        "Location",
        "Threat Indicator Distinct Count",
        "Time Max",
        "Time Min",
        "Most Recent Action",
    ]
    return tableToMarkdown(table_name, hr_output, headers=headers, removeNull=True)


def prepare_hr_for_soc_insight_comments(comments: list[dict[str, Any]], soc_insight_id: str) -> str:
    """
    Prepare human-readable for SOC insight comments command.

    :type comments: list[dict[str, Any]]
    :param comments: List of comments.

    :type soc_insight_id: str
    :param soc_insight_id: ID of the insight.

    :rtype: str
    :return: Human readable string for the command.
    """
    table_name = f"Comments for the given SOC Insight: {soc_insight_id}"
    hr_output = []
    for comment in comments:
        hr_output.append(
            {
                "Comment Changer": comment.get("commentsChanger"),
                "Date Changed": comment.get("dateChanged"),
                "Status": comment.get("status"),
                "Comment": string_escape_markdown(comment.get("newComment")),
            }
        )
    headers = [
        "Comment Changer",
        "Date Changed",
        "Status",
        "Comment",
    ]
    return tableToMarkdown(table_name, hr_output, headers=headers, removeNull=True)


def prepare_hr_for_domain(
    domain: str, threat_data: dict[str, Any], address_data: dict[str, Any], dbot_score_obj: Common.DBotScore
) -> str:
    """
    Prepare Human Readable output for Domain command.

    :param domain: Domain being queried.
    :type domain: ``str``

    :param threat_data: Threat intelligence data from API.
    :type threat_data: ``Dict[str, Any]``

    :param address_data: Address information data from API.
    :type address_data: ``Dict[str, Any]``

    :param dbot_score: DBot score for the URL.
    :type dbot_score: ``Common.DBotScore``

    :return: Human readable markdown output.
    :rtype: ``str``
    """
    # Main header
    readable_output = f"## Information for the given {dbot_score_obj.to_readable()} Domain: {domain}\n\n"

    # Threat Intelligence Section
    if threat_data:
        # Clean threat data for display
        clean_threat_data = remove_empty_elements_for_hr(threat_data)

        readable_output += (
            tableToMarkdown(
                "Threat Intelligence Summary",
                clean_threat_data,
                headerTransform=string_to_table_header,
                removeNull=True,
                is_auto_json_transform=True,
            )
            + "\n"
        )

    # Address Information Section
    if address_data:
        # Clean address data for display
        clean_address_data = remove_empty_elements_for_hr(address_data)

        readable_output += tableToMarkdown(
            "Address Information",
            clean_address_data,
            headerTransform=string_to_table_header,
            removeNull=True,
            is_auto_json_transform=True,
        )
    return readable_output


def prepare_hr_for_url(url: str, threat_data: Dict[str, Any], dbot_score_obj: Common.DBotScore) -> str:
    """
    Prepare Human Readable output for URL command.

    :param url: URL being queried.
    :type url: ``str``

    :param threat_data: Threat intelligence data from API.
    :type threat_data: ``Dict[str, Any]``

    :param dbot_score: DBot score for the URL.
    :type dbot_score: ``Common.DBotScore``

    :return: Human readable markdown output.
    :rtype: ``str``
    """
    # Main header
    readable_output = f"## Information for the given {dbot_score_obj.to_readable()} URL: {url}\n\n"

    # Clean threat data for display
    clean_threat_data = remove_empty_elements_for_hr(threat_data)

    readable_output += (
        tableToMarkdown(
            "Threat Intelligence Summary",
            clean_threat_data,
            headerTransform=header_transformer_for_url,
            removeNull=True,
            is_auto_json_transform=True,
        )
        + "\n"
    )
    return readable_output


def dossier_lookup_task_output(task: Dict) -> Dict:
    params = task.get("params", {})
    return {
        "Task Id": task.get("task_id"),
        "Type": params.get("type"),
        "Target": params.get("target"),
        "Source": params.get("source"),
    }


def dossier_source_list_command(client: BloxOneTDClient) -> CommandResults:
    sources = client.dossier_source_list()
    return CommandResults(
        outputs_prefix="BloxOneTD",
        outputs={"DossierSource": sources},
    )


def validate_and_format_lookalike_domain_list_args(args: Dict) -> Dict:
    if len(list(filter(bool, [args.get("filter"), args.get("target_domain"), args.get("detected_at")]))) != 1:
        raise DemistoException(
            "Please provide one of the following arguments 'target_domain', 'detected_at' or 'filter'"
            " (Exactly one of them, more than one is argument is not accepted)."
        )

    if args.get("detected_at"):
        detected_at = dateparser.parse(args["detected_at"], settings={"TIMEZONE": "UTC", "TO_TIMEZONE": "UTC"})
        if detected_at is None:
            raise DemistoException(f"could not parse {args['detected_at']} as a time value.")
        args["detected_at"] = detected_at.replace(tzinfo=None).isoformat(timespec="milliseconds")
    return args


def lookalike_domain_list_command(client: BloxOneTDClient, args: Dict) -> CommandResults:
    args = validate_and_format_lookalike_domain_list_args(args)

    data = client.lookalike_domain_list(
        user_filter=args.get("filter"),
        target_domain=args.get("target_domain"),
        detected_at=args.get("detected_at"),
        limit=arg_to_number(args.get("limit")) or 50,
        offset=arg_to_number(args.get("offset")) or 0,
    )
    readable_outputs = tableToMarkdown("Results", data, headerTransform=camelize_string)
    return CommandResults(outputs_prefix="BloxOneTD.LookalikeDomain", outputs=data, readable_output=readable_outputs)


def dossier_lookup_get_command_results(data: Dict) -> CommandResults:
    headers = ["Task Id", "Type", "Target", "Source"]
    outputs = data.get("results", [])
    readable_output_data = list(map(dossier_lookup_task_output, outputs))
    readable_output = tableToMarkdown(name="Lookalike Domain List", t=readable_output_data, headers=headers)
    return CommandResults(
        outputs_prefix="BloxOneTD.DossierLookup", outputs=outputs, readable_output=readable_output, raw_response=data
    )


def dossier_lookup_get_schedule_polling_result(args: Dict, first_time: bool = False) -> CommandResults:
    next_run_in_seconds = arg_to_number(args.get("interval_in_seconds")) or 10
    timeout_in_seconds = arg_to_number(args.get("timeout")) or 600
    args["timeout"] = timeout_in_seconds - next_run_in_seconds
    scheduled_command = ScheduledCommand(
        command="bloxone-td-dossier-lookup-get",
        next_run_in_seconds=next_run_in_seconds,
        timeout_in_seconds=timeout_in_seconds,
        args=args,
    )
    readable_output = None if not first_time else f"Job '{args['job_id']}' is still running, it may take a little while..."

    return CommandResults(readable_output=readable_output, scheduled_command=scheduled_command)


def dossier_lookup_get_command(client: BloxOneTDClient, args: Dict) -> CommandResults:
    job_id = args.get("job_id")
    first_time = False
    if job_id is None:
        job_id = client.dossier_lookup_get_create(args["indicator_type"], args["value"], sources=argToList(args.get("sources")))
        first_time = True

    if client.dossier_lookup_get_is_done(job_id):
        data = client.dossier_lookup_get_results(job_id)
        return dossier_lookup_get_command_results(data)
    args["job_id"] = job_id
    return dossier_lookup_get_schedule_polling_result(args, first_time)


def ip_command(client: BloxOneTDClient, args: Dict[str, Any]) -> List[CommandResults]:
    """
    Get IP reputation from Infoblox BloxOne Threat Defense.

    Args:
        client: BloxOne Threat Defense client.
        args: Command arguments

    Returns:
        CommandResults object with IP reputation data.
    """
    ips = argToList(args.get("ip"))
    invalid_ips, valid_ips = validate_ip_addresses(ips)
    total_ips = len(valid_ips + invalid_ips)
    if invalid_ips:
        return_warning(MESSAGES["INVALID_IP_ADDRESS"].format(", ".join(invalid_ips)), exit=len(invalid_ips) == total_ips)
    validate_argument(valid_ips, "ip")
    valid_ips = list(set(valid_ips))

    command_results: List[CommandResults] = []

    for ip in valid_ips:
        # Get threat intelligence and address data
        threat_result = client.get_indicator_threat_info(ip, "ip")
        address_result = client.get_ip_address_info(ip)

        # Extract threat data
        threat_data = None
        if threat_result and threat_result.get("threat"):
            threat_data = threat_result["threat"][0]

        # Extract address data
        address_data = None
        if address_result and address_result.get("results") and len(address_result["results"]) > 0:
            address_data = address_result["results"][0]

        if not threat_data and not address_data:
            return_warning(MESSAGES["NO_INFO_FOUND"].format("threat and address", "IP", ip))
            continue

        # Calculate DBot score based on threat data
        dbot_score = Common.DBotScore.NONE
        if threat_data:
            threat_level = threat_data.get("threat_level")
            confidence = threat_data.get("confidence", 0)
            dbot_score = get_dbot_score_from_threat_level(threat_level)

        # Create DBot score object
        dbot_score_obj = Common.DBotScore(
            indicator=ip,
            indicator_type=DBotScoreType.IP,
            integration_name=VENDOR_NAME,
            score=dbot_score,
            reliability=client.integration_reliability,
        )

        dbot_score_obj.integration_name = VENDOR_NAME

        # Create IP indicator object
        ip_indicator = Common.IP(ip=ip, dbot_score=dbot_score_obj)
        ip_indicator.tags = []

        # Map threat intelligence fields to IP indicator
        if threat_data:
            # Add basic threat intelligence details
            received = threat_data.get("received")
            if received:
                ip_indicator.detection_engines = 1

            class_ = threat_data.get("class")
            if class_:
                ip_indicator.malware_family = class_

            type_ = threat_data.get("type")
            if type_:
                ip_indicator.threat_types = [
                    Common.ThreatTypes(threat_category=type_, threat_category_confidence=str(confidence or ""))
                ]

            # Add extended threat information if available
            extended = threat_data.get("extended", {})
            if extended and isinstance(extended, dict):
                ip_indicator.tags.extend(
                    [f"{key}: {value}" for key, value in extended.items() if value and isinstance(value, str)]
                )

                notes = extended.get("notes")
                if notes:
                    ip_indicator.description = notes
                    dbot_score_obj.malicious_description = notes

        # Map address information fields
        if address_data:
            # Extract hostname from names if available
            names = address_data.get("names")
            if names and isinstance(names, list):
                for name_entry in names:
                    if isinstance(name_entry, dict) and name_entry.get("name") and not ip_indicator.hostname:
                        ip_indicator.hostname = name_entry["name"]
                        break

            # Determine if IP is internal based on usage field
            usage = address_data.get("usage")
            if usage and isinstance(usage, list):
                usage_list = usage
                internal_indicators = ["internal", "private", "corporate", "DHCP LEASED"]
                is_internal = any(
                    any(indicator.lower() in str(usage).lower() for indicator in internal_indicators)
                    for usage in usage_list
                    if usage
                )
                ip_indicator.internal = is_internal

            # Add protocol information if available
            protocol = address_data.get("protocol")
            if protocol:
                ip_indicator.tags.append(f"Protocol: {protocol}")

            # Add state information if available
            state = address_data.get("state")
            if state:
                ip_indicator.tags.append(f"State: {state}")

            address_data_tags = address_data.get("tags")
            if address_data_tags and isinstance(address_data_tags, dict):
                ip_indicator.tags.extend(
                    [f"{key}: {value}" for key, value in address_data_tags.items() if value and isinstance(value, str)]
                )

        # Prepare outputs for context
        outputs = {
            "ip": ip,
            "Threat": threat_data,
            "Address": address_data,
        }

        # Create comprehensive readable output
        readable_output = prepare_hr_for_ip(ip, threat_data, address_data, dbot_score_obj)  # type: ignore

        # Create indicator timeline
        timeline = None
        if threat_data and threat_data.get("received"):
            timeline = IndicatorsTimeline(
                indicators=[ip],
                category="Threat Intelligence Update",
                message=f"IP was identified with threat level: {threat_level or 'Unknown'}, "
                f"confidence: {confidence or 'Unknown'}%",
            )

        command_result = CommandResults(
            outputs_prefix=OUTPUT_PREFIX["IP"],
            outputs_key_field="ip",
            outputs=remove_empty_elements(outputs),
            readable_output=readable_output,
            raw_response={"threat_data": threat_result, "address_data": address_result},
            indicator=ip_indicator,
            indicators_timeline=timeline,
        )
        command_results.append(command_result)

    return command_results


def domain_command(client: BloxOneTDClient, args: Dict[str, Any]) -> List[CommandResults]:
    """
    Get domain/host reputation from Infoblox BloxOne Threat Defense.

    :param client: BloxOneTDClient instance.
    :type client: ``BloxOneTDClient``

    :param args: Command arguments.
    :type args: ``Dict[str, Any]``

    :return: CommandResults object with URL reputation data.
    :rtype: ``List[CommandResults]``
    """
    domains = argToList(args.get("domain"))
    valid_domains = [domain.strip() for domain in domains if domain.strip()]
    validate_argument(valid_domains, "domain")
    valid_domains = list(set(valid_domains))
    command_results = []
    for domain in valid_domains:
        threat_result = client.get_indicator_threat_info(domain, "host")
        address_result = client.get_domain_address_info(domain)

        # Extract threat data
        threat_data = None
        if threat_result and threat_result.get("threat"):
            threat_data = threat_result["threat"][0]

        # Extract address data
        address_data = None
        if address_result and address_result.get("results") and len(address_result["results"]) > 0:
            address_data = address_result["results"][0]

        if not threat_data and not address_data:
            return_warning(MESSAGES["NO_INFO_FOUND"].format("threat and address", "Domain", domain))
            continue

        # Calculate DBot score based on threat data
        dbot_score = Common.DBotScore.NONE
        if threat_data:
            threat_level = threat_data.get("threat_level")
            confidence = threat_data.get("confidence", 0)
            dbot_score = get_dbot_score_from_threat_level(threat_level)

        # Create DBot score object
        dbot_score_obj = Common.DBotScore(
            indicator=domain,
            indicator_type=DBotScoreType.DOMAIN,
            integration_name=VENDOR_NAME,
            score=dbot_score,
            reliability=client.integration_reliability,
        )

        dbot_score_obj.integration_name = VENDOR_NAME

        domain_indicator = Common.Domain(domain=domain, dbot_score=dbot_score_obj)
        domain_indicator.tags = []

        # Map threat intelligence fields to domain indicator
        if threat_data:
            # Add basic threat intelligence details
            received = threat_data.get("received")
            if received:
                domain_indicator.detection_engines = 1

            class_ = threat_data.get("class")
            if class_:
                domain_indicator.malware_family = class_

            type_ = threat_data.get("type")
            if type_:
                domain_indicator.threat_types = [
                    Common.ThreatTypes(threat_category=type_, threat_category_confidence=str(confidence or ""))
                ]

            # Add extended threat information if available
            extended = threat_data.get("extended", {})
            if extended and isinstance(extended, dict):
                domain_indicator.tags.extend(
                    [f"{key}: {value}" for key, value in extended.items() if value and isinstance(value, str)]
                )

                notes = extended.get("notes")
                if notes:
                    domain_indicator.description = notes
                    dbot_score_obj.malicious_description = notes

        # Map address information fields
        relationships = []
        create_relationships = demisto.params().get("create_relationships")
        if address_data:
            # Add extended address information if available
            addresses = address_data.get("addresses")
            if addresses and isinstance(addresses, list) and create_relationships:
                for address in addresses:
                    address_value = address.get("address")
                    if is_ip_valid(address_value, accept_v6_ips=True):
                        relationship = EntityRelationship(
                            name=EntityRelationship.Relationships.RESOLVES_TO,
                            entity_a=domain,
                            entity_a_type=FeedIndicatorType.Domain,
                            entity_b=address_value,
                            entity_b_type=FeedIndicatorType.IP,
                            source_reliability=client.integration_reliability,
                            brand=VENDOR_NAME,
                        )
                        relationships.append(relationship)

            address_data_tags = address_data.get("tags")
            if address_data_tags and isinstance(address_data_tags, dict):
                domain_indicator.tags.extend(
                    [f"{key}: {value}" for key, value in address_data_tags.items() if value and isinstance(value, str)]
                )

        domain_indicator.relationships = relationships

        # Prepare outputs for context
        outputs = {
            "domain": domain,
            "Threat": threat_data,
            "Address": address_data,
        }

        # Create comprehensive readable output
        readable_output = prepare_hr_for_domain(domain, threat_data, address_data, dbot_score_obj)  # type: ignore

        # Create indicator timeline
        timeline = None
        if threat_data and threat_data.get("received"):
            timeline = IndicatorsTimeline(
                indicators=[domain],
                category="Threat Intelligence Update",
                message=f"Domain was identified with threat level: {threat_level or 'Unknown'}, "
                f"confidence: {confidence or 'Unknown'}%",
            )

        command_result = CommandResults(
            outputs_prefix=OUTPUT_PREFIX["Domain"],
            outputs_key_field="domain",
            outputs=remove_empty_elements(outputs),
            readable_output=readable_output,
            raw_response={"threat_data": threat_result, "address_data": address_result},
            indicator=domain_indicator,
            indicators_timeline=timeline,
            relationships=relationships,
        )
        command_results.append(command_result)

    return command_results


def url_command(client: BloxOneTDClient, args: Dict[str, Any]) -> List[CommandResults]:
    """
    Get URL reputation from Infoblox BloxOne Threat Defense.

    :param client: BloxOneTDClient instance.
    :type client: ``BloxOneTDClient``

    :param args: Command arguments.
    :type args: ``Dict[str, Any]``

    :return: CommandResults object with URL reputation data.
    :rtype: ``List[CommandResults]``
    """
    urls = argToList(args.get("url"))
    valid_urls = [url.strip() for url in urls if url.strip()]
    validate_argument(valid_urls, "url")

    valid_urls = list(set(valid_urls))
    command_results = []
    for url in valid_urls:
        threat_result = client.get_indicator_threat_info_text_search(url, "url")
        # Extract threat data
        threat_data = None
        if threat_result and threat_result.get("threat"):
            threat_data = threat_result["threat"][0]

        if not threat_data:
            return_warning(MESSAGES["NO_INFO_FOUND"].format("threat", "URL", url))
            continue

        threat_level = threat_data.get("threat_level")
        confidence = threat_data.get("confidence", 0)

        dbot_score = get_dbot_score_from_threat_level(threat_level)

        # Create DBot score object
        dbot_score_obj = Common.DBotScore(
            indicator=url,
            indicator_type=DBotScoreType.URL,
            integration_name=VENDOR_NAME,
            score=dbot_score,
            reliability=client.integration_reliability,
        )

        dbot_score_obj.integration_name = VENDOR_NAME

        url_indicator = Common.URL(url=url, dbot_score=dbot_score_obj)
        url_indicator.tags = []

        # Map threat intelligence fields to URL indicator
        # Add basic threat intelligence details
        received = threat_data.get("received")
        if received:
            url_indicator.detection_engines = 1

        class_ = threat_data.get("class")
        if class_:
            url_indicator.malware_family = class_

        type_ = threat_data.get("type")
        if type_:
            url_indicator.threat_types = [
                Common.ThreatTypes(threat_category=type_, threat_category_confidence=str(confidence or ""))
            ]

        # Add extended threat information if available
        extended = threat_data.get("extended", {})
        if extended and isinstance(extended, dict):
            url_indicator.tags.extend([f"{key}: {value}" for key, value in extended.items() if value and isinstance(value, str)])

            notes = extended.get("notes")
            if notes:
                url_indicator.description = notes
                dbot_score_obj.malicious_description = notes

        outputs = {
            "url": url,
            "Threat": threat_data,
        }

        # Create comprehensive readable output
        readable_output = prepare_hr_for_url(url, threat_data, dbot_score_obj)

        # Create indicator timeline
        timeline = None
        if threat_data.get("received"):
            timeline = IndicatorsTimeline(
                indicators=[url],
                category="Threat Intelligence Update",
                message=f"URL was identified with threat level: {threat_level or 'Unknown'}, "
                f"confidence: {confidence or 'Unknown'}%",
            )

        command_result = CommandResults(
            outputs_prefix=OUTPUT_PREFIX["URL"],
            outputs_key_field="url",
            outputs=remove_empty_elements(outputs),
            readable_output=readable_output,
            raw_response={"threat_data": threat_result},
            indicator=url_indicator,
            indicators_timeline=timeline,
        )
        command_results.append(command_result)

    return command_results


def mac_enrich_command(client, args: Dict[str, Any]) -> CommandResults:
    """
    Enriches a MAC address with DHCP lease information.

    Args:
        client: The Infoblox client.
        args: Command arguments from Demisto.

    Returns:
        CommandResults object with MAC address enrichment data
    """
    mac = args.get("mac")
    if not mac:
        raise ValueError(MESSAGES["REQUIRED_ARGUMENT"].format("mac"))
    if not bool(MAC_PATTERN.match(mac)):
        raise ValueError(MESSAGES["INVALID_VALUE"].format(mac, "mac"))

    response = client.mac_enrich(mac)

    if not response or not response.get("results") or len(response.get("results", [])) == 0:
        return CommandResults(readable_output=MESSAGES["NO_INFO_FOUND"].format("DHCP lease", "MAC", mac))

    lease_data = response.get("results")[0]

    clean_lease_data = remove_empty_elements_for_hr(lease_data)
    if "options" in clean_lease_data:
        lease_options = None
        try:
            lease_options_str = clean_lease_data["options"]
            lease_options = json.loads(lease_options_str)
            if lease_options and "Options" in lease_options:
                lease_options = lease_options["Options"]
            clean_lease_data["options"] = lease_options if lease_options else lease_options_str
        except Exception:
            pass
    readable_output = tableToMarkdown(
        f"DHCP Lease Information for MAC: {mac}",
        clean_lease_data,
        headerTransform=header_transformer_for_ip,
        removeNull=True,
        is_auto_json_transform=True,
    )

    # Return results
    return CommandResults(
        outputs_key_field="hardware",
        readable_output=readable_output,
        outputs_prefix="InfobloxCloud.DHCPLease",
        outputs=remove_empty_elements(lease_data),
        raw_response=response,
    )


def command_test_module(client: BloxOneTDClient) -> str:
    params = demisto.params()
    is_fetch = params.get("isFetch", False)
    if is_fetch:
        fetch_incidents(client, params, is_test=True)
    else:
        client.dossier_source_list()
    return "ok"


def fetch_incidents(client: BloxOneTDClient, params: dict, is_test: bool = False):
    """
    Fetches new SOC insights and DNS security events and creates incidents for them.
    :param client: BloxOneTDClient instance.
    :param params: Dictionary of parameters.
    :param is_test: Whether this is a test run.
    :return: None
    """
    max_fetch = arg_to_number(params.get("max_fetch"))
    if max_fetch is None:
        max_fetch = 50
    if max_fetch > 200:  # type: ignore
        if is_test:
            raise ValueError(ERRORS["INVALID_MAX_FETCH"].format(max_fetch))
        max_fetch = 200
        demisto.debug(
            f"The max fetch value is {max_fetch}, which is greater than the maximum allowed value of 200. Setting it to 200."
        )
    elif max_fetch < 1:  # type: ignore
        raise ValueError(ERRORS["INVALID_MAX_FETCH"].format(max_fetch))

    incidents = []
    last_run = demisto.getLastRun() or {}

    # Determine what to fetch based on parameters
    ingestion_type = params.get("ingestion_type", "SOC Insight")

    # Fetch SOC insights if enabled
    if ingestion_type == "SOC Insight":
        insights_incidents, last_run = fetch_soc_insights(client, params, last_run, max_fetch, is_test)
        incidents.extend(insights_incidents)

    # Fetch DNS security events if enabled
    if ingestion_type == "DNS Security Event":
        dns_incidents, last_run = fetch_dns_security_events(client, params, last_run, max_fetch, is_test)
        incidents.extend(dns_incidents)

    if is_test:
        return

    if not incidents:
        demisto.debug("[Infoblox] No incidents found.")
    else:
        demisto.debug(f"[Infoblox] Total {len(incidents)} incidents fetched for {ingestion_type}.")

    # Create incidents
    demisto.incidents(incidents)

    # Save the updated last run data
    demisto.setLastRun(last_run)


def fetch_dns_security_events(
    client: BloxOneTDClient, params: dict, last_run: dict, max_fetch: int, is_test: bool = False
) -> tuple[list, dict]:
    """
    Fetches DNS security events and creates incidents for them.
    :param client: BloxOneTDClient instance.
    :param params: Dictionary of parameters.
    :param last_run: Last run data.
    :param max_fetch: Maximum number of events to fetch.
    :param is_test: Whether this is a test run.
    :return: Tuple of incidents list and next run data.
    """
    incidents = []

    # Get the last fetch time for DNS events
    last_fetch_time = last_run.get("dns_events_last_fetch")

    # If no last fetch time, use first_fetch parameter
    if last_fetch_time:
        last_fetch_time = arg_to_datetime(last_fetch_time).timestamp()  # type: ignore
    else:
        last_fetch_time = arg_to_datetime(  # type: ignore
            params.get("first_fetch", DEFAULT_FIRST_FETCH), "first_fetch"
        ).timestamp()

    # Build API parameters
    api_params: dict[str, Any] = {
        "_limit": max_fetch,
        "t0": int(last_fetch_time),
        "t1": int(arg_to_datetime("now").timestamp()),  # type: ignore
    }

    # Add optional filters
    if params.get("dns_events_queried_name"):
        api_params["qname"] = ",".join(  # Note: API expects 'qname' not 'queried_name'
            item.strip() for item in argToList(params.get("dns_events_queried_name", [])) if item.strip()
        )
    if params.get("dns_events_policy_name"):
        api_params["policy_name"] = ",".join(
            item.strip() for item in argToList(params.get("dns_events_policy_name", [])) if item.strip()
        )
    if params.get("dns_events_threat_level"):
        threat_levels = [item.strip() for item in argToList(params.get("dns_events_threat_level", [])) if item.strip()]
        threat_levels_upper = [item.upper() for item in threat_levels]
        for level, upper_level in zip(threat_levels, threat_levels_upper):
            if upper_level not in THREAT_LEVELS:
                raise ValueError(MESSAGES["INVALID_DNS_EVENT_THREAT_LEVEL"].format(level))
        api_params["threat_level"] = ",".join(threat_levels_upper)
    if params.get("dns_events_threat_class"):
        api_params["threat_class"] = ",".join(
            item.strip() for item in argToList(params.get("dns_events_threat_class", [])) if item.strip()
        )
    if params.get("dns_events_threat_family"):
        api_params["threat_family"] = ",".join(
            item.strip() for item in argToList(params.get("dns_events_threat_family", [])) if item.strip()
        )
    if params.get("dns_events_threat_indicator"):
        api_params["threat_indicator"] = ",".join(
            item.strip() for item in argToList(params.get("dns_events_threat_indicator", [])) if item.strip()
        )
    if params.get("dns_events_policy_action"):
        api_params["policy_action"] = ",".join(
            item.strip() for item in argToList(params.get("dns_events_policy_action", [])) if item.strip()
        )
    if params.get("dns_events_feed_name"):
        api_params["feed_name"] = ",".join(
            item.strip() for item in argToList(params.get("dns_events_feed_name", [])) if item.strip()
        )
    if params.get("dns_events_network"):
        api_params["network"] = ",".join(item.strip() for item in argToList(params.get("dns_events_network", [])) if item.strip())

    # Fetch DNS security events
    response = client.list_dns_security_events(api_params)
    events = response.get("result", []) if isinstance(response, dict) else response  # type: ignore

    demisto.debug(f"[Infoblox DNS Security Events] Fetched {len(events)} events from API.")

    if is_test:
        return [], {}

    if not events:
        demisto.debug("[Infoblox DNS Security Events] No events found.")
        return [], last_run

    latest_event_time = events[0].get("event_time")
    events = events[::-1]
    last_run_ids = last_run.get("dns_events_ids", [])
    new_event_ids = []
    duplicate_event_ids = []

    for event in events:
        event_time = event.get("event_time")
        qname_truncated = event.get("qname", "")[:20]
        event["incident_type"] = "Infoblox Cloud DNS Security Event"
        # Create a composite key with fields separated by '|'
        key_parts = [
            event_time,
            qname_truncated,
            event.get("device", ""),
            event.get("feed_name", ""),
        ]
        composite_key = "|".join([str(part) for part in key_parts if part])
        if composite_key in last_run_ids:
            duplicate_event_ids.append(composite_key)
            continue
        last_run_ids.append(composite_key)
        new_event_ids.append(composite_key)

        # Create incident for each DNS security event
        incident_name = f"Infoblox DNS Security Event - {event.get('tclass', 'Unknown')} : {qname_truncated}"

        incident = {
            "name": incident_name,
            "details": json.dumps(event),
            "rawJSON": json.dumps(event),
            "severity": SEVERITY_MAP.get(event.get("severity", "INFO"), 1),
            "occurred": event_time,
        }
        incidents.append(incident)

    # Update next run data
    demisto.debug(f"[Infoblox DNS Security Events] Setting last_fetch_time to {latest_event_time} and index to 1.")
    last_run["dns_events_last_fetch"] = latest_event_time
    demisto.debug(f"[Infoblox DNS Security Events] Found {len(new_event_ids)} new events with IDs: {', '.join(new_event_ids)}.")
    last_run["dns_events_ids"] = last_run_ids

    if duplicate_event_ids:
        demisto.debug(
            f"[Infoblox DNS Security Events] {len(duplicate_event_ids)} duplicate events were skipped with"
            f"IDs: {', '.join(duplicate_event_ids)}."
        )

    return incidents, last_run


def fetch_soc_insights(
    client: BloxOneTDClient, params: dict, last_run: dict, max_fetch: int, is_test: bool = False
) -> tuple[list, dict]:
    """
    Fetches new SOC insights and creates incidents for them.
    :param client: BloxOneTDClient instance.
    :param params: Dictionary of parameters.
    :param last_run: Last run data.
    :param max_fetch: Maximum number of insights to fetch.
    :param is_test: Whether this is a test run.
    :return: Tuple of incidents list and next run data.
    """
    incidents = []
    last_run_ids = last_run.get("soc_insight_ids", [])

    params = {
        "status": params.get("soc_insight_status"),
        "priority": params.get("soc_insight_priority_level"),
        "threat_type": params.get("soc_insight_threat_type"),
    }

    results = client.soc_insights_list(params)
    insights = results.get("insightList", [])  # type: ignore
    soc_insight_ids = []
    new_insights = []
    new_insight_ids = []
    duplicate_insight_ids = []

    for insight in insights:
        soc_insight_id = insight.get("insightId")
        if not soc_insight_id or soc_insight_id in last_run_ids:
            duplicate_insight_ids.append(soc_insight_id) if soc_insight_id else None
            continue
        insight["incident_link"] = INCIDENT_LINK.format(soc_insight_id)
        new_insights.append(insight)
        last_run_ids.append(soc_insight_id)
        new_insight_ids.append(soc_insight_id)
        soc_insight_ids.append(insight.get("insightId"))
        if len(new_insights) >= max_fetch:  # type: ignore
            break

    if is_test:
        return [], {}

    for insight in new_insights:
        threat_type = insight.get("threatType")
        threat_family = insight.get("tFamily")
        insight["incident_type"] = "Infoblox Cloud SOC Insight"
        incident = {
            "name": f"Infoblox SOC Insight - {threat_type} : {threat_family}",  # noqa: E203
            "details": json.dumps(insight),
            "rawJSON": json.dumps(insight),
            "severity": SEVERITY_MAP.get(insight["priorityText"], 1),
        }
        incidents.append(incident)

    if not insights:
        demisto.debug("[Infoblox SOC Insight] No SOC Insights found.")
        return [], last_run

    # Update next run data
    last_run["soc_insight_ids"] = last_run_ids
    demisto.debug(f"[Infoblox SOC Insight] Found {len(new_insight_ids)} new SOC Insights with IDs: {', '.join(new_insight_ids)}.")

    demisto.debug(
        f"[Infoblox SOC Insight] {len(duplicate_insight_ids)} duplicate SOC Insights were skipped with"
        f"IDs: {', '.join(duplicate_insight_ids)}."
    )

    return incidents, last_run


def remove_duplicate_entries(indicator_list: list[str]) -> list[str]:
    """
    Remove duplicate entries in a list.
    :param indicator_list: List of indicators.
    :return: List of indicators without duplicates.
    """
    result = []
    for item in indicator_list:
        if item.strip() and item.strip() not in result:
            result.append(item.strip())
    return result


def generic_named_list_method(
    client: BloxOneTDClient, args: dict[str, Any], data: dict[str, Any], is_remove: bool = False
) -> CommandResults:
    """
    Generic method for named list operations.
    :param client: BloxOneTDClient instance.
    :param args: Dictionary of arguments.
    :param data: Dictionary of data to update the named list.
    :return: CommandResults instance.
    """
    params = {
        "name": validate_argument(args.get("custom_list_name"), "custom_list_name"),  # type: ignore
        "type": validate_argument(args.get("custom_list_type"), "custom_list_type"),  # type: ignore
    }
    try:
        named_list = client.get_named_list(params)
    except DemistoException as error:
        if client.last_response.text:  # type: ignore
            text = client.last_response.text  # type: ignore
            raise ValueError(f"{error}\n{text}")
        raise ValueError(f"Failed to get named list: {error}")
    named_list_id = validate_key(named_list.get("results"), "id")
    items = data.get("items")
    items = remove_duplicate_entries(items)  # type: ignore
    data["items"] = items
    indicators = ", ".join(items)
    if is_remove:
        try:
            client.remove_named_list_items(named_list_id, data)
            title = f"'{indicators}' indicators removed from the '{args.get('custom_list_name')}' list"
        except Exception as error:
            match = re.search(r"(\d+)\s+Items", str(error))
            if match:
                number = int(match.group(1))
                raise ValueError(f"{number} indicators were not present in the list.")
            raise ValueError(f"Failed to remove indicators from named list: {error}")
    else:
        try:
            client.update_named_list(named_list_id, data)
            title = f"'{indicators}' indicators added to the '{args.get('custom_list_name')}' list"
        except Exception as error:
            raise ValueError(f"Failed to add indicators to named list: {error}")
    data = client.get_named_list(params)
    named_list = validate_key(data, "results")
    return CommandResults(
        readable_output=prepare_hr_for_named_list(named_list, title),
        outputs_prefix="InfobloxCloud.CustomList",
        outputs_key_field="id",
        outputs=remove_empty_elements(named_list),
        raw_response=data,
    )


def validate_ip(ip: str):
    """
    Validate an IP address or CIDR.
    :param ip: IP address or CIDR.
    :return: Validated IP address or CIDR.
    """
    ip = validate_argument(ip, "ip")
    for fn in [ipaddress.ip_address, lambda v: ipaddress.ip_network(v, strict=False)]:
        try:
            fn(ip)
            return ip
        except ValueError:
            continue
    raise ValueError(f"Invalid IP or CIDR: {ip}")


def validate_ip_list(ip_list: str) -> list[str]:
    """
    Validate a list of IP addresses or CIDRs.
    :param ip_list: List of IP addresses or CIDRs.
    :return: Validated list of IP addresses or CIDRs.
    """
    ip_list = argToList(ip_list, ",")
    ip_list = [ip.strip() for ip in ip_list if ip.strip()]
    for ip in ip_list:
        validate_ip(ip)
    ip_list = validate_argument(ip_list, "ip")  # type: ignore
    return ip_list  # type: ignore


def validate_domain(domain: str):
    """
    Validate a domain.
    :param domain: Domain.
    :return: Validated domains.
    """
    domains = argToList(domain, ",")
    domains = [domain.strip() for domain in domains if domain.strip()]
    domains = validate_argument(domains, "domain")  # type: ignore
    return domains


def validate_datetime(time_string: str, name: str) -> str | None:
    """
    Validate a datetime.
    :param time_string: Time string.
    :param name: Name of the time string.
    :return: Validated datetime.
    """
    time_obj = arg_to_datetime(time_string, name)
    if time_obj:
        return time_obj.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3]  # type: ignore
    return None


def block_ip_command(client: BloxOneTDClient, args: dict[str, Any]) -> CommandResults:
    """
    Block an IP in a custom list.
    :param client: BloxOneTDClient instance.
    :param args: Dictionary of arguments.
    :return: CommandResults instance.
    """
    ip_list = validate_ip_list(args.get("ip"))  # type: ignore
    data = {"items": ip_list}
    return generic_named_list_method(client, args, data)


def unblock_ip_command(client: BloxOneTDClient, args: dict[str, Any]) -> CommandResults:
    """
    Unblock an IP from a custom list.
    :param client: BloxOneTDClient instance.
    :param args: Dictionary of arguments.
    :return: CommandResults instance.
    """
    ip_list = validate_ip_list(args.get("ip"))  # type: ignore
    data = {"items": ip_list}
    return generic_named_list_method(client, args, data)


def block_domain_command(client: BloxOneTDClient, args: dict[str, Any]) -> CommandResults:
    """
    Block an domain in a custom list.
    :param client: BloxOneTDClient instance.
    :param args: Dictionary of arguments.
    :return: CommandResults instance.
    """
    domain = validate_domain(args.get("domain"))  # type: ignore
    data = {"items": domain}
    return generic_named_list_method(client, args, data)


def unblock_domain_command(client: BloxOneTDClient, args: dict[str, Any]) -> CommandResults:
    """
    Unblock an domain from a custom list.
    :param client: BloxOneTDClient instance.
    :param args: Dictionary of arguments.
    :return: CommandResults instance.
    """
    domain = validate_domain(args.get("domain"))  # type: ignore
    data = {"items": domain}
    return generic_named_list_method(client, args, data)


def infobloxcloud_customlist_indicator_remove(client: BloxOneTDClient, args: dict[str, Any]) -> CommandResults:
    """
    Unblock an IP from a custom list.
    :param client: BloxOneTDClient instance.
    :param args: Dictionary of arguments.
    :return: CommandResults instance.
    """
    indicators = argToList(args.get("indicators"), ",")
    indicators = remove_duplicate_entries(indicators)
    indicators = validate_argument(indicators, "indicators")
    data = {"items": indicators}
    return generic_named_list_method(client, args, data, is_remove=True)


def list_soc_insights_command(client: BloxOneTDClient, args: dict[str, Any]) -> CommandResults:
    """
    List SOC insights.
    :param client: BloxOneTDClient instance.
    :param args: Dictionary of arguments.
    :return: CommandResults instance.
    """
    params = {
        "status": args.get("status"),
        "priority": args.get("priority"),
        "threat_type": args.get("threat_type"),
    }
    insights = client.soc_insights_list(params)
    insights = insights.get("insightList", [])  # type: ignore
    if not insights:
        return CommandResults(
            readable_output="No SOC Insights found.",
            raw_response=insights,
        )
    return CommandResults(
        readable_output=prepare_hr_for_soc_insights(insights),
        outputs_prefix="InfobloxCloud.SOCInsight",
        outputs_key_field="insightId",
        outputs=remove_empty_elements(insights),
        raw_response=insights,
    )


def list_soc_insight_indicators_command(client: BloxOneTDClient, args: dict[str, Any]) -> CommandResults:
    """
    List SOC insight indicators.
    :param client: BloxOneTDClient instance.
    :param args: Dictionary of arguments.
    :return: CommandResults instance.
    """
    soc_insight_id = validate_argument(args.get("soc_insight_id"), "soc_insight_id")
    params = {
        "confidence": args.get("confidence"),
        "indicator": args.get("indicator"),
        "action": args.get("action"),
        "actor": args.get("actor"),
        "limit": arg_to_number(args.get("limit", 50)),
        "from": validate_datetime(args.get("start_time"), "start_time"),  # type: ignore
        "to": validate_datetime(args.get("end_time"), "end_time"),  # type: ignore
    }
    params = remove_empty_elements(params)
    indicators = client.soc_insight_indicators_list(params, soc_insight_id)
    indicators = indicators.get("indicators", [])  # type: ignore
    if not indicators:
        return CommandResults(
            readable_output="No indicators found.",
            raw_response=indicators,
        )
    return CommandResults(
        readable_output=prepare_hr_for_soc_insight_indicators(indicators, soc_insight_id),
        outputs_prefix="InfobloxCloud.Indicator",
        outputs_key_field="indicatorId",
        outputs=remove_empty_elements(indicators),
        raw_response=indicators,
    )


def list_soc_insight_events_command(client: BloxOneTDClient, args: dict[str, Any]) -> CommandResults:
    """
    List SOC insight events.
    :param client: BloxOneTDClient instance.
    :param args: Dictionary of arguments.
    :return: CommandResults instance.
    """
    soc_insight_id = validate_argument(args.get("soc_insight_id"), "soc_insight_id")
    device_ip = args.get("device_ip")
    if device_ip and not is_ip_valid(device_ip, accept_v6_ips=True):
        raise ValueError(MESSAGES["INVALID_VALUE"].format(device_ip, "device_ip"))
    params = {
        "threat_level": args.get("threat_level"),
        "confidence_level": args.get("confidence_level"),
        "query": args.get("query"),
        "query_type": args.get("query_type"),
        "limit": arg_to_number(args.get("limit", 50)),
        "from": validate_datetime(args.get("start_time"), "start_time"),  # type: ignore
        "to": validate_datetime(args.get("end_time"), "end_time"),  # type: ignore
        "source": args.get("source"),
        "device_ip": device_ip,
        "indicator": args.get("indicator"),
    }
    params = remove_empty_elements(params)
    events = client.soc_insight_events_list(params, soc_insight_id)
    events = events.get("events", [])  # type: ignore
    if not events:
        return CommandResults(
            readable_output="No events found.",
            raw_response=events,
        )
    return CommandResults(
        readable_output=prepare_hr_for_soc_insight_events(events, soc_insight_id),
        outputs_prefix="InfobloxCloud.Event",
        outputs_key_field="eventId",
        outputs=remove_empty_elements(events),
        raw_response=events,
    )


def list_soc_insight_assets_command(client: BloxOneTDClient, args: dict[str, Any]) -> CommandResults:
    """
    List SOC insight assets.
    :param client: BloxOneTDClient instance.
    :param args: Dictionary of arguments.
    :return: CommandResults instance.
    """
    qip = args.get("qip")
    cmac = args.get("cmac")
    if qip and not is_ip_valid(qip, accept_v6_ips=True):
        raise ValueError(MESSAGES["INVALID_VALUE"].format(qip, "qip"))
    if cmac and not bool(MAC_PATTERN.match(cmac)):
        raise ValueError(MESSAGES["INVALID_VALUE"].format(cmac, "cmac"))
    soc_insight_id = validate_argument(args.get("soc_insight_id"), "soc_insight_id")
    params = {
        "qip": qip,
        "cmac": cmac,
        "os_version": args.get("os_version"),
        "user": args.get("user"),
        "limit": arg_to_number(args.get("limit", 50)),
        "from": validate_datetime(args.get("start_time"), "start_time"),  # type: ignore
        "to": validate_datetime(args.get("end_time"), "end_time"),  # type: ignore
    }
    params = remove_empty_elements(params)
    assets = client.soc_insight_assets_list(params, soc_insight_id)
    assets = assets.get("assets", [])  # type: ignore
    if not assets:
        return CommandResults(
            readable_output="No assets found.",
            raw_response=assets,
        )
    return CommandResults(
        readable_output=prepare_hr_for_soc_insight_assets(assets, soc_insight_id),
        outputs_prefix="InfobloxCloud.Asset",
        outputs_key_field="assetId",
        outputs=remove_empty_elements(assets),
        raw_response=assets,
    )


def list_soc_insight_comments_command(client: BloxOneTDClient, args: dict[str, Any]) -> CommandResults:
    """
    List SOC insight comments.
    :param client: BloxOneTDClient instance.
    :param args: Dictionary of arguments.
    :return: CommandResults instance.
    """
    soc_insight_id = validate_argument(args.get("soc_insight_id"), "soc_insight_id")
    limit = arg_to_number(args.get("limit", 50))
    if limit < 0:  # type: ignore
        raise ValueError("Limit should not be less than 0.")
    params = {
        "from": validate_datetime(args.get("start_time"), "start_time"),  # type: ignore
        "to": validate_datetime(args.get("end_time"), "end_time"),  # type: ignore
    }
    params = remove_empty_elements(params)
    comments = client.soc_insight_comments_list(params, soc_insight_id)
    comments = comments.get("comments", [])  # type: ignore
    if not comments:
        return CommandResults(
            readable_output="No comments found.",
            raw_response=comments,
        )
    if limit != 0:
        comments = comments[:limit]
    return CommandResults(
        readable_output=prepare_hr_for_soc_insight_comments(comments, soc_insight_id),
        outputs_prefix="InfobloxCloud.Comment",
        outputs_key_field="commentId",
        outputs=remove_empty_elements(comments),
        raw_response=comments,
    )


def main():
    params = demisto.params()
    client = BloxOneTDClient(
        api_key=params["credentials"]["password"],
        verify=not argToBoolean(params.get("insecure", False)),
        proxy=argToBoolean(params.get("proxy", False)),
    )
    commands_with_args = {
        "bloxone-td-dossier-lookup-get": dossier_lookup_get_command,
        "bloxone-td-lookalike-domain-list": lookalike_domain_list_command,
    }

    commands_without_args = {
        "test-module": command_test_module,
        "bloxone-td-dossier-source-list": dossier_source_list_command,
    }

    new_commands_with_args = {
        "infobloxcloud-block-ip": block_ip_command,
        "infobloxcloud-unblock-ip": unblock_ip_command,
        "infobloxcloud-block-domain": block_domain_command,
        "infobloxcloud-unblock-domain": unblock_domain_command,
        "infobloxcloud-customlist-indicator-remove": infobloxcloud_customlist_indicator_remove,
        "ip": ip_command,
        "domain": domain_command,
        "url": url_command,
        "infobloxcloud-mac-enrich": mac_enrich_command,
        "infobloxcloud-soc-insight-list": list_soc_insights_command,
        "infobloxcloud-soc-insight-indicator-list": list_soc_insight_indicators_command,
        "infobloxcloud-soc-insight-event-list": list_soc_insight_events_command,
        "infobloxcloud-soc-insight-asset-list": list_soc_insight_assets_command,
        "infobloxcloud-soc-insight-comment-list": list_soc_insight_comments_command,
    }

    command = demisto.command()
    demisto.debug(f"Command being called is {command}")
    try:
        if command in commands_without_args:
            results = commands_without_args[command](client)
            return_results(results)
        elif command in commands_with_args:
            args = demisto.args()
            results = commands_with_args[command](client, args)
            return_results(results)
        elif command in new_commands_with_args:
            command_args = trim_args(demisto.args())
            remove_nulls_from_dictionary(command_args)
            results = new_commands_with_args[command](client, command_args)
            return_results(results)
        elif command == "fetch-incidents":
            fetch_incidents(client, params)
        else:
            raise NotImplementedError(f"command {command} is not implemented.")
    except Exception as e:
        auth_error = isinstance(e, DemistoException) and e.res is not None and e.res.status_code == 401  # pylint: disable=E1101
        if auth_error:
            error_msg = "authentication error"
        else:
            error_msg = f"an error occurred while executing command {command}\nerror: {e}"

        return_error(error_msg, e)


if __name__ in ("__main__", "builtins"):
    main()