PolySwarmV2
Real-time threat intelligence from a crowd-sourced network of security experts and antivirus companies.
Data Enrichment & Threat Intelligence · PolySwarm
Details
| ID | PolySwarmV2 |
|---|---|
| Provider | PolySwarm |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.0.0 |
| Docker Image | demisto/polyswarm:1.0.0.6911470 |
| Supported Modules | Agentix XSIAM |
README
Real-time threat intelligence from a crowd-sourced network of security experts and antivirus companies.
Configure PolySwarmV2 in Cortex
| Parameter | Description | Required |
|---|---|---|
| PolySwarm API Key | True | |
| The base URL to connect to | True | |
| PolySwarm v2 Community | the segment of PolySwarm’s marketplace to query on. | 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.
polyswarm-get-report
Returns a report using the UUID.
Base Command
polyswarm-get-report
Input
| Argument Name | Description | Required |
|---|---|---|
| scan_uuid | UUID string. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| PolySwarm.Total | Number | The total number of scans. |
| PolySwarm.Permalink | String | PolySwarm permalink results. |
| PolySwarm.Positives | Number | The total number of positives found. |
| PolySwarm.Scan_UUID | String | The PolySwarm scan UUID. |
| PolySwarm.Artifact | String | The artifact queried. |
Command Example
!polyswarm-get-report scan_uuid="25e755c8957163376b3437ce808843c1c2598e0fb3c5f31dc958576cd5cde63e"
!polyswarm-get-report scan_uuid="25e755c8957163376b3437ce808843c1c2598e0fb3c5f31dc958576cd5cde63e, 2410907a92b16dbd23a88d6bbd5037eae20eea809279f370293b587e1996eafe"
Human Readable Output
file
Queries PolySwarm for file reputation information.
Base Command
file
Input
| Argument Name | Description | Required |
|---|---|---|
| hash | The value of the file hash for which to retrieve the reputation information. The hash type can be: “SHA256”, “SHA1”, or “MD5”. | Optional |
| file | The type of the file hash for which to retrieve the reputation information. The hash type can be: “SHA256”, “SHA1”, or “MD5”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| PolySwarm.Total | Number | The total number of scans. |
| PolySwarm.Permalink | String | PolySwarm permalink results. |
| PolySwarm.Positives | Number | The total number of positives found. |
| PolySwarm.Scan_UUID | String | The PolySwarm scan UUID. |
| PolySwarm.Artifact | String | The artifact queried. |
| DBotScore.Indicator | The indicator that was tested. | String |
| DBotScore.Score | The actual score. | Number |
| DBotScore.Type | The type of indicator. | String |
| DBotScore.Vendor | The vendor used to calculate the score. | String |
| DBotScore.Reliability | Reliability of the source providing the intelligence data. | String |
| File.MD5 | The MD5 hash of the file. | String |
| File.SHA256 | The SHA256 hash of the file. | String |
| File.SHA1 | The SHA1 hash of the file. | String |
Command Example
!file hash="2410907a92b16dbd23a88d6bbd5037eae20eea809279f370293b587e1996eafe"
!file hash="2410907a92b16dbd23a88d6bbd5037eae20eea809279f370293b587e1996eafe, 1d4c0b32aea68056755daf70689699200ffa09688495ccd65a0907cade18bd2a"
Human Readable Output
ip
Queries PolySwarm for IP reputation information.
Base Command
ip
Input
| Argument Name | Description | Required |
|---|---|---|
| ip | The IP address for which to retrieve the reputation information. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| PolySwarm.Total | Number | The total number of scans. |
| PolySwarm.Permalink | String | PolySwarm permalink results. |
| PolySwarm.Positives | Number | The total number of positives found. |
| PolySwarm.Scan_UUID | String | The PolySwarm scan UUID. |
| PolySwarm.Artifact | String | The artifact queried. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Indicator | String | The indicator that was tested. |
| IP.Address | String | The IP address. |
| IP.Malicious.Vendor | String | For malicious files, the vendor that made the decision. |
| IP.MalwareFamily | String | The malware family associated with the IP. |
| IP.Tags | String | Tags that are associated with the IP. |
Command Example
!ip ip="8.8.8.8"
url
Queries PolySwarm for URL reputation information.
Notice: Submitting indicators using this command might make the indicator data publicly available. See the vendor’s documentation for more details.
Base Command
url
Input
| Argument Name | Description | Required |
|---|---|---|
| url | The URL for which to retrieve the reputation information. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| PolySwarm.Total | Number | The total number of scans. |
| PolySwarm.Permalink | String | PolySwarm permalink results. |
| PolySwarm.Positives | Number | The total number of positives found. |
| PolySwarm.Scan_UUID | String | The PolySwarm scan UUID. |
| PolySwarm.Artifact | String | The artifact queried. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Indicator | String | The indicator that was tested. |
| URL.Data | String | The URL address. |
| URL.Malicious.Vendor | String | For malicious files, the vendor that made the decision. |
| URL.MalwareFamily | String | The malware family associated with the url. |
| URL.Tags | String | Tags that are associated with the url. |
Command Example
!url url="https://polyswarm.io"
Context Example
Human Readable Output
domain
Queries PolySwarm to retrieve domain reputation information.
Notice: Submitting indicators using this command might make the indicator data publicly available. See the vendor’s documentation for more details.
Base Command
domain
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | Domain for which to retrieve the reputation information. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| PolySwarm.Total | Number | The total number of scans. |
| PolySwarm.Permalink | String | PolySwarm permalink results. |
| PolySwarm.Positives | Number | The total number of positives found. |
| PolySwarm.Scan_UUID | String | The PolySwarm scan UUID. |
| PolySwarm.Artifact | String | The artifact queried. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Indicator | String | The indicator that was tested. |
| Domain.Name | String | The domain name, for example: “google.com”. |
| Domain.Malicious.Vendor | String | For malicious files, the vendor that made the decision. |
| Domain.MalwareFamily | String | The malware family associated with the domain. |
| Domain.Tags | String | Tags that are associated with the domain. |
Command Example
!domain domain="polyswarm.io"
Context Example
Human Readable Output
url-scan
Uploads a URL to PolySwarm and retrieves the analysis results.
Notice: Submitting indicators using this command might make the indicator data publicly available. See the vendor’s documentation for more details.
Base Command
url-scan
Input
| Argument Name | Description | Required |
|---|---|---|
| url | The URL to scan. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| PolySwarm.Total | Number | The total number of scans. |
| PolySwarm.Permalink | String | PolySwarm permalink results. |
| PolySwarm.Positives | Number | The total number of positives found. |
| PolySwarm.Scan_UUID | String | The PolySwarm scan UUID. |
| PolySwarm.Artifact | String | The artifact queried. |
Command Example
!url-scan url="https://polyswarm.io"
!url-scan url="https://polyswarm.io, https://polyswarm.network"
Human Readable Output
file-rescan
Rescans the uploaded artifact by hash.
Base Command
file-rescan
Input
| Argument Name | Description | Required |
|---|---|---|
| hash | The type of the file hash to rescan. The hash type can be: “SHA256”, “SHA1”, or “MD5”. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| PolySwarm.Total | Number | The total number of scans. |
| PolySwarm.Permalink | String | PolySwarm permalink results. |
| PolySwarm.Positives | Number | The total number of positives found. |
| PolySwarm.Scan_UUID | String | The PolySwarm scan UUID. |
| PolySwarm.Artifact | String | The artifact queried. |
Command Example
!file-rescan hash="2410907a92b16dbd23a88d6bbd5037eae20eea809279f370293b587e1996eafe"
!file-rescan hash="2410907a92b16dbd23a88d6bbd5037eae20eea809279f370293b587e1996eafe, 25e755c8957163376b3437ce808843c1c2598e0fb3c5f31dc958576cd5cde63e"
Human Readable Output
get-file
Downloads a file hash from PolySwarm.
Base Command
get-file
Input
| Argument Name | Description | Required |
|---|---|---|
| hash | The file hash type to download. The hash type can be: “SHA256”, “SHA1”, or “MD5”. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| File.Size | Number | The file size. |
| File.SHA1 | String | The SHA1 hash of the file. |
| File.SHA256 | String | The SHA256 hash of the file. |
| File.Name | String | The sample name. |
| File.SSDeep | String | The SSDeep hash of the file. |
| File.EntryID | String | The War Room entry ID of the file. |
| File.Info | String | Basic information of the file. |
| File.Type | String | File type. For example, “PE”. |
| File MD5 | String | The MD5 hash of the file. |
| File.Extension | String | The file extension. |
| PolySwarm.FileID | String | The file ID. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Indicator | String | The indicator that was tested. |
| File.Tags.TagGroups.TagGroupName | String | The tag’s group name. |
| File.Tags.Aliases | String | Aliases of the tags. |
| File.Tags.PublicTagName | String | The public name of the tag. This is usually used as the ID of the tag. |
| File.Tags.TagName | String | The simple name of the tag. |
Command Example
!get-file hash="2410907a92b16dbd23a88d6bbd5037eae20eea809279f370293b587e1996eafe
Human Readable Output
file-scan
Uploads a file to PolySwarm and retrieves the analysis results.
Base Command
file-scan
Input
| Argument Name | Description | Required |
|---|---|---|
| entryID | The War Room entry ID of the file. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| PolySwarm.Total | Number | The total number of scans. |
| PolySwarm.Permalink | String | PolySwarm permalink results. |
| PolySwarm.Positives | Number | The total number of positives found. |
| PolySwarm.Scan_UUID | String | The PolySwarm scan UUID. |
| PolySwarm.Artifact | String | The artifact queried. |
Command Example
!file-scan entryID="995@0c42ee2d-57ff-4ccf-88ef-8d51c7936595"
Human Readable Output
Configuration parameters
api_key— PolySwarm API Key (required)base_url— The base URL to connect to (required)PolySwarm_v2— PolySwarm v2 Community (required)integrationReliability— Source ReliabilityfeedExpirationPolicy—feedExpirationInterval—
Commands (9)
-
domainQueries PolySwarm to retrieve domain reputation information.
-
fileQueries PolySwarm for file reputation information.
-
file-rescanRescans the uploaded artifact by hash.
-
file-scanUploads a file to PolySwarm and retrieves the analysis results.
-
get-fileDownloads a file hash from PolySwarm.
-
ipQueries PolySwarm for IP reputation information.
-
polyswarm-get-reportReturns a report using the UUID (SHA256).
-
urlQueries PolySwarm for URL reputation information.
-
url-scanUploads a URL to PolySwarm and retrieves the analysis results.
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 """ IMPORTS """ from polyswarm_api.api import PolyswarmAPI from polyswarm_api import settings as polyswarm_settings import socket import io """ CONSTANTS """ POLYSWARM_DEMISTO_VERSION = "2.0.11" ERROR_ENDPOINT = "Error with endpoint: " # Allows nested keys to be accesible def makehash(): import collections return collections.defaultdict(makehash) # Polyswarm-Demisto Interface class PolyswarmConnector: def __init__(self): self.config = {} # type: Dict[str,str] self.config["polyswarm_api_key"] = demisto.params().get("api_key") self.config["base_url"] = demisto.params().get("base_url") self.config["polyswarm_community"] = demisto.params().get("polyswarm_community") polyswarm_ua = f"{polyswarm_settings.DEFAULT_USER_AGENT} xsoar-PolySwarmV2/{POLYSWARM_DEMISTO_VERSION}" self.polyswarm_api = PolyswarmAPI( key=self.config["polyswarm_api_key"], uri=self.config["base_url"], user_agent=polyswarm_ua, ) def _get_results( self, object_name: str, title: str, total_scans: int, positives: int, permalink: str, artifact: str, indicator: object ) -> object: results = { "Scan_UUID": artifact, "Total": str(total_scans), "Positives": str(positives), "Permalink": permalink, "Artifact": artifact, } readable_output = tableToMarkdown(title, results) return CommandResults( readable_output=readable_output, outputs_prefix=f"PolySwarm.{object_name}", outputs_key_field="Scan_UUID", outputs=results, indicator=indicator, # type: ignore ignore_auto_extract=True, ) def test_connectivity(self) -> bool: EICAR_HASH = "131f95c51cc819465fa1797f6ccacf9d494aaaff46fa3eac73ae63ffbdfd8267" # guardrails-disable-line try: results = self.polyswarm_api.search(EICAR_HASH) for result in results: if result.failed: return False except Exception: return False return True def get_score(self, polyscore) -> int: try: if float(polyscore) < 0.2: return Common.DBotScore.GOOD elif 0.2 <= float(polyscore) < 0.7: return Common.DBotScore.SUSPICIOUS else: # polyscore is >= 0.7 return Common.DBotScore.BAD except TypeError: return Common.DBotScore.NONE def return_hash_results(self, results: list, title: str, error_msg: str) -> object: # default values total_scans: int = 0 positives: int = 0 md5: str = "" sha256: str = "" sha1: str = "" polyscore: int = 0 for result in results: if result.failed: return_error(error_msg) if not result.assertions: return_error("Run Rescan for this hash") # iterate for getting positives and total_scan number for assertion in result.assertions: if assertion.verdict: positives += 1 total_scans += 1 demisto.debug(f"Positives: {positives} - Total Scans: {total_scans}") md5 = result.md5 sha256 = result.sha256 sha1 = result.sha1 polyscore = result.polyscore dbot_score = Common.DBotScore( indicator=md5, indicator_type=DBotScoreType.FILE, integration_name="PolySwarm", score=self.get_score(polyscore), reliability=demisto.params().get("integrationReliability"), ) indicator = Common.File(md5=md5, sha1=sha1, sha256=sha256, dbot_score=dbot_score) return self._get_results("File", title, total_scans, positives, result.permalink, sha256, indicator) def file_reputation(self, hashes: list) -> object: command_results = [] artifacts = argToList(hashes) for artifact in artifacts: title = f"PolySwarm File Reputation for Hash: {artifact}" demisto.debug(f"[file_reputation] {title}") try: results = self.polyswarm_api.search(artifact) except Exception as err: return_error(f"{ERROR_ENDPOINT}{err}") error_msg = "Error fetching results. Please try again." command_results.append(self.return_hash_results(results, title, error_msg)) return command_results def detonate_file(self, entry_id: dict) -> object: title = f"PolySwarm File Detonation for Entry ID: {entry_id}" demisto.debug(f"[detonate_file] {title}") try: file_info = demisto.getFilePath(entry_id) except Exception: return_error(f"File not found - EntryID: {entry_id}") try: demisto.debug(f"Submit file: {file_info}") instance = self.polyswarm_api.submit(file_info["path"], artifact_name=file_info["name"]) result = self.polyswarm_api.wait_for(instance) except Exception as err: return_error(f"{ERROR_ENDPOINT}{err}") error_msg = "Error submitting File." return self.return_hash_results([result], title, error_msg) def rescan_file(self, hashes: list) -> object: command_results = [] artifacts = argToList(hashes) for artifact in artifacts: title = f"PolySwarm Rescan for Hash: {artifact}" demisto.debug(f"[rescan_file] {title}") try: instance = self.polyswarm_api.rescan(artifact) result = self.polyswarm_api.wait_for(instance) except Exception as err: return_error(f"{ERROR_ENDPOINT}{err}") error_msg = "Error rescaning File." command_results.append(self.return_hash_results([result], title, error_msg)) return command_results def get_file(self, hash_file: str): demisto.debug(f"[get_file] Hash: {hash_file}") handle_file = io.BytesIO() try: self.polyswarm_api.download_to_handle(hash_file, handle_file) return fileResult(hash_file, handle_file.getvalue()) except Exception as err: return_error(f"{ERROR_ENDPOINT}{err}") def url_reputation(self, param: dict, artifact_type: str) -> list: command_results = [] artifacts = argToList(param[artifact_type]) for artifact in artifacts: title = f"PolySwarm {artifact_type.upper()} Reputation for: {artifact}" demisto.debug(f"[url_reputation] {title}") # default values total_scans = 0 positives = 0 polyscore = 0 # IP validation if artifact_type == "ip": try: socket.inet_aton(artifact) except OSError: return_error(f"Invalid IP Address: {artifact}") try: # PolySwarm API: URL, IP and Domain are artifact_type='url' instance = self.polyswarm_api.submit(artifact, artifact_type="url") result = self.polyswarm_api.wait_for(instance) if result.failed: return demisto.results("Error submitting URL.") # iterate for getting positives and total_scan number for assertion in result.assertions: if assertion.verdict: positives += 1 total_scans += 1 polyscore = result.polyscore except Exception as err: return_error(f"{ERROR_ENDPOINT}{err}") if artifact_type == "ip": object_name = "IP" dbot_score_type = DBotScoreType.IP elif artifact_type == "url": object_name = "URL" dbot_score_type = DBotScoreType.URL elif artifact_type == "domain": object_name = "Domain" dbot_score_type = DBotScoreType.DOMAIN else: dbot_score_type = "" object_name = "" demisto.debug(f" {artifact_type=} -> {dbot_score_type=} {object_name=}") dbot_score = Common.DBotScore( indicator=artifact, indicator_type=dbot_score_type, integration_name="PolySwarm", score=self.get_score(polyscore), reliability=demisto.params().get("integrationReliability"), ) indicator = None if artifact_type == "ip": indicator = Common.IP(ip=artifact, dbot_score=dbot_score) elif artifact_type == "url": indicator = Common.URL(url=artifact, dbot_score=dbot_score) # type: ignore elif artifact_type == "domain": indicator = Common.Domain(domain=artifact, dbot_score=dbot_score) # type: ignore results = self._get_results(object_name, title, total_scans, positives, result.permalink, artifact, indicator) command_results.append(results) return command_results def get_report(self, hashes: list) -> object: """ UUID is equal to Hash. """ title = f"PolySwarm Report for UUID: {hashes}" demisto.debug(f"[get_report] {title}") return self.file_reputation(hashes) def main(): """EXECUTION""" LOG(f"command is {demisto.command()}") try: polyswarm = PolyswarmConnector() command = demisto.command() param = demisto.args() if command == "test-module": if polyswarm.test_connectivity(): return_results("ok") else: return_error("Connection Failed") elif command == "file": return_results(polyswarm.file_reputation(param["hash"])) elif command == "get-file": return_results(polyswarm.get_file(param["hash"])) elif command == "file-scan": return_results(polyswarm.detonate_file(param["entryID"])) elif command == "file-rescan": return_results(polyswarm.rescan_file(param["hash"])) elif command == "url": return_results(polyswarm.url_reputation(param, "url")) elif command == "url-scan": return_results(polyswarm.url_reputation(param, "url")) elif command == "ip": return_results(polyswarm.url_reputation(param, "ip")) elif command == "domain": return_results(polyswarm.url_reputation(param, "domain")) elif command == "polyswarm-get-report": return_results(polyswarm.get_report(param["scan_uuid"])) except Exception as e: return_error(str(e), error=traceback.format_exc()) if __name__ in ("__main__", "__builtin__", "builtins"): main()