From e44654193cd25f4478adf1cdcbdc79b1017cb103 Mon Sep 17 00:00:00 2001 From: Karan Deep Date: Fri, 10 Jan 2025 17:42:40 +0530 Subject: [PATCH] implemented search-domain command --- .../Integrations/SilentPush/SilentPush.py | 73 +++++- .../Integrations/SilentPush/SilentPush.yml | 231 ++++++++---------- 2 files changed, 169 insertions(+), 135 deletions(-) diff --git a/Packs/SilentPush/Integrations/SilentPush/SilentPush.py b/Packs/SilentPush/Integrations/SilentPush/SilentPush.py index f71c8c6657a9..ba417b681c26 100644 --- a/Packs/SilentPush/Integrations/SilentPush/SilentPush.py +++ b/Packs/SilentPush/Integrations/SilentPush/SilentPush.py @@ -13,7 +13,7 @@ import requests import urllib3 -from typing import Any +from typing import Any, Optional, Dict # Disable insecure warnings urllib3.disable_warnings() @@ -134,6 +134,42 @@ def get_domain_certificates(self, domain: str) -> dict: url_suffix = f'explore/domain/certificates/{domain}' return self._http_request('GET', url_suffix) + def search_domains(self, + query: Optional[str] = None, + start_date: Optional[str] = None, + end_date: Optional[str] = None, + risk_score_min: Optional[int] = None, + risk_score_max: Optional[int] = None, + limit: int = 100) -> dict: + """ + Search for domains with optional filters. + + Args: + query (str, optional): Search query string (e.g., domain pattern, keywords) + start_date (str, optional): Start date for domain registration (ISO8601 format) + end_date (str, optional): End date for domain registration (ISO8601 format) + risk_score_min (int, optional): Minimum risk score filter + risk_score_max (int, optional): Maximum risk score filter + limit (int, optional): Maximum number of results to return (default: 100) + + Returns: + dict: A dictionary containing the search results + """ + demisto.debug(f'Searching domains with query: {query}') + url_suffix = 'explore/domain/search' + + # Build parameters dictionary with only non-None values + params = {k: v for k, v in { + 'query': query, + 'start_date': start_date, + 'end_date': end_date, + 'risk_score_min': risk_score_min, + 'risk_score_max': risk_score_max, + 'limit': limit + }.items() if v is not None} + + return self._http_request('GET', url_suffix, params=params) + def test_module(client: Client) -> str: """ @@ -218,6 +254,38 @@ def get_domain_certificates_command(client: Client, args: dict) -> CommandResult ) +def search_domains_command(client: Client, args: dict) -> CommandResults: + + # Extract parameters from args with type conversion + query = args.get('query') + start_date = args.get('start_date') + end_date = args.get('end_date') + risk_score_min = arg_to_number(args.get('risk_score_min')) + risk_score_max = arg_to_number(args.get('risk_score_max')) + limit = arg_to_number(args.get('limit', 100)) + + demisto.debug(f'Searching domains with query: {query}') + + raw_response = client.search_domains( + query=query, + start_date=start_date, + end_date=end_date, + risk_score_min=risk_score_min, + risk_score_max=risk_score_max, + limit=limit + ) + + readable_output = tableToMarkdown('Domain Search Results', raw_response.get('results', [])) + + return CommandResults( + outputs_prefix='SilentPush.SearchResults', + outputs_key_field='domain', + outputs=raw_response, + readable_output=readable_output, + raw_response=raw_response + ) + + ''' MAIN FUNCTION ''' @@ -257,6 +325,7 @@ def main(): 'test-module': test_module, 'silentpush-list-domain-information': list_domain_information_command, 'silentpush-get-domain-certificates': get_domain_certificates_command, + 'silentpush-search-domains': search_domains_command, } if command in command_handlers: @@ -277,4 +346,4 @@ def main(): if __name__ in ('__main__', '__builtin__', 'builtins'): - main() + main() \ No newline at end of file diff --git a/Packs/SilentPush/Integrations/SilentPush/SilentPush.yml b/Packs/SilentPush/Integrations/SilentPush/SilentPush.yml index 375bbb45fadd..fbf62f668863 100644 --- a/Packs/SilentPush/Integrations/SilentPush/SilentPush.yml +++ b/Packs/SilentPush/Integrations/SilentPush/SilentPush.yml @@ -1,139 +1,104 @@ commonfields: id: SilentPush - version: -1 - name: SilentPush - type: python - subType: python3 - description: | - This integration allows fetching domain information from the SilentPush API. It includes commands to get domain-related information such as WHOIS data, domain age, and risk scores, as well as SSL/TLS certificate data. - tags: [] - enabled: true - manufacturer: SilentPush - comment: '' - minVersion: -1 - dependencies: - - CommonServerPython - - CommonServerUserPython - -scripts: - - path: SilentPush.py - comment: | - Integration for SilentPush that enables fetching domain information, including WHOIS data, domain age, risk scores, and certificates. - -commands: - - name: test-module - description: | - Tests the connectivity to the SilentPush API and checks the authentication status. - isArray: false - argContext: - - id: base_url - type: string - description: The base URL for the SilentPush API. - - id: api_key - type: string - description: The API key used to authenticate requests. - - id: verify_ssl - type: boolean - description: Flag to determine whether SSL verification is enabled. - examples: | - !test-module - - - name: silentpush-list-domain-information - description: | - Fetches domain information, such as WHOIS data, domain age, and risk scores. - isArray: false - argContext: - - id: domain - type: string - description: The domain name to fetch information for. - examples: | - !silentpush-list-domain-information domain=example.com - - - name: silentpush-get-domain-certificates - description: | - Fetches SSL/TLS certificate data for a given domain. - isArray: false - argContext: - - id: domain - type: string - description: The domain to fetch certificate information for. - examples: | - !silentpush-get-domain-certificates domain=example.com + version: 1.0.0 -args: - - id: domain - isArray: false - description: | - The domain to fetch information for. - type: string +name: SilentPush +display: SilentPush +category: Data Enrichment & Threat Intelligence +description: Integration with SilentPush API for domain intelligence and analysis. +configuration: + - display: Server URL + name: url + defaultvalue: https://api.silentpush.com + type: 0 + required: true + + - display: API Key + name: credentials + type: 9 + required: true + + - display: Trust any certificate (not secure) + name: insecure + type: 8 + required: false + + - display: Use system proxy settings + name: proxy + type: 8 + required: false -outputs: - - id: SilentPush.Domain - type: complex - description: | - The domain information fetched from SilentPush API, including WHOIS data, domain age, and risk scores. - contents: - - name: domain - type: string - - name: whois_data - type: string - - name: domain_age - type: integer - - name: risk_score - type: float - - - id: SilentPush.Certificates - type: complex - description: | - The certificate information fetched from SilentPush API for the domain. - contents: - - name: domain - type: string - - name: certificates - type: list - items: - - name: certificate_issuer - type: string - - name: valid_from - type: string - - name: valid_to - type: string - - name: certificate_serial_number - type: string +script: + script: '' + type: python + commands: + - name: silentpush-list-domain-information + description: Fetches domain information such as WHOIS data, domain age, and risk scores + arguments: + - name: domain + description: The domain to fetch information for + required: true + default: false + outputs: + - contextPath: SilentPush.Domain + description: Domain information retrieved from SilentPush + type: unknown + - contextPath: SilentPush.Domain.domain + description: The domain name + type: string + + - name: silentpush-get-domain-certificates + description: Fetches SSL/TLS certificate data for a given domain + arguments: + - name: domain + description: The domain to fetch certificate information for + required: true + default: false + outputs: + - contextPath: SilentPush.Certificates + description: Certificate information for the domain + type: unknown + - contextPath: SilentPush.Certificates.domain + description: The domain name + type: string + + - name: silentpush-search-domains + description: Search for domains with optional filters + arguments: + - name: query + description: Search query string (e.g., domain pattern, keywords) + required: false + default: false + - name: start_date + description: Start date for domain registration (ISO8601 format) + required: false + default: false + - name: end_date + description: End date for domain registration (ISO8601 format) + required: false + default: false + - name: risk_score_min + description: Minimum risk score filter + required: false + default: false + - name: risk_score_max + description: Maximum risk score filter + required: false + default: false + - name: limit + description: Maximum number of results to return + required: false + default: true + defaultValue: "100" + outputs: + - contextPath: SilentPush.SearchResults + description: Search results from the domain query + type: unknown + - contextPath: SilentPush.SearchResults.domain + description: The domain name in the search results + type: string +dockerimage: demisto/python3:3.10 +fromversion: 6.0.0 tests: - - name: Test SilentPush Integration - description: Test the integration with the SilentPush API. - steps: - - script: test-module - name: Test SilentPush API Connectivity - args: - base_url: https://api.silentpush.com - api_key: 'your_api_key' - - -configurations: - - default: true - isArray: false - description: The configuration parameters required for connecting to SilentPush API. - context: - - id: base_url - type: string - description: The base URL for the SilentPush API. - - id: api_key - type: string - description: The API key used to authenticate requests. - - id: verify_ssl - type: boolean - description: Flag to determine whether SSL verification is enabled. - - id: proxy - type: boolean - description: Flag to determine whether to use a proxy. - -errorHandling: - - errorCode: 403 - description: | - If an authorization error is encountered, it could indicate an incorrect or expired API key. - - errorCode: 400 - description: | - Bad Request error, likely due to incorrect input format or invalid parameters in the request. + - No tests \ No newline at end of file