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 os import io import demistomock as demisto from CommonServerPython import EntryType import PolySwarmV2 from PolySwarmV2 import PolyswarmConnector import pytest import vcr as libvcr pytest_plugins = "test_data.vendored_pytest_vcr" TEST_FOLDER = os.path.dirname(os.path.abspath(__file__)) TEST_SCAN_UUID = "95039375646493045" TEST_SCAN_DOMAIN = "preesallmobilevalating23-gmail[.]com".replace("[.]", ".") TEST_SCAN_IP = "205[.]210[.]31[.]208".replace("[.]", ".") TEST_SCAN_URL = "http://preesallmobilevalating23-gmail[.]com".replace("[.]", ".") TEST_HASH_FILE = "275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f" TEST_ENTRY_ID = "XXXXX" MOCK_API_URL = os.getenv("POLYSWARM_API_URI", "https://api.polyswarm.network/v3/") POLYSWARM_URL_RESULTS_BASE = "https://polyswarm.network/scan/results/file" POLYSWARM_URL_RESULTS = f"{POLYSWARM_URL_RESULTS_BASE}/{TEST_HASH_FILE}" POLYSWARM_COMMUNITY = "default" MOCK_PARAMS = { "api_key": os.getenv("POLYSWARM_API_KEY", "XXXXXXXXXXXXXXXXXXXXXXXXXX"), "base_url": MOCK_API_URL, "polyswarm_community": POLYSWARM_COMMUNITY, } MOCK_FILE_INFO = {"name": "MaliciousFile.exe", "path": "/path/MaliciousFile.exe"} @pytest.fixture(autouse=True) def patch_VCRHTTPResponse_version_string(): # FROM: https://github.com/kevin1024/vcrpy/issues/888#issuecomment-2561302419 # Can be removed after vcrpy gets updated from vcr.stubs import VCRHTTPResponse if not hasattr(VCRHTTPResponse, "version_string"): VCRHTTPResponse.version_string = None @pytest.fixture(scope="module") def vcr_config(): redacted_data = [ ("authorization", "XXXXXXXXXXXXXXXXXXXXXXXXXX"), ("X-Amz-Credential", "AKIADEADBEEFCREDENTIAL"), ("X-Amz-Signature", "2345678deadbeefdeadbeef2345678deadbeefdeadbeef2345678deadbeef"), ("X-Billing-ID", "876543218765"), ] def redact_response(response): for name, new_value in redacted_data: if name in response["headers"]: response["headers"][name] = new_value return response return { "serializer": "yaml", "cassette_library_dir": os.path.join(TEST_FOLDER, "test_data/fixtures/vcr/"), "path_transformer": libvcr.VCR.ensure_suffix(".tape"), "record_mode": libvcr.record_mode.RecordMode.ONCE, # .ALL, # .NONE "filter_headers": redacted_data, "filter_post_data_parameters": redacted_data, "filter_query_parameters": redacted_data, "before_record_response": redact_response, } @pytest.mark.vcr() def test_file_scan(mocker): mocker.patch.object(demisto, "debug", return_value=None) mocker.patch.object(demisto, "params", return_value=MOCK_PARAMS) mocker.patch.object(demisto, "getFilePath", return_value=MOCK_FILE_INFO) mocker.patch.object(PolySwarmV2, "fileResult", return_value={"Type": EntryType.ENTRY_INFO_FILE}) polyswarm = PolyswarmConnector() param = {"entryID": TEST_ENTRY_ID} def fake_open(*args, **kwargs): result = io.StringIO("X5O!P" r"%@AP[4\PZ" "X54(P^)7CC" ")7}$EICAR-STANDARD-ANTIVIRUS" "-TEST-FILE!$H+H*") result.seek(0) return result mocker.patch("builtins.open", fake_open) results = polyswarm.detonate_file(param["entryID"]) results = results.to_context() assert results["Contents"]["Positives"] >= "10" assert results["Contents"]["Total"] >= "10" assert results["Contents"]["Scan_UUID"] == TEST_HASH_FILE assert results["Contents"]["Permalink"].startswith(POLYSWARM_URL_RESULTS) assert results["Contents"]["Artifact"] == TEST_HASH_FILE @pytest.mark.vcr() @pytest.mark.parametrize( "kind,scan_target,results_id", [ pytest.param( "domain", TEST_SCAN_DOMAIN, "bd870bed700771f4fbe8992b5022fa655df743a397278c60cc40f4d25dac4052", id="domain" ), # test Domain scan reputation pytest.param( "ip", TEST_SCAN_IP, "af0169d053b43eb83b886fd65a8bc7df1d76bcc2b068c862ec1048e8cf1df8a2", id="ip" ), # test IP scan reputation pytest.param( "url", TEST_SCAN_URL, "dca3fb56531786e4141a7fdcdfaf0e74b64755b2514c2712881124e0449ba41d", id="url" ), # test URL scan reputation ], ) def test_reputation(mocker, kind, scan_target, results_id): mocker.patch.object(demisto, "debug", return_value=None) mocker.patch.object(demisto, "params", return_value=MOCK_PARAMS) mocker.patch.object(PolySwarmV2, "fileResult", return_value={"Type": EntryType.ENTRY_INFO_FILE}) polyswarm = PolyswarmConnector() param = {kind: [scan_target]} results = polyswarm.url_reputation(param, kind) results = results[0].to_context() assert results["Contents"]["Positives"] >= "1" assert results["Contents"]["Total"] >= "3" assert results["Contents"]["Scan_UUID"] == scan_target assert results["Contents"]["Permalink"].startswith( f"{POLYSWARM_URL_RESULTS_BASE}/{results_id}/" ), f'REALITY: {results["Contents"]["Permalink"]}' assert results["Contents"]["Artifact"] == scan_target @pytest.mark.vcr() def test_polyswarm_get_report(mocker): mocker.patch.object(demisto, "debug", return_value=None) mocker.patch.object(demisto, "params", return_value=MOCK_PARAMS) mocker.patch.object(PolySwarmV2, "fileResult", return_value={"Type": EntryType.ENTRY_INFO_FILE}) polyswarm = PolyswarmConnector() param = {"scan_uuid": TEST_HASH_FILE} results = polyswarm.get_report(param["scan_uuid"]) results = results[0].to_context() assert int(results["Contents"]["Positives"]) >= 6 assert int(results["Contents"]["Total"]) >= 11 assert results["Contents"]["Scan_UUID"] == TEST_HASH_FILE assert results["Contents"]["Permalink"].startswith(POLYSWARM_URL_RESULTS), f'REALITY: {results["Contents"]["Permalink"]}' assert results["Contents"]["Artifact"] == TEST_HASH_FILE @pytest.mark.vcr() def test_file_rescan(mocker): mocker.patch.object(demisto, "debug", return_value=None) mocker.patch.object(demisto, "params", return_value=MOCK_PARAMS) mocker.patch.object(PolySwarmV2, "fileResult", return_value={"Type": EntryType.ENTRY_INFO_FILE}) polyswarm = PolyswarmConnector() param = {"hash": TEST_HASH_FILE} results = polyswarm.rescan_file(param["hash"]) results = results[0].to_context() assert int(results["Contents"]["Positives"]) >= 1 assert int(results["Contents"]["Total"]) >= 3 assert results["Contents"]["Scan_UUID"] == TEST_HASH_FILE assert results["Contents"]["Permalink"].startswith(POLYSWARM_URL_RESULTS), f'REALITY: {results["Contents"]["Permalink"]}' assert results["Contents"]["Artifact"] == TEST_HASH_FILE @pytest.mark.vcr() def test_get_file(mocker): mocker.patch.object(demisto, "debug", return_value=None) mocker.patch.object(demisto, "params", return_value=MOCK_PARAMS) polyswarm = PolyswarmConnector() param = {"hash": TEST_HASH_FILE} results = polyswarm.get_file(param["hash"]) try: assert results["File"] == TEST_HASH_FILE finally: # Cannot mock fileResult as we are testing also its return value. # Instead, lets cleanup its leftovers os.unlink("1_" + results["FileID"]) @pytest.mark.vcr() def test_file(mocker): mocker.patch.object(demisto, "debug", return_value=None) mocker.patch.object(demisto, "params", return_value=MOCK_PARAMS) mocker.patch.object(PolySwarmV2, "fileResult", return_value={"Type": EntryType.ENTRY_INFO_FILE}) polyswarm = PolyswarmConnector() # Verify custom User-Agent header ua = polyswarm.polyswarm_api.session.headers["User-Agent"] assert "polyswarm_api/" in ua or "polyswarm-api/" in ua assert f"xsoar-PolySwarmV2/{PolySwarmV2.POLYSWARM_DEMISTO_VERSION}" in ua param = {"hash": TEST_HASH_FILE} results = polyswarm.file_reputation(param["hash"]) results = results[0].to_context() assert int(results["Contents"]["Positives"]) >= 6 assert int(results["Contents"]["Total"]) >= 9 assert results["Contents"]["Scan_UUID"] == TEST_HASH_FILE assert results["Contents"]["Permalink"].startswith(POLYSWARM_URL_RESULTS), f'REALITY: {results["Contents"]["Permalink"]}' assert results["Contents"]["Artifact"] == TEST_HASH_FILE