FullHunt
Cortex XSOAR integration with FullHunt.io API.
Data Enrichment & Threat Intelligence · FullHunt
Details
| ID | FullHunt |
|---|---|
| Provider | FullHunt |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.12.8.3296088 |
| Supported Modules | Agentix 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-domainGet details about one specified domain
-
fullhunt-get-account-statusGet information about the user account such as credit and usage
-
fullhunt-get-hostGet host details
-
fullhunt-get-subdomainGet 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()