Shodan_v2

A search engine used for searching Internet-connected devices.

Data Enrichment & Threat Intelligence · Shodan

Details

IDShodan_v2
ProviderShodan
CategoryData Enrichment & Threat Intelligence
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM EDR Cortex Cloud Attack Surface Management Cloud Runtime Security Cloud Posture Security Exposure Management

README

Shodan is a search engine for Internet-connected devices. Unlike traditional search engines that index websites, Shodan indexes information about the devices connected to the internet, such as servers, routers, webcams, and other IoT devices.

Configure Shodan v2 in Cortex

Parameter Description Required
API Key   False
Base URL to Shodan API   True
Trust any certificate (not secure)   False
Use system proxy settings   False
Source Reliability Reliability of the source providing the intelligence data. False
The maximum number of events per fetch   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.

search


Searches Shodan using facets to get summary information on properties.

Base Command

search

Input

Argument Name Description Required
query The query for searching the database of banners. The search query supports filtering using the “filter:value” format to narrow your search. For example, the query “apache country:DE” returns Apache web servers located in Germany. Required
facets A CSV list of properties on which to get summary information. The search query supports filtering using the “property:count” format to define the number of facets to return for a property. For example, the query “country:100” returns the top 100 countries. Optional
page The page number of the fetched results. Each page contains a maximum of 100 results. Default is 1. Optional
return_json Whether to return a JSON file containing the full search results for further processing. Possible values are: Yes, No. Default is No. Optional

Context Output

Path Type Description
Shodan.Banner.Org String The name of the organization to which the space of the IP address space for the searched device is assigned.
Shodan.Banner.Isp String The Internet Service Provider that provides the organization with the IP address space for the searched device.
Shodan.Banner.Transport String The IP address transport protocol used to fetch the summary information. Can be “UDP” or “TCP”.
Shodan.Banner.Asn String The Autonomous System Number. For example, “AS4837”.
Shodan.Banner.IP String The IP address of the host as a string.
Shodan.Banner.Port Number The port number on which the service is operating.
Shodan.Banner.Ssl.versions String The list of SSL versions that are supported by the server. Unsupported versions are prefixed with a “-“. For example, [“TLSv1”, “-SSLv2”] means that the server supports TLSv1, but does not support SSLv2.
Shodan.Banner.Hostnames String An array of strings containing all of the host names that have been assigned to the IP address for the searched device.
Shodan.Banner.Location.City String The city in which the searched device is located.
Shodan.Banner.Location.Longitude Number The longitude of the geolocation of the searched device.
Shodan.Banner.Location.Latitude Number The latitude of the geolocation of the searched device.
Shodan.Banner.Location.Country String The country in which the searched device is located.
Shodan.Banner.Timestamp Date The timestamp in UTC format indicating when the banner was fetched from the searched device.
Shodan.Banner.Domains String An array of strings containing the top-level domains for the host names of the searched device. It is a utility property for filtering by a top-level domain instead of a subdomain. It supports handling global top-level domains that have several dots in the domain. For example, “co.uk”.
Shodan.Banner.OS String The operating system that powers the searched device.
Shodan.Banner.Product String Name of the software that powers the service.
Shodan.Banner.Ntlm.OSBuild String OS build reported by the service.
Shodan.Banner.Ntlm.DNSForestName String DNS Forest Name reported by the service.
Shodan.Banner.Ntlm.Timestamp Number Timestamp.
Shodan.Banner.Ntlm.FQDN String FQDN.
Shodan.Banner.Ntlm.NetBIOSDomainName String Netbios Domain Name.
Shodan.Banner.Ntlm.NetBIOSComputerName String Netbios Computer Name.
Shodan.Banner.Ntlm.TargetRealm String Target Realm.
Shodan.Banner.Ntlm.OS Unknown OS.
Shodan.Banner.Ntlm.DNSDomainName String DNS Domain Name.
Shodan.Banner.Hash Number Numeric hash of the “data” property which is helpful for finding other IPs with the exact same information.
Shodan.Banner.Tags Unknown Tag applied by Shodan analysis.
Shodan.Banner.SslCert.SigAlg String Certificate Signature Algorithm.
Shodan.Banner.SslCert.Issued Date Timestamp of the beginning of certificate validity (Not Valid Before).
Shodan.Banner.SslCert.Expires Date Timestamp of the end of certificate validity (Not Valid After).
Shodan.Banner.SslCert.Version Number X.509 Certificate Version.
Shodan.Banner.SslCert.Serial Number Serial Number assigned by the issuer.
Shodan.Banner.SslCert.Subject.CN String Subject Common Name.
Shodan.Banner.SslCert.Subject.O String Subject Organization.
Shodan.Banner.SslCert.Subject.L String Subject Locality or City.
Shodan.Banner.SslCert.Subject.ST String Subject State or Province.
Shodan.Banner.SslCert.Subject.C String Subject Country Name.
Shodan.Banner.SslCert.Expired Boolean Boolean indicating whether the certificate is expired.
Shodan.Banner.SslCert.Issuer.CN String Issuer Certificate Common Name.
Shodan.Banner.SslCert.Issuer.O String Issuer Organization.
Shodan.Banner.SslCert.Issuer.OU String Issuer Organizational Unit.
Shodan.Banner.SslCert.Issuer.L String Issuer Locality or City.
Shodan.Banner.SslCert.Issuer.ST String Issuer State or Province.
Shodan.Banner.SslCert.Issuer.C String Issuer Country Name.
Shodan.Banner.Data String The raw data returned fro the service.
Shodan.Banner.CPE23 Unknown CPE information in the 2.3 format.
Shodan.Banner.Device String Device identified by Shodan.
Shodan.Banner.DeviceType String The Device Type identified by Shodan.
Shodan.Banner.Info String Additional information provided by Shodan.
Shodan.Banner.IPv6 String The IPv6 address of the host as a string.
Shodan.Banner.Link String The Link identified by Shodan.
Shodan.Banner.Platform String The Platform identified by Shodan.
Shodan.Banner.Product String The Product identified by Shodan.

Command Example

!search query="country:HK org:RLL-HK -port:80 -port:443 -port:21 -port:25 has_ssl:false" using-brand=Shodan_v2

Context Example

{
    "Shodan": [
        {
            "Banner": {
                "Asn": "AS9311",
                "Domains": [],
                "Hostnames": [],
                "IP": "1.2.3.4",
                "Isp": "HITRON TECHNOLOGY INC.",
                "Location": {
                    "City": "Hong Kong",
                    "Country": "Hong Kong",
                    "Latitude": 22.27832,
                    "Longitude": 114.17469
                },
                "OS": null,
                "Org": "RLL-HK",
                "Port": 5353,
                "Ssl": {
                    "versions": []
                },
                "Timestamp": "2021-08-17T03:33:07.392394",
                "Transport": "udp"
            }
        },
        {
            "Banner": {
                "Asn": "AS9919",
                "Domains": [],
                "Hostnames": [],
                "IP": "1.2.3.4",
                "Isp": "New Century InfoComm Tech Co., Ltd.",
                "Location": {
                    "City": "Hong Kong",
                    "Country": "Hong Kong",
                    "Latitude": 22.27832,
                    "Longitude": 114.17469
                },
                "OS": null,
                "Org": "RLL-HK",
                "Port": 5353,
                "Ssl": {
                    "versions": []
                },
                "Timestamp": "2021-08-17T03:21:00.992437",
                "Transport": "udp"
            }
        },
        {
            "Banner": {
                "Asn": "AS9311",
                "Domains": [],
                "Hostnames": [],
                "IP": "1.2.3.4",
                "Isp": "HITRON TECHNOLOGY INC.",
                "Location": {
                    "City": "Hong Kong",
                    "Country": "Hong Kong",
                    "Latitude": 22.27832,
                    "Longitude": 114.17469
                },
                "OS": null,
                "Org": "RLL-HK",
                "Port": 5353,
                "Ssl": {
                    "versions": []
                },
                "Timestamp": "2021-08-17T03:13:54.617598",
                "Transport": "udp"
            }
        }
    ]
}

Human Readable Output

Search results for query “country:HK org:RLL-HK -port:80 -port:443 -port:21 -port:25 has_ssl:false” - page 1, facets: None

IP Port Timestamp
1.2.3.4 5353 2021-08-17T03:13:54.617598

ip


Returns all services that have been found on the IP address of the searched host.

Base Command

ip

Input

Argument Name Description Required
ip The IP address of the host. Required

Context Output

Path Type Description
IP.ASN Unknown The Autonomous System Number.
IP.Address Unknown The IP address.
IP.Geo.Country Unknown The country of a given IP address.
IP.Geo.Description Unknown The description of the location.
IP.Geo.Location Unknown The latitude and longitude of an IP address.
IP.Hostname Unknown The hostname of the IP address.
IP.Relationships Unknown The relationships between the ip and it’s CVEs.
Shodan.IP.Tags String The tags associated with the IP address.
Shodan.IP.Latitude Number The latitude of the geolocation of the searched device.
Shodan.IP.Org String The name of the organization to which the IP space for the searched device is assigned.
Shodan.IP.ASN String The Autonomous System Number. For example, “AS4837”.
Shodan.IP.ISP String The Internet Service Provider that provides the organization with the IP space for the searched device.
Shodan.IP.Longitude Number The longitude of the geolocation of the searched device.
Shodan.IP.LastUpdate Date The timestamp in UTC format indicating when the banner was fetched from the searched device.
Shodan.IP.CountryName String The country in which the searched device is located.
Shodan.IP.OS String The operating system on which the searched device is running.
Shodan.IP.Port Number The port number on which the service is operating.
Shodan.IP.Address String The IP address of the host as a string.
Shodan.IP.Vulnerabilities Unknown A list of Vulnerabilities.
DBotScore.Indicator String The indicator that was tested.
DBotScore.Score Number The actual score.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.

Command Example

!ip ip="8.8.8.8" using-brand="Shodan_v2"

Context Example

{
    "IP": {
        "ASN": "AS15169",
        "Address": "8.8.8.8",
        "Geo": {
            "Country": "United States",
            "Location": "37.406,-122.078"
        },
        "Hostname": "dns.google",
        "Relationships": [
          {
            "EntityA": "8.8.8.8",
            "EntityAType": "IP",
            "EntityB": "CVE-2016-11111",
            "EntityBType": "CVE",
            "Relationship": "related-to"
          }
        ]
    },
    "Shodan": {
        "IP": {
            "ASN": "AS15169",
            "Address": "8.8.8.8",
            "CountryName": "United States",
            "ISP": "Google LLC",
            "LastUpdate": "2021-08-20T17:13:07.423800",
            "Latitude": 37.4056,
            "Longitude": -122.0775,
            "OS": null,
            "Org": "Google LLC",
            "Port": [
                53
            ],
            "Tag": [],
            "Vulnerabilities": ["CVE-2016-11111"]
        }
    },
    "DBotScore": {
        "Indicator": "8.8.8.8",
        "Score": 0,
        "Type": "ip",
        "Vendor": "Shodan_v2"
    }
}

Human Readable Output

Shodan details for IP 8.8.8.8

ASN Country Hostname ISP Location Ports
AS15169 United States dns.google Google LLC 37.406,-122.078 53

shodan-search-count


Returns the total number of results that match only the specified query or facet settings. This command does not return host results. This command does not consume query credits.

Base Command

shodan-search-count

Input

Argument Name Description Required
query The query for searching the database of banners. The search query supports filtering using the “filter:value” format to narrow your search. For example, the query “apache country:DE” returns Apache web servers located in Germany. Required

Context Output

Path Type Description
Shodan.Search.ResultCount Number The number of results matched in the search query.

Command Example

!shodan-search-count query="country:HK product:Apache"

Context Example

{
    "Shodan": {
        "Search": {
            "ResultCount": 498645
        }
    }
}

Human Readable Output

498645 results for query “country:HK product:Apache”

shodan-scan-ip


Requests Shodan to crawl a network.

Base Command

shodan-scan-ip

Input

Argument Name Description Required
ips A CSV list of IP addresses or netblocks for Shodan to crawl defined in CIDR notation. Required

Context Output

Path Type Description
Shodan.Scan.ID String The unique ID of the scan.
Shodan.Scan.Status String The status of the scan.

Command Example

!shodan-scan-ip ips=8.8.8.8

Context Example

{
    "Shodan": {
        "Scan": {
            "ID": "wQEp0bIIEHklpAwa",
            "Status": "PROCESSING"
        }
    }
}

Human Readable Output

Scanning results for scan wQEp0bIIEHklpAwa

ID Status
wQEp0bIIEHklpAwa PROCESSING

shodan-scan-internet


Requests for Shodan to perform a scan on the specified port and protocol.

Base Command

shodan-scan-internet

Input

Argument Name Description Required
port The port for which Shodan crawls the Internet. Required
protocol The name of the protocol used to interrogate the port. Required

Context Output

Path Type Description
Shodan.Scan.ID String The ID of the initial scan.

Command Example


#### Human Readable Output

### shodan-scan-status

***
Checks the progress of a previously submitted scan request on the specified port and protocol.

#### Base Command

`shodan-scan-status`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| scanID | The unique ID of the initial scan. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| Shodan.Scan.Id | String | The unique ID of the scan request checked for progress. |
| Shodan.Scan.Status | String | The status of the scan job checked for progress. |

#### Command Example

```!shodan-scan-status scanID=7rbp1CAtx91BMwcg```

#### Context Example

```json
{
    "Shodan": {
        "Scan": {
            "ID": "7rbp1CAtx91BMwcg",
            "Status": "DONE"
        }
    }
}

Human Readable Output

Scanning results for scan 7rbp1CAtx91BMwcg

ID Status
7rbp1CAtx91BMwcg DONE

shodan-create-network-alert


Creates a network alert for a defined IP address or netblock used for subscribing to changes or events that are discovered within the netblock’s range.

Base Command

shodan-create-network-alert

Input

Argument Name Description Required
alertName The name of the network alert. Required
ip A list of IP addresses or network ranges defined in CIDR notation. Required
expires The number of seconds for the network alert to remain active. Optional

Context Output

Path Type Description
Shodan.Alert.ID String The ID of the subscription of the specified network alert.
Shodan.Alert.Expires String The number of seconds that the specified network alert remains active.

Command Example

!shodan-create-network-alert alertName="test_alert" ip="1.1.1.1"

Context Example

{
    "Shodan": {
        "Alert": {
            "Expires": 0,
            "ID": "CB68M776ICCMS36L"
        }
    }
}

Human Readable Output

Alert ID CB68M776ICCMS36L

Expires IP Name
0 1.1.1.1 test_alert

shodan-network-get-alert-by-id


Gets the details of a network alert.

Base Command

shodan-network-get-alert-by-id

Input

Argument Name Description Required
alertID The ID of the network alert. Required

Context Output

Path Type Description
Shodan.Alert.ID String The ID of the subscription of the network alert.
Shodan.Alert.Expires String The number of seconds that the network alert remains active.

Command Example

!shodan-network-get-alert-by-id alertID="0EKRH38BBQEHTQ3E"

Context Example

{
    "Shodan": {
        "Alert": {
            "Expires": 0,
            "ID": "0EKRH38BBQEHTQ3E"
        }
    }
}

Human Readable Output

Alert ID 0EKRH38BBQEHTQ3E

Expires IP Name
0 1.2.3.4 test_alert

shodan-network-get-alerts


Gets a list of all created network alerts.

Base Command

shodan-network-get-alerts

Input

There are no input arguments for this command.

Context Output

Path Type Description
Shodan.Alert.ID String The IDs of the subscriptions of the network alerts.
Shodan.Alert.Expires String The number of seconds that the network alerts remain active.

Command Example


#### Context Example

```json
{
    "Shodan": [
        {
            "Alert": {
                "Expires": 0,
                "ID": "0EKRH38BBQEHTQ3E"
            }
        },
        {
            "Alert": {
                "Expires": 0,
                "ID": "CB68M776ICCMS36L"
            }
        },
        {
            "Alert": {
                "Expires": 0,
                "ID": "HTWLPTVPUHN5VAGA"
            }
        },
        {
            "Alert": {
                "Expires": 0,
                "ID": "VXGB6CZ536X5AWE6"
            }
        }
    ]
}

Human Readable Output

Alert ID VXGB6CZ536X5AWE6

Expires IP Name
0 1.1.1.1 test_alert

shodan-network-delete-alert


Removes the specified network alert.

Base Command

shodan-network-delete-alert

Input

Argument Name Description Required
alertID The ID of the network alert to remove. Required

Context Output

There is no context output for this command.

Command Example

!shodan-network-delete-alert alertID="0EKRH38BBQEHTQ3E"

Human Readable Output

Deleted alert 0EKRH38BBQEHTQ3E

shodan-network-alert-set-trigger


Enables receiving notifications for network alerts that are set off by the specified triggers.

Base Command

shodan-network-alert-set-trigger

Input

Argument Name Description Required
alertID The ID of the network alert for which to enable notifications. Required
Trigger The name of the trigger. Required

Context Output

There is no context output for this command.

Command Example

!shodan-network-alert-set-trigger alertID="0EKRH38BBQEHTQ3E" Trigger=any

Human Readable Output

Set trigger “any” for alert 0EKRH38BBQEHTQ3E

shodan-network-alert-remove-trigger


Disables receiving notifications for network alerts that are set off by the specified triggers.

Base Command

shodan-network-alert-remove-trigger

Input

Argument Name Description Required
alertID The ID of the network alert for which to disable notifications. Required
Trigger The name of the trigger. Required

Context Output

There is no context output for this command.

Command Example

!shodan-network-alert-remove-trigger alertID="0EKRH38BBQEHTQ3E" Trigger="any"

Human Readable Output

Deleted trigger “any” for alert 0EKRH38BBQEHTQ3E

shodan-network-alert-whitelist-service


Ignores the specified services for network alerts that are set off by the specified triggers.

Base Command

shodan-network-alert-whitelist-service

Input

Argument Name Description Required
alertID The ID of the network alert for which to ignore the specified services. Required
trigger The name of the trigger. Required
service The service specified in the “ip:port” format. For example, “1.1.1.1:80”. Required

Context Output

There is no context output for this command.

Command Example

!shodan-network-alert-whitelist-service alertID="0EKRH38BBQEHTQ3E" trigger="any" service="1.1.1.1:80"

Human Readable Output

Whitelisted service “1.1.1.1:80” for trigger any in alert 0EKRH38BBQEHTQ3E

shodan-network-alert-remove-service-from-whitelist


Resumes receiving notifications for network alerts that are set off by the specified triggers.

Base Command

shodan-network-alert-remove-service-from-whitelist

Input

Argument Name Description Required
alertID The ID of the alert for which to resume the specified services. Required
trigger The name of the trigger. Required
service The service specified in the “ip:port” format. For example, “1.1.1.1:80”. Required

Context Output

There is no context output for this command.

Command Example

!shodan-network-alert-remove-service-from-whitelist alertID="0EKRH38BBQEHTQ3E" trigger="any" service="1.1.1.1:80"

Human Readable Output

Removed service “1.1.1.1:80” for trigger any in alert 0EKRH38BBQEHTQ3E from the allow list

shodan-get-events


Retrieves events from Shodan.

Base Command

shodan-get-events

Input

Argument Name Description Required
should_push_events If set to ‘True’, the command will create events; otherwise, it will only display them. Possible values are: True, False. Default is False. Optional
start_date Fetch events created after this date. You can also use relative terms like “3 days ago”. Default is 3 days ago. Optional
max_fetch The maximum amount of events to return. Default is 50000. Optional

Context Output

There is no context output for this command.

Fetch Events

Fetch process returns a listing of all the network alerts that are currently active on the account.

To enable the Shodan integration you need to have an API key, which you can get for free by creating a Shodan account https://account.shodan.io/register
Once you have an API key, you insert it into the API Key field and click the Test button.

Rate Limits

All API plans are subject to a rate limit of 1 request per second - docs

Configuration parameters

  • credentials
  • api_key — API Key
  • api_url — Base url to Shodan API (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • integrationReliability — Source Reliability
  • feedExpirationPolicy
  • feedExpirationInterval
  • max_fetch — The maximum number of events per fetch

Commands (15)

  • ip

    Returns all services that have been found on the IP address of the searched host.

  • search

    Searches Shodan using facets to get summary information on properties.

  • shodan-create-network-alert

    Creates a network alert for a defined IP address or netblock used for subscribing to changes or events that are discovered within the netblock's range.

  • shodan-get-events

    Retrieves events from Shodan.

  • shodan-network-alert-remove-service-from-whitelist

    Resumes receiving notifications for network alerts that are set off by the specified triggers.

  • shodan-network-alert-remove-trigger

    Disables receiving notifications for network alerts that are set off by the specified triggers.

  • shodan-network-alert-set-trigger

    Enables receiving notifications for network alerts that are set off by the specified triggers.

  • shodan-network-alert-whitelist-service

    Ignores the specified services for network alerts that are set off by the specified triggers.

  • shodan-network-delete-alert

    Removes the specified network alert.

  • shodan-network-get-alert-by-id

    Gets the details of a network alert.

  • shodan-network-get-alerts

    Gets a list of all created network alerts.

  • shodan-scan-internet

    Requests for Shodan to perform a scan on the specified port and protocol.

  • shodan-scan-ip

    Requests Shodan to crawl a network.

  • shodan-scan-status

    Checks the progress of a previously submitted scan request on the specified port and protocol.

  • shodan-search-count

    Returns the total number of results that match only the specified query or facet settings. This command does not return host results. This command does not consume query credits.

import json
from datetime import datetime

import pytest
from pytest_mock import MockerFixture
import demistomock as demisto


def util_load_json(path):
    with open(path) as f:
        return json.loads(f.read())


with open("./test_data/response.json") as f:
    RESPONSE = json.load(f)


@pytest.fixture(autouse=True)
def mock_demisto_params(mocker: MockerFixture):
    """
    Automatically patches 'demistomock.params' for all test cases.
    """
    mocker.patch(
        "demistomock.params",
        return_value={
            "api_url": "https://api.shodan.io",
            "credentials": {"credential": "", "credentials": {}, "password": "123"},
            "max_fetch": "2",
        },
    )


def test_get_events_command(mocker: MockerFixture):
    from Shodan_v2 import get_events_command

    mock_http_request = mocker.patch("Shodan_v2.http_request", return_value=RESPONSE)
    _, events = get_events_command({"max_fetch": 2})

    assert len(events) == 2
    assert events[0]["name"] == "test_alert2"

    mock_http_request.assert_called_once_with("GET", "/shodan/alert/info")


def test_filter_events(mocker: MockerFixture):
    from Shodan_v2 import filter_events

    filtered_events = filter_events(events=RESPONSE, limit=3, last_run={"last_fetch_time": "2024-08-10T12:46:18.012000"})
    assert len(filtered_events) == 3
    assert filtered_events[0]["name"] == "test_alert2"


def test_format_record_keys():
    from Shodan_v2 import format_record_keys

    event = [{"column_name": "val1"}]
    hr = format_record_keys(event)

    assert hr == [{"Column Name": "val1"}]


def test_add_time_to_events():
    from Shodan_v2 import add_time_to_events

    add_time_to_events(RESPONSE)

    assert "_time" in RESPONSE[0]


def test_parse_event_date():
    from Shodan_v2 import parse_event_date

    created = parse_event_date(RESPONSE[0])
    assert isinstance(created, datetime)


def test_fetch_events(mocker):
    from Shodan_v2 import fetch_events

    mock_http_request = mocker.patch("Shodan_v2.http_request", return_value=RESPONSE)
    last_run, filtered_events = fetch_events({"last_fetch_time": "2024-08-10T12:46:18.012000"}, {"max_fetch": "2"})

    assert len(filtered_events) == 2
    assert last_run == {"last_fetch_time": "2024-08-12T08:46:18.012000", "last_event_ids": ["6789"]}
    mock_http_request.assert_called_once_with("GET", "/shodan/alert/info")


@pytest.mark.parametrize(
    "api_response_data, expected_demistoresults_args",
    [
        (
            util_load_json("./test_data/searchresults_NoSSL.json"),
            util_load_json("./test_data/expected_return_results_NoSSL.json"),
        ),
        (
            util_load_json("./test_data/searchresults_SSL_NoNTLM.json"),
            util_load_json("./test_data/expected_return_results_SSL_NoNTLM.json"),
        ),
        (
            util_load_json("./test_data/searchresults_SSL_WithNTLM.json"),
            util_load_json("./test_data/expected_return_results_SSL_WithNTLM.json"),
        ),
    ],
)
def test_search_command(api_response_data: dict, expected_demistoresults_args: dict, mocker: MockerFixture):
    """
    Test the search_command function.

    This test verifies that the search_command function correctly processes the API response
    and produces the expected demisto results. It mocks the necessary dependencies and
    compares the output with the expected results.

    Args:
        api_response_data (dict): The mocked API response data.
        expected_demistoresults_args (dict): The expected arguments for demisto.results.
        mocker (MockerFixture): Pytest fixture for mocking.

    The test checks various aspects of the results, including Type, Contents, ContentsFormat,
    HumanReadable, HumanReadableFormat, and EntryContext.
    """
    from Shodan_v2 import search_command

    mocker.patch.object(
        demisto, "args", return_value={"query": "port:3389 ip:10.2.3.4", "facets": "", "page": 1, "return_json": "No"}
    )
    mocker.patch("Shodan_v2.http_request", return_value=api_response_data)
    mock_results = mocker.patch("Shodan_v2.demisto.results", return_value=True)
    search_command()
    results_call_args = mock_results.call_args[0][0]
    assert results_call_args["Type"] == expected_demistoresults_args["Type"]
    assert results_call_args["Contents"] == expected_demistoresults_args["Contents"]
    assert results_call_args["ContentsFormat"] == expected_demistoresults_args["ContentsFormat"]
    assert results_call_args["HumanReadable"] == expected_demistoresults_args["HumanReadable"]
    assert results_call_args["HumanReadableFormat"] == expected_demistoresults_args["HumanReadableFormat"]
    assert results_call_args["EntryContext"] == expected_demistoresults_args["EntryContext"]