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 pytest from QutteraWebsiteMalwareScanner import report_malware, rescan_status, scan_report, scan_start, status_blacklist SERVER_URL = "scannerapi.quttera.com" HTTPS_BASE = f"https://{SERVER_URL}/api/v3" class ResponseMock: start_scan = {"error": 200, "errorstr": "success"} rescan_status = { "error": 200, "errorstr": "success", "status": { "blacklisted": "no", "files": 12, "scanner_result": "undef", "sensitivity": "HEURISTIC", "state": "SCAN", "time": 1653420189, "url": "domain.test", }, } scan_report_clean = { "error": 200, "errorstr": "success", "status": { "blacklisted": "no", "files": 16, "scanner_result": "clean", "sensitivity": "HEURISTIC", "state": "DONE", "time": 1670147717, "url": "domain.test", }, } scan_report_in_progress = { "error": 200, "errorstr": "success", "status": { "blacklisted": "no", "files": 16, "scanner_result": "clean", "sensitivity": "HEURISTIC", "state": "DOWNLOAD", "time": 1670147717, "url": "domain.test", }, } status_blacklist = {"error": 200, "errorstr": "success", "status": {"blacklisted": "no", "url": "domain.test"}} report_malware = { "error": 200, "errorstr": "success", "report": { "blacklist_report": { "blacklist_status": "NoThreat", "providers": [ {"name": "Google", "status": "NoThreat", "time": "1511222759"}, {"name": "Google", "status": "NoThreat", "time": "1511222759"}, {"name": "MalwareDomainList", "status": "NoThreat", "time": "1511222759"}, {"name": "ZeusTracker", "status": "NoThreat", "time": "1511222759"}, ], }, "blacklisted_domains": {}, "blacklisted_domains_count": 0, "blacklisted_iframes": {}, "blacklisted_iframes_count": 0, "blacklisted_links": {}, "blacklisted_links_count": 0, "domains": {"adssettings.google.com": "NoThreat", "domain.test": "NoThreat", "youtu.be": "NoThreat"}, "domains_count": 2, "files": [ { "MD5": "18912736AD1E68285BBD6087610FDBF7", "_severity": "clean", "details": "File is clean.", "dumpMD5": "00000000000000000000000000000000", "endtime": "Sun Dec 4 11:18:29 2022", "filename": "domain.test/website-anti-malware-monitoring", "filesize": "91356", "filetype": "HTML", "layer": "js-emulation-layer", "line": "0", "offset": "0", "pattern_id": "N/A", "reason": "No significant issues detected.", "result": "1", "scantime": "5.820000", "threat": "Clean", "threat_name": "Undefined", }, { "MD5": "91274D3E5EB68C1BABBD22B55C416698", "_severity": "clean", "details": "File is clean.", "dumpMD5": "00000000000000000000000000000000", "endtime": "Sun Dec 4 11:18:37 2022", "filename": "domain.test/affiliates", "filesize": "67062", "filetype": "HTML", "layer": "js-emulation-layer", "line": "0", "offset": "0", "pattern_id": "N/A", "reason": "No significant issues detected.", "result": "1", "scantime": "7.224000", "threat": "Clean", "threat_name": "Undefined", }, ], "http_timeout": 0.844234, "iframes": { '<iframe class%3D"embed-responsive-item">': "NoThreat", '<iframe width%3D"420" height%3D"315" >': "NoThreat", }, "iframes_count": 7, "links": { "http://docs.fortinet.com/document/fortisoar/1.0.0/quttera/404/quttera-v1-0-0": "NoThreat", "http://domain.test/...": "NoThreat", "https://youtu.be/zphj16hzj8g": "NoThreat", }, }, } class ClientMock: def __init__(self, params): self.mock_resp = params self.apikey = "1234" self.base_url = "api.quttera" def _api_request(self, domain: str, method: str, operation: str): return self.mock_resp @pytest.fixture(scope="function") def client(client_args): return ClientMock(client_args) @pytest.mark.parametrize("client_args", [ResponseMock.start_scan]) def test_start_scan(client): """ Given mock BaseClient and domain to scan When Calling the start scan Then Test the scan trigger response """ args = {"domain": "domain.test"} response = scan_start(client, args) assert response.outputs == ResponseMock.start_scan @pytest.mark.parametrize("client_args", [ResponseMock.rescan_status]) def test_rescan_status(client): """ Given mock BaseClient and domain to scan When Rescan the domain Then Test the scan trigger response """ args = {"domain": "domain.test"} response = rescan_status(client, args) assert response.outputs == ResponseMock.rescan_status @pytest.mark.parametrize("client_args", [ResponseMock.scan_report_clean]) def test_scan_status_clean(client): """ Given mock BaseClient and domain to scan When Retrieve status of scanned domain Then Test the scan status response """ args = {"domain": "domain.test"} response = scan_report(client, args) assert response.readable_output == "Domain domain.test is clean" @pytest.mark.parametrize("client_args", [ResponseMock.scan_report_in_progress]) def test_scan_status_in_progress(client): """ Given mock BaseClient and domain to scan When Retrieve status of scanned domain Then Test the scan status response """ args = {"domain": "domain.test"} response = scan_report(client, args) assert response.readable_output == "Domain domain.test is being scanned" @pytest.mark.parametrize("client_args", [ResponseMock.status_blacklist]) def test_blacklist_status(client): """ Given mock BaseClient and domain to scan When Retrieve the info about blacklist status of the domain Then Test the blacklist status response """ args = {"domain": "domain.test"} response = status_blacklist(client, args) assert response.readable_output == "Domain domain.test is NOT blacklisted" @pytest.mark.parametrize("client_args", [ResponseMock.report_malware]) def test_report_malware(client): """ Given mock BaseClient and domain to scan When Retrieve the malware report for given domain Then Test the malware status response """ args = {"url": "domain.test"} response = report_malware(client, args) assert response.outputs == ResponseMock.report_malware @pytest.mark.parametrize("client", [client]) @pytest.mark.parametrize("method", ["scan_start", "rescan_status", "scan_report", "status_blacklist"]) def test_valueerror(client, method): with pytest.raises(ValueError): globals()[method](client, {"domain": ""}) class Failure: response = {"error": 404, "errorstr": "item not found"} @pytest.mark.parametrize("client_args", [Failure.response]) @pytest.mark.parametrize("method", ["scan_start", "rescan_status"]) def test_failed_response(client, method): args = {"domain": "domain.test"} res = globals()[method](client, args) assert res.raw_response.get("errorstr") == "item not found" @pytest.mark.parametrize("client_args", [Failure.response]) @pytest.mark.parametrize("method", ["scan_report"]) def test_failed_scan_report(client, method): args = {"domain": "domain.test"} res = globals()[method](client, args) assert res.readable_output == "Domain domain.test was not scanned. Scan it with !quttera-scan-start domain=domain.test" class FailureBlacklist: response = {"error": 200, "errorstr": "success", "status": {"blacklisted": "no", "url": "domain.test"}} @pytest.mark.parametrize("client_args", [FailureBlacklist.response]) @pytest.mark.parametrize("method", ["status_blacklist"]) def test_failed_status_blacklist(client, method): args = {"domain": "domain.test"} res = globals()[method](client, args) assert res.readable_output == "Domain domain.test is NOT blacklisted"