QutteraWebsiteMalwareScanner

Quttera Website Malware Scanner.

Data Enrichment & Threat Intelligence · Quttera Website Malware Scanner

Details

IDQutteraWebsiteMalwareScanner
ProviderQuttera
CategoryData Enrichment & Threat Intelligence
From Version6.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix 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-malware

    Retrieve url blacklist and reputation.

  • quttera-rescan-status

    Retrieve status of submitted domain.

  • quttera-scan-report

    Retrieve report of submitted domain.

  • quttera-scan-start

    Start to scan a given domain.

  • quttera-status-blacklist

    Retrieve 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()