Skip to content

ScanVsto

Scanner class for extracting information from VSTO files.

This class provides a scan method that extracts information from VSTO files, and stores it in the event dictionary attribute of the class.

Source code in strelka/src/python/strelka/scanners/scan_vsto.py
class ScanVsto(strelka.Scanner):
    """
    Scanner class for extracting information from VSTO files.

    This class provides a `scan` method that extracts information from VSTO files, and stores it in the `event`
    dictionary attribute of the class.

    """

    def scan(self, data, file, options, expire_at):
        """
        Extracts information from the VSTO file.

        Args:
            data: The binary data of the VSTO file to be scanned.
            file: File associated with data.
            options: Any options passed in from the backend configuration file.
            expire_at: The expiry time for this scan.

        """
        try:
            # As Vsto is in an XML format, parse the XML data
            xml = xmltodict.parse(data)

            # Extract the VSTO name
            if props := xml.get("Properties"):
                for prop in props.get("property", []):
                    if prop["vt:lpwstr"].endswith("vstolocal"):
                        self.event["vsto"] = prop["vt:lpwstr"].split("|")[0]

            # Extract the assembly identity, dependencies, publisher, and certificate information
            if asm := xml.get("asmv1:assembly"):
                if asm.get("assemblyIdentity"):
                    self.event["identity"] = asm["assemblyIdentity"]["@name"]
                    self.event["dependency"] = {
                        "manifest": asm["dependency"]["dependentAssembly"]["@codebase"],
                        "name": asm["dependency"]["dependentAssembly"][
                            "assemblyIdentity"
                        ]["@name"],
                    }
                    self.event["publisher"] = asm["publisherIdentity"]["@name"]
                    self.event["certificate"] = {
                        "b64": asm["Signature"]["KeyInfo"]["msrel:RelData"][
                            "r:license"
                        ]["r:issuer"]["Signature"]["KeyInfo"]["X509Data"][
                            "X509Certificate"
                        ],
                        "md5": hashlib.md5(
                            base64.b64decode(
                                asm["Signature"]["KeyInfo"]["msrel:RelData"][
                                    "r:license"
                                ]["r:issuer"]["Signature"]["KeyInfo"]["X509Data"][
                                    "X509Certificate"
                                ]
                            )
                        ).hexdigest(),
                    }

        except Exception as e:
            print(e)
            self.flags.append(f"{self.__class__.__name__} Exception: {str(e)[:100]}")

scan(data, file, options, expire_at)

Extracts information from the VSTO file.

Parameters:

Name Type Description Default
data

The binary data of the VSTO file to be scanned.

required
file

File associated with data.

required
options

Any options passed in from the backend configuration file.

required
expire_at

The expiry time for this scan.

required
Source code in strelka/src/python/strelka/scanners/scan_vsto.py
def scan(self, data, file, options, expire_at):
    """
    Extracts information from the VSTO file.

    Args:
        data: The binary data of the VSTO file to be scanned.
        file: File associated with data.
        options: Any options passed in from the backend configuration file.
        expire_at: The expiry time for this scan.

    """
    try:
        # As Vsto is in an XML format, parse the XML data
        xml = xmltodict.parse(data)

        # Extract the VSTO name
        if props := xml.get("Properties"):
            for prop in props.get("property", []):
                if prop["vt:lpwstr"].endswith("vstolocal"):
                    self.event["vsto"] = prop["vt:lpwstr"].split("|")[0]

        # Extract the assembly identity, dependencies, publisher, and certificate information
        if asm := xml.get("asmv1:assembly"):
            if asm.get("assemblyIdentity"):
                self.event["identity"] = asm["assemblyIdentity"]["@name"]
                self.event["dependency"] = {
                    "manifest": asm["dependency"]["dependentAssembly"]["@codebase"],
                    "name": asm["dependency"]["dependentAssembly"][
                        "assemblyIdentity"
                    ]["@name"],
                }
                self.event["publisher"] = asm["publisherIdentity"]["@name"]
                self.event["certificate"] = {
                    "b64": asm["Signature"]["KeyInfo"]["msrel:RelData"][
                        "r:license"
                    ]["r:issuer"]["Signature"]["KeyInfo"]["X509Data"][
                        "X509Certificate"
                    ],
                    "md5": hashlib.md5(
                        base64.b64decode(
                            asm["Signature"]["KeyInfo"]["msrel:RelData"][
                                "r:license"
                            ]["r:issuer"]["Signature"]["KeyInfo"]["X509Data"][
                                "X509Certificate"
                            ]
                        )
                    ).hexdigest(),
                }

    except Exception as e:
        print(e)
        self.flags.append(f"{self.__class__.__name__} Exception: {str(e)[:100]}")

Features

The features of this scanner are detailed below. These features represent the capabilities and the type of analysis the scanner can perform. This may include support for Indicators of Compromise (IOC), the ability to emit files for further analysis, and the presence of extended documentation for complex analysis techniques.

Feature
Support
IOC Support
Emit Files
Extended Docs
Malware Scanner
Image Thumbnails

Tastes

Strelka's file distribution system assigns scanners to files based on 'flavors' and 'tastes'. Flavors describe the type of file, typically determined by MIME types from libmagic, matches from YARA rules, or characteristics of parent files. Tastes are the criteria used within Strelka to determine which scanners are applied to which files, with positive and negative tastes defining files to be included or excluded respectively.

Source Filetype
Include / Exclude
vsto_file

Scanner Fields

This section provides a list of fields that are extracted from the files processed by this scanner. These fields include the data elements that the scanner extracts from each file, representing the analytical results produced by the scanner. If the test file is missing or cannot be parsed, this section will not contain any data.

Field Name
Field Type
certificate
dict
certificate.b64
str
certificate.md5
str
dependency
dict
dependency.manifest
str
dependency.name
str
elapsed
str
flags
list
identity
str
publisher
str

Sample Event

Below is a sample event generated by this scanner, demonstrating the kind of output that can be expected when it processes a file. This sample is derived from a mock scan event configured in the scanner's test file. If no test file is available, this section will not display a sample event.

    test_scan_event = {
        "elapsed": 0.001,
        "dependency": {
            "manifest": "TestInstaller.dll.manifest",
            "name": "TestIdentityName.dll",
        },
        "publisher": "CN=TEST\\test",
        "certificate": {
            "b64": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVuaWFtLCBxdWlzIG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBuaXNpIHV0IGFsaXF1aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxpdCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBFeGNlcHRldXIgc2ludCBvY2NhZWNhdCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBzdW50IGluIGN1bHBhIHF1aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLg==",
            "md5": "db89bb5ceab87f9c0fcc2ab36c189c2c",
        },
        "identity": "TestName.vsto",
        "flags": [],
    }