PolySwarmPolySwarmPolySwarmPolySwarm
Help

Building an EICAR-Detecting Microengine

概览

The EICAR test file is used by the Antivirus industry to test engines' ability to detect malware. The file is not malicious, but is flagged as such by most vendors.

The EICAR test file is defined as a file that contains begins with the following string: X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H* followed by a variable amount of whitespace.

Elsewhere, we discuss implementing an Ambassador that submits the EICAR test file.

(Optional) Review the components of a Microengine →l


Implement an EICAR Test File Scanner

Detecting EICAR is as simple as implementing a Scanner class that knows how to identify the EICAR test file.

When you created your microengine, participant-template created a Scanner class in your microengine's {{ cookiecutter.project_slug }}/{{ cookiecutter.package_slug }}/{{ cookiecutter.participant_name_slug }}.py file*. Scanner subclasses AbstractScanner, which is provided polyswarm-client.

*These are cookiecutter variables; your directory structure will be based on responses to cookiecutter prompts.

You'll need to implement your Scanner's scan() method, instructing it to flag the EICAR test file as malicious.

There are, of course, many ways to identify files that match the EICAR criteria. The following are 2 examples for how you can write your scan() function to detect EICAR.

String Matching

This method does not detect EICAR test files with appended whitespace. Expanding this example to detect the full range of EICAR test files is left as an exercise to the user.

String matching is used by microengine-eicar:

import base64
from polyswarmclient.abstractmicroengine import AbstractMicroengine
from polyswarmclient.abstractscanner import AbstractScanner, ScanResult

EICAR = base64.b64decode(b'WDVPIVAlQEFQWzRcUFpYNTQoUF4pN0NDKTd9JEVJQ0FSLVNUQU5EQVJELUFOVElWSVJVUy1URVNULUZJTEUhJEgrSCo=')

class Scanner(AbstractScanner):

    async def scan(self, guid, artifact_type, content, chain):
        if content == EICAR:
            return ScanResult(bit=True, verdict=True)

        return ScanResult(bit=True, verdict=False)

SHA-256 Matching

This method does not detect EICAR test files with appended whitespace. Expanding this example to detect the full range of EICAR test files is left as an exercise to the user.

This method compares the SHA-256 digest of the EICAR test file with a known-bad hash:

import base64

from hashlib import sha256
from polyswarmclient.abstractmicroengine import AbstractMicroengine
from polyswarmclient.abstractscanner import AbstractScanner, ScanResult

EICAR = base64.b64decode(b'WDVPIVAlQEFQWzRcUFpYNTQoUF4pN0NDKTd9JEVJQ0FSLVNUQU5EQVJELUFOVElWSVJVUy1URVNULUZJTEUhJEgrSCo=')
HASH = sha256(EICAR).hexdigest()

class Scanner(AbstractScanner):

    async def scan(self, guid, artifact_type, content, chain):
        testhash = sha256(content).hexdigest()
        if (testhash == HASH):
            return ScanResult(bit=True, verdict=True)

        return ScanResult(bit=True, verdict=False)

测试您的参与者

Once everything is in place, let's test our participant:

Unit Testing →

Next Steps

Housing all of your microengine's scan logic in the scan() function is unlikely to scalel. Perhaps you have an existing scan engine or external library that houses the details of your scanning logic and you need to call out to that scan engine for results.

Next, we'll wrap the open source ClamAV antivirus engine into a microengine →