FullHunt

Cortex XSOAR integration with FullHunt.io API.

Data Enrichment & Threat Intelligence · FullHunt

Details

IDFullHunt
ProviderFullHunt
CategoryData Enrichment & Threat Intelligence
From Version6.0.0
Docker Imagedemisto/python3:3.12.8.3296088
Supported ModulesAgentix XSIAM

README

FullHunt is the attack surface database of the entire Internet. FullHunt enables companies to discover all of their attack surfaces, monitor them for exposure, and continuously scan them for the latest security vulnerabilities. All, in a single platform, and more.

Configure FullHunt in Cortex

Parameter Required
Server URL True
API Key True
Trust any certificate (not secure) False
Use system proxy settings False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

fullhunt-get-account-status


Get information about the user account such as company, email, credit, and usage

Base Command

fullhunt-get-account-status

Input

None

Context Output

Path Type Description
FullHunt.UserInfo.user.company string Company name
FullHunt.UserInfo.user.email string Company email
FullHunt.UserInfo.user.first_name string First name
FullHunt.UserInfo.user.last_name string Last name
FullHunt.UserInfo.user.plan string Fullhunt plan
FullHunt.UserInfo.user_credits.credits_usage number Credits usage at the time of the request
FullHunt.UserInfo.user_credits.max_results_per_request number Maximum results per request
FullHunt.UserInfo.user_credits.remaining_credits number Remaining credits on the account for the current month
FullHunt.UserInfo.user_credits.total_credits_per_month number Total credits available per month

fullhunt-get-host


Get host details

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

Base Command

fullhunt-get-host

Input

Argument Name Description Required
host Host or list of hosts Required

Context Output

Path Type Description
FullHunt.Host.is_cloud boolean Whether the host is based on cloud technology or not
FullHunt.Host.network_ports array List of open ports
FullHunt.Host.is_live boolean Whether the host is live or not
FullHunt.Host.http_title string HTTP title
FullHunt.Host.http_status_code number HTTP status code
FullHunt.Host.domain string Domain
FullHunt.Host.ip_metadata.postal_code number Postal code related to the IP
FullHunt.Host.ip_metadata.location_longitude number Longitude coordinate of the IP
FullHunt.Host.ip_metadata.isp string Internet Service Provider of the IP
FullHunt.Host.ip_metadata.organization string Organization of the IP
FullHunt.Host.ip_metadata.country_name string Name of the country of the IP
FullHunt.Host.ip_metadata.region string Region of the IP
FullHunt.Host.ip_metadata.country_code string Two letters country code
FullHunt.Host.ip_metadata.location_latitude number Latitude coordinate of the IP
FullHunt.Host.ip_metadata.asn number Autonomous System Number
FullHunt.Host.ip_metadata.city_name string City name of the IP
FullHunt.Host.has_private_ip boolean Whether the host has a private IP listed
FullHunt.Host.is_resolvable boolean Whether the host is resolvable
FullHunt.Host.dns.a array List of DNS A entries
FullHunt.Host.dns.aaaa string DNS AAAA entry
FullHunt.Host.dns.cname array List of DNS CNAME entries
FullHunt.Host.dns.mx array List of DNS MX entries
FullHunt.Host.dns.ns array List of DNS NS entries
FullHunt.Host.dns.ptr string DNS PTR entry
FullHunt.Host.dns.txt string DNS TXT entry
FullHunt.Host.has_ipv6 boolean Whether the host has an IPv6 listed
FullHunt.Host.tld string Top Level Domain
FullHunt.Host.cdn string Content Delivery Network
FullHunt.Host.is_cloudflare boolean Whether host uses Cloudflare or not
FullHunt.Host.cloud.provider string Name of the cloud provider
FullHunt.Host.cloud.region string Region of the cloud provider
FullHunt.Host.is_cdn boolean Whether host uses CDN
FullHunt.Host.tags array Tags of the host
FullHunt.Host.ip_address string IP address of the host

domain


Get details about one specified domain

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

Base Command

fullhunt-domain

Input

Argument Name Description Required
domain One domain to check Required

Context Output

Path Type Description
FullHunt.Domain.domain string Domain
FullHunt.Domain.hosts array List of hosts with same details as running the command “fullhunt-get-host”
FullHunt.Domain.message string Message
FullHunt.Domain.metadata.all_results_count number Number of results for this API request
FullHunt.Domain.metadata.available_results_for_user number Number of results available for the user performing the API request
FullHunt.Domain.metadata.domain string Domain
FullHunt.Domain.metadata.last_scanned number Epoch timestamp of the domain last scan
FullHunt.Domain.metadata.max_results_for_user number Maximum results for the user
FullHunt.Domain.metadata.timestamp number Epoch timestamp of the API request
FullHunt.Domain.metadata.user_plan string Fullhunt plan
FullHunt.Domain.status number HTTP status code

fullhunt-get-subdomain


Get all subdomains from a given domain

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

Base Command

fullhunt-get-subdomain

Input

Argument Name Description Required
domain Enter the domain from which you want to enumerate subdomains. Required

Context Output

Path Type Description
FullHunt.Subdomain.domain string Domain
FullHunt.Subdomain.hosts array List of subdomains
FullHunt.Subdomain.message string Message
FullHunt.Subdomain.metadata.all_results_count number Number of results for this API request
FullHunt.Subdomain.metadata.available_results_for_user number Number of results available for the user performing the API request
FullHunt.Subdomain.metadata.domain string Domain
FullHunt.Subdomain.metadata.last_scanned number Epoch timestamp of the domain last scan
FullHunt.Subdomain.metadata.max_results_for_user number Maximum results for the user
FullHunt.Subdomain.metadata.timestamp number Epoch timestamp of the API request
FullHunt.Subdomain.metadata.user_plan string Fullhunt plan
FullHunt.Subdomain.status number HTTP status code

Configuration parameters

  • url — Server URL (required)
  • credentials — (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (4)

  • fullhunt-domain

    Get details about one specified domain

  • fullhunt-get-account-status

    Get information about the user account such as credit and usage

  • fullhunt-get-host

    Get host details

  • fullhunt-get-subdomain

    Get all subdomains from a given domain

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

"""
FullHunt.io API integration
"""

""" IMPORTS """


""" CONSTANTS """

DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"

""" CLIENT CLASS """


class Client(BaseClient):
    """Client class to interact with the service API
    This Client implements API calls, and does not contain any Demisto logic.
    Should only do requests and return data.
    It inherits from BaseClient defined in CommonServer Python.
    Most calls use _http_request() that handles proxy, SSL verification, etc.
    For this HelloWorld implementation, no special attributes defined
    """

    def get_account_status(self) -> dict:
        """
        Get the account status with email, credits, etc. with the /auth/status API endpoint.
        """
        return self._http_request(
            method="GET",
            url_suffix="/auth/status",
        )

    def get_host(self, host: str) -> Dict[str, Any]:
        """
        Gets the host details using the '/host' API endpoint.

        """

        return self._http_request(method="GET", url_suffix=f"/host/{host}")

    def get_domain_details(self, domain: str) -> Dict[str, Any]:
        """
        Get domain details using the '/domain/<domain>/details' API endpoint

        """

        return self._http_request(method="GET", url_suffix=f"/domain/{domain}/details")

    def get_subdomain(self, domain: str) -> Dict[str, Any]:
        """
        Get all subdomains from a given domain using the '/domain/<domain>/subdomains' API endpoint

        """

        return self._http_request(method="GET", url_suffix=f"/domain/{domain}/subdomains")


""" STANDALONE FUNCTION """


""" COMMAND FUNCTION """


def test_module(client: Client, params: Dict[str, Any]) -> str:
    """
    Tests API connectivity and authentication by using the get_account_status() function
    """

    try:
        client.get_account_status()
        return "ok"

    except DemistoException as e:
        if "Unauthorized" in str(e):
            return "Authorization error 401: Probably the API key is not set correctly"
        else:
            raise e


def get_account_status_command(client: Client, params: Dict[str, Any]) -> CommandResults:
    """
    Get the information about the user and user credit
    """
    try:
        response = client.get_account_status()
        user_info = tableToMarkdown("User Info", response.get("user", ""))
        credit_info = tableToMarkdown("Credit Info", response.get("user_credits", ""))
        readable_output = f"{user_info}\n{credit_info}"

        return CommandResults(
            outputs_prefix="FullHunt.UserInfo", outputs_key_field="", outputs=response, readable_output=readable_output
        )

    except DemistoException as e:
        raise e


def get_host_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]:
    hosts = argToList(args.get("host"))
    if len(hosts) == 0:
        raise ValueError("host(s) not specified")

    command_results: List[CommandResults] = []

    for host in hosts:
        host_data = client.get_host(host)
        host_data["host"] = host

        readable_output = tableToMarkdown("Domain", host_data)

        command_results.append(
            CommandResults(
                readable_output=readable_output, outputs_prefix="FullHunt.Host", outputs_key_field="host", outputs=host_data
            )
        )

    return command_results


def get_domain_command(client: Client, args: Dict[str, Any]) -> CommandResults:
    domain = args.get("domain")
    if not domain:
        raise ValueError("domain not specified")
    elif "," in domain:
        raise ValueError("Several domains provided, please provide one unique domain")

    domain_data = client.get_domain_details(domain)

    readable_output = tableToMarkdown("Domain information", domain_data)

    return CommandResults(
        outputs_prefix="FullHunt.Domain", outputs_key_field="", outputs=domain_data, readable_output=readable_output
    )


def get_subdomain_command(client: Client, args: Dict[str, Any]) -> CommandResults:
    domain = args.get("domain")
    if not domain:
        raise ValueError("domain not specified")
    elif "," in domain:
        raise ValueError("Several domains provided, please provide one unique domain")

    subdomain_data = client.get_subdomain(domain)

    readable_output = tableToMarkdown("Subdomains information", subdomain_data)

    return CommandResults(
        outputs_prefix="FullHunt.Subdomain", outputs_key_field="", outputs=subdomain_data, readable_output=readable_output
    )


""" MAIN FUNCTION """


def main() -> None:
    """
    main function, parses params and runs command functions
    """

    params = demisto.params()
    args = demisto.args()
    command = demisto.command()

    api_key = params.get("credentials", {}).get("password")

    # Get the service API url
    base_url = urljoin(params.get("url"), "/api/v1")

    # if your Client class inherits from BaseClient, SSL verification is
    # handled out of the box by it, just pass ``verify_certificate`` to
    # the Client constructor
    verify_certificate = not params.get("insecure", False)

    # if your Client class inherits from BaseClient, system proxy is handled
    # out of the box by it, just pass ``proxy`` to the Client constructor
    proxy = params.get("proxy", False)

    demisto.debug(f"Command being called is {command}")
    try:
        headers = {"X-API-KEY": f"{api_key}"}
        client = Client(
            base_url=base_url, verify=verify_certificate, headers=headers, proxy=handle_proxy("proxy", proxy).get("http", "")
        )

        if command == "test-module":
            # This is the call made when pressing the integration Test button.
            return_results(test_module(client, params))

        elif command == "fullhunt-get-account-status":
            # Get user account information and credit.
            return_results(get_account_status_command(client, params))

        elif command == "fullhunt-get-host":
            # Get host details
            return_results(get_host_command(client, args))

        elif command == "fullhunt-get-subdomain":
            # Get subdomain from a given domain
            return_results(get_subdomain_command(client, args))

        elif command == "fullhunt-domain":
            # Get details about the specified domain
            return_results(get_domain_command(client, args))

        else:
            raise NotImplementedError(f"Command {command} is not implemented")

    # Log exceptions and return errors
    except Exception as e:
        return_error(f"Failed to execute {command} command.\nError:\n{e!s}")


""" ENTRY POINT """

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