Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename to MetaDefender Sandbox #3

Merged
merged 4 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ name: Docker Build & Publish
on:
push:
tags:
# Assemblyline tags start with 4.4.
- '4.4.*'
# Assemblyline tags start with 4.4. or 4.5.
- '4.5.*'

env:
REGISTRY: opswat
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM cccs/assemblyline-v4-service-base:stable

# Python path to the service class from your service directory
# The following example refers to the class "Sample" from the "sample.py" file
ENV SERVICE_PATH filescan_sandbox.FilescanSandbox
ENV SERVICE_PATH metadefender_sandbox.MetaDefenderSandbox

# Install any service dependencies here
# For example: RUN apt-get update && apt-get install -y libyaml-dev
Expand All @@ -16,7 +16,7 @@ USER assemblyline
WORKDIR /opt/al_service
COPY . .

ARG version=4.4.1.dev1
ARG version=4.5.1.dev0
USER root
RUN sed -i -e "s/\$SERVICE_TAG/$version/g" service_manifest.yml

Expand Down
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
# assemblyline-service-opswat-filescan-sandbox
# assemblyline-service-metadefender-sandbox

This repository is self-developed Assemblyline service which submits a file or a URL from Assemblyline4 to OPSWAT Filescan Sandbox, and after a successful scan its fetches and parses the result.
This repository is self-developed Assemblyline service which submits a file or a URL from Assemblyline4 to MetaDefender Sandbox (previously known as OPSWAT Filescan Sandbox), and after a successful scan its fetches and parses the result.

## Prerequirements

Using this integration it is necessary to have an OPSWAT Filescan Sandbox API-key. You can use the Activation Key that you received from your OPSWAT Sales Representative, and follow the instructions on the [License Activation page](https://docs.opswat.com/filescan/installation/license-activation) or you can create an API key on the [Community site](https://www.filescan.io/auth/signin) under API Key tab.
Using this integration it is necessary to have a MetaDefender Sandbox API-key. You can use the Activation Key that you received from your OPSWAT Sales Representative, and follow the instructions on the [License Activation page](https://docs.opswat.com/filescan/installation/license-activation) or you can create an API key on the [Community site](https://www.filescan.io/auth/signin) under API Key tab.

## Heuristics

The result contains two types of heuristic:

- __Filescan Sandbox verdict is _VERDICT___ : This is the final verdict of Filescan Sandbox and added as a ResultSection
- __MetaDefender Sandbox verdict is _VERDICT___ : This is the final verdict of MetaDefender Sandbox and added as a ResultSection
- ___VERDICT_ threat indicators__: Comes from signal groups and added as a subsection

Heuristic score is the following:

| score | Filescan Sandbox verdict |
|------:|--------------------------|
| -1000 | BENIGN |
| 150 | NO THREAT |
| 299 | UNKNOWN |
| 500 | SUSPICIOUS |
| 850 | LIKELY MALICIOUS |
| 1000 | MALICIOUS |
| score | MetaDefender Sandbox verdict |
|------:|------------------------------|
| -1000 | BENIGN |
| 150 | NO THREAT |
| 299 | UNKNOWN |
| 500 | SUSPICIOUS |
| 850 | LIKELY MALICIOUS |
| 1000 | MALICIOUS |

## Official documentation

Expand Down
26 changes: 13 additions & 13 deletions filescan_sandbox.py → metadefender_sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import json
import base64
import filescan_sandbox_result
import metadefender_sandbox_result

import time
import requests
Expand Down Expand Up @@ -42,9 +42,9 @@ def requests_retry_session(
return session


class FilescanSandbox(ServiceBase):
class MetaDefenderSandbox(ServiceBase):
def __init__(self, config=None):
super(FilescanSandbox, self).__init__(config)
super(MetaDefenderSandbox, self).__init__(config)
self.api_key = self.config.get("api_key")
self.host = self.config.get("host")
self.headers = {}
Expand All @@ -57,7 +57,7 @@ def start(self):
# Your service might have to do some warming up on startup to make things faster

self.log.info(f"start() from {self.service_attributes.name} service called")
self.log.debug("OPSWAT Filescan Sandbox service started")
self.log.debug("MetaDefender Sandbox service started")


def post_sample(self, request: ServiceRequest, url=None, file_path=None):
Expand Down Expand Up @@ -178,7 +178,7 @@ def execute(self, request: ServiceRequest) -> None:
assert self.poll_interval > 0 and self.timeout > 0, "Poll interval or timeout is not appropriate"
except Exception as e:
self.log.error(
"No API key or Host found for OPSWAT Filescan Sandbox. Error: {e!r}"
"No API key or Host found for MetaDefender Sandbox. Error: {e!r}"
)
raise e

Expand All @@ -188,10 +188,10 @@ def execute(self, request: ServiceRequest) -> None:
response = {}
try:
if submitted_url:
self.log.info("OPSWAT Filescan Sandbox start to scan a file")
self.log.info("MetaDefender Sandbox start to scan a file")
response = self.post_sample(request, url=submitted_url)
elif submitted_file:
self.log.info("OPSWAT Filescan Sandbox start to scan an URL")
self.log.info("MetaDefender Sandbox start to scan an URL")
response = self.post_sample(request, file_path=submitted_file)
except Exception as e:
self.log.error(f"Error occurred when scan a file/URL: {e!r}")
Expand All @@ -204,23 +204,23 @@ def execute(self, request: ServiceRequest) -> None:
rejected = response.get("rejected_files", None)
if rejected:
for rejection in rejected:
rejection_result = ResultSection('OPSWAT Filescan Sandbox rejection',
rejection_result = ResultSection('MetaDefender Sandbox rejection',
body_format=BODY_FORMAT.KEY_VALUE,
body=json.dumps(rejection))
result.add_section(rejection_result)

if response.get("reports", {}):
result = filescan_sandbox_result.result_parser(result, response)
result = metadefender_sandbox_result.result_parser(result, response)
else:
self.log.warning(f"There is no OPSWAT Filescan Sandbox reports.")
self.log.warning(f"There is no MetaDefender Sandbox reports.")

report_link = f"{self.host}/uploads/{response.get('flowId')}"
report_link_rs = ResultSection('OPSWAT Filescan Sandbox full report is available here:',
report_link_rs = ResultSection('MetaDefender Sandbox full report is available here:',
body_format=BODY_FORMAT.URL,
body=json.dumps({"name": "Filescan Sandbox report", "url": report_link}))
body=json.dumps({"name": "MetaDefender Sandbox report", "url": report_link}))
result.add_section(report_link_rs)

else:
self.log.warning(f"There is no OPSWAT Filescan Sandbox response.")
self.log.warning(f"There is no MetaDefender Sandbox response.")

request.result = result
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ def process_resources(result_section, resources):
def parse_report(report, report_id, flow_id):
compact_result = parse_compact_result(report, report_id, flow_id)
verdict_rs = ResultSection(
"OPSWAT Filescan Sandbox result",
"MetaDefender Sandbox result",
body_format=BODY_FORMAT.KEY_VALUE,
body=json.dumps(compact_result),
)
Expand Down
8 changes: 8 additions & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
## Release notes

### 4.5.1.dev0

Date: 5 April, 2024

Changed:

- Integration renaming: From _OPSWAT Filescan Sandbox_ to _MetaDefender Sandbox_

### 4.4.1.dev1

Date: 8 Sept, 2023
Expand Down
42 changes: 21 additions & 21 deletions service_manifest.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Name of the service
name: OPSWAT_Filescan_Sandbox
name: MetaDefender_Sandbox
# Version of the service
version: $SERVICE_TAG

description: This Assemblyline service interfaces with the OPSWAT Filescan Sandbox, detonating files and URLs. This integration was developed by OPSWAT. (C) OPSWAT, Inc.
description: This Assemblyline service interfaces with the MetaDefender Sandbox -previously known as OPSWAT Filescan Sandbox-, detonating files and URLs. This integration was developed by OPSWAT. (C) OPSWAT, Inc.

accepts: .*
rejects: empty
Expand All @@ -26,62 +26,62 @@ uses_metadata: true
# >= 1000: malicious

heuristics:
- description: OPSWAT Filescan Sandbox determined that the file is benign.
- description: MetaDefender Sandbox determined that the file is benign.
filetype: "*"
heur_id: 1
name: Filescan Sandbox verdict is benign.
name: MetaDefender Sandbox verdict is benign.
score: -1000
- description: OPSWAT Filescan Sandbox signal group is benign.
- description: MetaDefender Sandbox signal group is benign.
filetype: "*"
heur_id: 2
name: Benign threat indicators
score: -1000
- description: OPSWAT Filescan Sandbox determined that the file is informational/no threat.
- description: MetaDefender Sandbox determined that the file is informational/no threat.
filetype: "*"
heur_id: 3
name: Filescan Sandbox verdict is no threat.
name: MetaDefender Sandbox verdict is no threat.
score: 150
- description: OPSWAT Filescan Sandbox signal group is informational/no threat.
- description: MetaDefender Sandbox signal group is informational/no threat.
filetype: "*"
heur_id: 4
name: Informational threat indicators
score: 150
- description: OPSWAT Filescan Sandbox determined that the file is unknown.
- description: MetaDefender Sandbox determined that the file is unknown.
filetype: "*"
heur_id: 5
name: Filescan Sandbox verdict is unknown
name: MetaDefender Sandbox verdict is unknown
score: 299
- description: OPSWAT Filescan Sandbox signal group is unknown.
- description: MetaDefender Sandbox signal group is unknown.
filetype: "*"
heur_id: 6
name: Unknown threat indicators
score: 299
- description: OPSWAT Filescan Sandbox determined that the file is suspicious.
- description: MetaDefender Sandbox determined that the file is suspicious.
filetype: "*"
heur_id: 7
name: Filescan Sandbox verdict is suspicious
name: MetaDefender Sandbox verdict is suspicious
score: 500
- description: OPSWAT Filescan Sandbox signal group is suspicious.
- description: MetaDefender Sandbox signal group is suspicious.
filetype: "*"
heur_id: 8
name: Suspicious threat indicators
score: 500
- description: OPSWAT Filescan Sandbox determined that the file is likely malicious.
- description: MetaDefender Sandbox determined that the file is likely malicious.
filetype: "*"
heur_id: 9
name: Filescan Sandbox verdict is likely malicious
name: MetaDefender Sandbox verdict is likely malicious
score: 850
- description: OPSWAT Filescan Sandbox signal group is likely malicious.
- description: MetaDefender Sandbox signal group is likely malicious.
filetype: "*"
heur_id: 10
name: Likely malicious threat indicators
score: 850
- description: OPSWAT Filescan Sandbox determined that the file is malicious.
- description: MetaDefender Sandbox determined that the file is malicious.
filetype: "*"
heur_id: 11
name: Filescan Sandbox verdict is malicious
name: MetaDefender Sandbox verdict is malicious
score: 1000
- description: OPSWAT Filescan Sandbox signal group is malicious.
- description: MetaDefender Sandbox signal group is malicious.
filetype: "*"
heur_id: 12
name: Malicious threat indicators
Expand All @@ -91,7 +91,7 @@ heuristics:
# - the name of the docker container that will be created
# - CPU and ram allocation by the container
docker_config:
image: ${REGISTRY}opswat/assemblyline-service-opswat-filescan-sandbox:$SERVICE_TAG
image: ${REGISTRY}opswat/assemblyline-service-metadefender-sandbox:$SERVICE_TAG
cpu_cores: 1.0
ram_mb: 1024
allow_internet_access: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


sys.path.append("..")
import filescan_sandbox_result
import metadefender_sandbox_result
from assemblyline_v4_service.common.result import (
Result,
ResultSection,
Expand All @@ -22,7 +22,7 @@ def util_load_json(path: str) -> Any:
return json.loads(f.read())


class TestFilescanSandboxResult:
class TestMetaDefenderSandboxResult:
@classmethod
def setup_class(cls):
# copy yml
Expand Down Expand Up @@ -51,7 +51,7 @@ def test_parse_compact_result_bad():
.get("reports", {})
.get("93a90ffb-1aac-43f6-abdd-c579d6ae14df", {})
)
compact_result = filescan_sandbox_result.parse_compact_result(
compact_result = metadefender_sandbox_result.parse_compact_result(
raw_response,
"93a90ffb-1aac-43f6-abdd-c579d6ae14df",
"64d1fb9c2a1db2a88ac17017",
Expand All @@ -76,7 +76,7 @@ def test_parse_compact_result_informational():
.get("reports", {})
.get("21815d5f-3653-466e-a421-187423ca7b93", {})
)
compact_result = filescan_sandbox_result.parse_compact_result(
compact_result = metadefender_sandbox_result.parse_compact_result(
raw_response,
"21815d5f-3653-466e-a421-187423ca7b93",
"64de1abb9489ac1ead366732",
Expand All @@ -101,7 +101,7 @@ def test_parse_compact_result_badfile2():
.get("reports", {})
.get("d389e943-dc72-4070-aade-1d11f0457ea3", {})
)
compact_result = filescan_sandbox_result.parse_compact_result(
compact_result = metadefender_sandbox_result.parse_compact_result(
raw_response,
"d389e943-dc72-4070-aade-1d11f0457ea3",
"64de19f4a29d57e20384dac6",
Expand Down Expand Up @@ -146,7 +146,7 @@ def test_parse_compact_result_badfile2():
@staticmethod
def test_parse_compact_result_empty():
raw_response = {}
compact_result = filescan_sandbox_result.parse_compact_result(
compact_result = metadefender_sandbox_result.parse_compact_result(
raw_response,
"93a90ffb-1aac-43f6-abdd-c579d6ae14df",
"64d1fb9c2a1db2a88ac17017",
Expand Down Expand Up @@ -175,7 +175,7 @@ def test_process_allSignalGroups():

rs = ResultSection("Test", body_format=BODY_FORMAT.TEXT, body="test")

compact_result = filescan_sandbox_result.process_allSignalGroups(
compact_result = metadefender_sandbox_result.process_allSignalGroups(
rs, raw_response
)

Expand All @@ -193,7 +193,7 @@ def test_process_iocs():

rs = ResultSection("Test", body_format=BODY_FORMAT.TEXT, body="test")

compact_result = filescan_sandbox_result.process_iocs(rs, raw_response)
compact_result = metadefender_sandbox_result.process_iocs(rs, raw_response)
tags = {
"network.email.address": ["ActivationDepartment@FedRetireSoftware.com"],
"network.static.uri": [
Expand All @@ -218,7 +218,7 @@ def test_process_allOsintTags():

rs = ResultSection("Test", body_format=BODY_FORMAT.TEXT, body="test")

compact_result = filescan_sandbox_result.process_allOsintTags(rs, raw_response)
compact_result = metadefender_sandbox_result.process_allOsintTags(rs, raw_response)
tags = {"av.virus_name": ["emotet", "geodo"]}
assert rs.tags == tags

Expand All @@ -233,7 +233,7 @@ def test_process_resources():

rs = ResultSection("Test", body_format=BODY_FORMAT.TEXT, body="test")

compact_result = filescan_sandbox_result.process_resources(rs, raw_response)
compact_result = metadefender_sandbox_result.process_resources(rs, raw_response)
tags = {
"av.virus_name": ["Trojan/Riskware!my0NYEEN"],
"attribution.family": ["riskware"],
Expand Down
Loading