QutteraWebsiteMalwareScanner
Quttera Website Malware Scanner.
Data Enrichment & Threat Intelligence · Quttera Website Malware Scanner
Details
| ID | QutteraWebsiteMalwareScanner |
|---|---|
| Provider | Quttera |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Quttera Website Malware Scanner
This integration was integrated and tested with version v3 of QutteraWebsiteMalwareScanner
Configure QutteraWebsiteMalwareScanner in Cortex
| Parameter | Required |
|---|---|
| API Key | True |
| Quttera Scanner URL | True |
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.
quttera-scan-start
Start to scan 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
quttera-scan-start
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | The name of the domain to scan. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| QutteraWebsiteMalwareScanning.Start.error | Number | HTTP response from the scanner |
| QutteraWebsiteMalwareScanning.Start.errorstr | String | Status of the scan request |
quttera-rescan-status
Retrieve status of submitted domain
Base Command
quttera-rescan-status
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | The name of the domain to retrieve its status. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| QutteraWebsiteMalwareScanning.Status.error | Number | Scan result request status |
| QutteraWebsiteMalwareScanning.Status.errorstr | String | Scan result request description |
| QutteraWebsiteMalwareScanning.Status.status.blacklisted | String | Is the domain blacklisted |
| QutteraWebsiteMalwareScanning.Status.status.files | Number | Amount of scanned files |
| QutteraWebsiteMalwareScanning.Status.status.scanner_result | String | Scan result |
| QutteraWebsiteMalwareScanning.Status.status.sensitivity | String | Sensitivity |
| QutteraWebsiteMalwareScanning.Status.status.state | String | Is scanning done |
| QutteraWebsiteMalwareScanning.Status.status.time | String | Time |
| QutteraWebsiteMalwareScanning.Status.status.url | String | Scanned URL |
quttera-scan-report
Retrieve report of submitted domain
Base Command
quttera-scan-report
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | The name of the domain to retrieve its report. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| QutteraWebsiteMalwareScanning.report.error | Number | Retrieving domain scan return code |
| QutteraWebsiteMalwareScanning.report.errorstr | String | Retrieving domain scan report state |
| QutteraWebsiteMalwareScanning.report.status | Dict | Detailed domain scan report |
| QutteraWebsiteMalwareScanning.report.status.blacklisted | String | Is domain blacklisted |
| QutteraWebsiteMalwareScanning.report.status.files | Number | How many files were scanned |
| QutteraWebsiteMalwareScanning.report.status.scanner_result | String | Scanner result |
| QutteraWebsiteMalwareScanning.report.status.sensitivity | String | Domain sensitivity |
| QutteraWebsiteMalwareScanning.report.status.state | String | State of the domain |
| QutteraWebsiteMalwareScanning.report.status.time | String | Scan time |
| QutteraWebsiteMalwareScanning.report.status.url | String | Scanned URL |
quttera-report-malware
Retrieve url blacklist and reputation
Notice: Submitting indicators using this command might make the indicator data publicly available. See the vendor’s documentation for more details.
Base Command
quttera-report-malware
Input
| Argument Name | Description | Required |
|---|---|---|
| url | URL to retrieve its blacklist and reputation. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| QutteraWebsiteMalwareScanning.report | Dict | Retrieving url blacklist and reputation |
quttera-status-blacklist
Retrieve domain blacklist and reputation
Base Command
quttera-status-blacklist
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | The name of the domain to retrieve its blacklist and reputation. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| QutteraWebsiteMalwareScanning.report | Dict | Retrieving domain blacklist and reputation |
Configuration parameters
apikey— API Key (required)base_url— Quttera Scanner URL (required)
Commands (5)
-
quttera-report-malwareRetrieve url blacklist and reputation.
-
quttera-rescan-statusRetrieve status of submitted domain.
-
quttera-scan-reportRetrieve report of submitted domain.
-
quttera-scan-startStart to scan a given domain.
-
quttera-status-blacklistRetrieve domain blacklist and reputation.
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 """QutteraWebsiteMalwareScanner Integration for Cortex XSOAR (aka Demisto) """ import urllib3 # Disable insecure warnings urllib3.disable_warnings() """ CONSTANTS """ DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ" class Client(BaseClient): """Client class for basic interaction with Quttera API.""" def __init__(self, params): self.apikey = params["apikey"] self.base_url = params["base_url"] super().__init__(base_url=self.base_url) def _api_request(self, domain: str, method: str, operation: str) -> Dict: """Start domain scanning :type domain: ``str`` :param domain: Domain to scan :return: dict containing response from api request :rtype: ``Dict`` """ operations = { "scan": f"/api/v3/{self.apikey}/url/scan", "rescan": f"/api/v3/{self.apikey}/url/scan", "statscan": f"/api/v3/{self.apikey}/url/status", "malware": f"/api/v3/{self.apikey}/url/report", "blacklist": f"/api/v3/{self.apikey}/blacklist/status", } op = operations[operation] return self._http_request(method=method, url_suffix=f"{op}/{domain}", ok_codes=(200, 404)) def _test_module(self): return self._http_request(method="GET", url_suffix=f"/api/v3/{self.apikey}/status") def scan_start(client: Client, args: dict) -> CommandResults: """ quttera-scan-start command: Scan a domain/website for malware and blacklist. :type client: ``Client`e :param Client: Qutter API client :type args: ``Dict[str, Any]`` :param args: all command arguments from ``demisto.args()`` :return: ``CommandResults`` object contain the start scan response :rtype: ``CommandResults`` """ domain = args.get("domain") if not domain: raise ValueError("domain is missing") start = client._api_request(domain=domain, method="POST", operation="scan") demisto.info(f"Start output {start}") readable_output = f"Started scan of {domain}. Run !quttera-report-malware to see the results." if start.get("errorstr") != "success": readable_output = f"Failed to scan domain {domain}" return CommandResults( readable_output=readable_output, outputs_prefix="QutteraWebsiteMalwareScanning.Start", outputs_key_field="error", outputs=start, ) def rescan_status(client: Client, args: dict) -> CommandResults: """ Retrieves scan status for previously submitted domain name or URL. """ domain = args.get("domain") if not domain: raise ValueError("domain is missing") rescan = client._api_request(domain=domain, method="PUT", operation="rescan") readable_output = f"Rescan of {domain}" return CommandResults( readable_output=readable_output, outputs_prefix="QutteraWebsiteMalwareScanning.Status", outputs_key_field="error", outputs=rescan, ) def scan_report(client: Client, args: dict) -> CommandResults: """ Retrieves scan report for previously submitted domain or URL in context or as a File (default) """ domain = args.get("domain") if not domain: raise ValueError("domain is missing") readable_output = "No output" report = client._api_request(domain=domain, method="GET", operation="statscan") state = None try: state = report["status"]["state"] states = ["NEW", "DOWNLOAD", "DOWNLOADED", "SCAN"] if state in states: readable_output = f"Domain {domain} is being scanned" else: status = report["status"]["scanner_result"] readable_output = f"Domain {domain} is {status}" except KeyError: readable_output = f"Domain {domain} was not scanned. Scan it with !quttera-scan-start domain={domain}" return CommandResults( readable_output=readable_output, outputs_prefix="QutteraWebsiteMalwareScanning.report", outputs_key_field="error" ) def report_malware(client: Client, args: dict) -> CommandResults: """ Returns malware status for given url """ url = args.get("url") if not url: raise ValueError("url is missing") scanned_files = None state = None full_report = None malware = client._api_request(domain=url, method="GET", operation="malware") apikey = client.apikey base_url = client.base_url try: scanned_files = malware["report"]["scanned_files"] state = malware["report"]["state"] headers = ("url", "status", "files", "full_report") full_report = (f"{base_url}/api/v3/{apikey}/url/report/{url}",) malware_data = {"url": url, "status": state, "files": scanned_files, "full_report": full_report} readable_output = tableToMarkdown( "Malware report", malware_data, headers=headers, headerTransform=string_to_table_header, ) except KeyError: readable_output = f"Report is not ready or domain {url} was not scanned yet" return CommandResults( readable_output=readable_output, outputs_prefix="QutteraWebsiteMalwareScanning.malware", outputs_key_field="error", outputs=malware, ) def status_blacklist(client: Client, args: dict) -> CommandResults: """ Returns url blacklisting information and reputation. """ domain = args.get("domain") if not domain: raise ValueError("domain is missing") blacklist = client._api_request(domain=domain, method="GET", operation="blacklist") readable_output = f"Domain {domain} is NOT blacklisted" if blacklist["status"]["blacklisted"] == "yes": readable_output = f"Domain {domain} is blacklisted" return CommandResults( readable_output=readable_output, outputs_prefix="", outputs_key_field="QutteraWebsiteMalwareScanning.report", ) def test_module(client: Client): """Performs basic request to ensure API server is running Return True if request succeeded """ resp = client._test_module() if resp.get("errorstr") == "success": return "ok" raise DemistoException(f"Service is down: ${resp}") def main(): # pragma: no cover """main function, parses params and runs command functions""" params = demisto.params() args = demisto.args() command = demisto.command() demisto.info(f"Command called {command}") demisto.info(f"Args are {args}") client = Client(params) try: if command == "quttera-scan-start": results = scan_start(client, args) elif command == "quttera-rescan-status": results = rescan_status(client, args) elif command == "quttera-scan-report": results = scan_report(client, args) elif command == "quttera-report-malware": results = report_malware(client, args) elif command == "quttera-status-blacklist": results = status_blacklist(client, args) elif command == "test-module": results = test_module(client) else: raise ValueError(f"Command {command} is not implemented in this integration") return_results(results) except Exception as e: return_error(f"Failed to execute {command} command.\nError:\n{e!s}") if __name__ in ("__main__", "__builtin__", "builtins"): main()