-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #346 from target/ScanVsto
ScanVsto
- Loading branch information
Showing
7 changed files
with
259 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
""" | ||
This module provides a scanner that extracts information from VSTO files. | ||
It defines the following class: | ||
- ScanVsto: Scans VSTO files and extracts information like the name, assembly identity, dependencies, | ||
publisher, and certificate. | ||
""" | ||
|
||
|
||
import base64 | ||
import hashlib | ||
|
||
import xmltodict | ||
|
||
from strelka import strelka | ||
|
||
|
||
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]}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" | ||
xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" | ||
xmlns="urn:schemas-microsoft-com:asm.v2" | ||
xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" | ||
xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" | ||
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" | ||
xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" | ||
xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2"> | ||
<assemblyIdentity name="TestName.vsto" version="1.0.0.1" publicKeyToken="09fad4d541a5a080" language="neutral" processorArchitecture="msil" | ||
xmlns="urn:schemas-microsoft-com:asm.v1" /> | ||
<description asmv2:publisher="TestPublisher" asmv2:product="TestProduct" | ||
xmlns="urn:schemas-microsoft-com:asm.v1" /> | ||
<deployment install="false" /> | ||
<compatibleFrameworks | ||
xmlns="urn:schemas-microsoft-com:clickonce.v2"> | ||
<framework targetVersion="4.5" profile="Full" supportedRuntime="4.0.30319" /> | ||
</compatibleFrameworks> | ||
<dependency> | ||
<dependentAssembly dependencyType="install" codebase="TestInstaller.dll.manifest" size="13456"> | ||
<assemblyIdentity name="TestIdentityName.dll" version="1.0.0.1" publicKeyToken="09fad4d541a5a080" language="neutral" processorArchitecture="msil" type="win32" /> | ||
<hash> | ||
<dsig:Transforms> | ||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" /> | ||
</dsig:Transforms> | ||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /> | ||
<dsig:DigestValue>hjtoNGCkEXL0ZSfJTK4WsgrsRjtcww3+IrtNnfR8h8o=</dsig:DigestValue> | ||
</hash> | ||
</dependentAssembly> | ||
</dependency> | ||
<publisherIdentity name="CN=TEST\test" issuerKeyHash="db88bb5ceab87f9c0fcc2ab36c189c2c" /> | ||
<Signature Id="StrongNameSignature" | ||
xmlns="http://www.w3.org/2000/09/xmldsig#"> | ||
<SignedInfo> | ||
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> | ||
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /> | ||
<Reference URI=""> | ||
<Transforms> | ||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> | ||
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> | ||
</Transforms> | ||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /> | ||
<DigestValue>TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=</DigestValue> | ||
</Reference> | ||
</SignedInfo> | ||
<SignatureValue>TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=</SignatureValue> | ||
<KeyInfo Id="StrongNameKeyInfo"> | ||
<KeyValue> | ||
<RSAKeyValue> | ||
<Modulus>TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=</Modulus> | ||
<Exponent>AQAB</Exponent> | ||
</RSAKeyValue> | ||
</KeyValue> | ||
<msrel:RelData | ||
xmlns:msrel="http://schemas.microsoft.com/windows/rel/2005/reldata"> | ||
<r:license | ||
xmlns:r="urn:mpeg:mpeg21:2003:01-REL-R-NS" | ||
xmlns:as="http://schemas.microsoft.com/windows/pki/2005/Authenticode"> | ||
<r:grant> | ||
<as:ManifestInformation Hash="eb78b614be2e9c728abd7470cbd0a076e757d677e7264da98306d0d19548de86" Description="" Url=""> | ||
<as:assemblyIdentity name="TestIdentityName.vsto" version="1.0.0.1" publicKeyToken="09fad4d541a5a080" language="neutral" processorArchitecture="msil" | ||
xmlns="urn:schemas-microsoft-com:asm.v1" /> | ||
</as:ManifestInformation> | ||
<as:SignedBy /> | ||
<as:AuthenticodePublisher> | ||
<as:X509SubjectName>CN=TEST\test</as:X509SubjectName> | ||
</as:AuthenticodePublisher> | ||
</r:grant> | ||
<r:issuer> | ||
<Signature Id="AuthenticodeSignature" | ||
xmlns="http://www.w3.org/2000/09/xmldsig#"> | ||
<SignedInfo> | ||
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> | ||
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /> | ||
<Reference URI=""> | ||
<Transforms> | ||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> | ||
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> | ||
</Transforms> | ||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /> | ||
<DigestValue>TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=</DigestValue> | ||
</Reference> | ||
</SignedInfo> | ||
<SignatureValue>TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=</SignatureValue> | ||
<KeyInfo> | ||
<KeyValue> | ||
<RSAKeyValue> | ||
<Modulus>TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=</Modulus> | ||
<Exponent>AQAB</Exponent> | ||
</RSAKeyValue> | ||
</KeyValue> | ||
<X509Data> | ||
<X509Certificate>TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVuaWFtLCBxdWlzIG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBuaXNpIHV0IGFsaXF1aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxpdCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBFeGNlcHRldXIgc2ludCBvY2NhZWNhdCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBzdW50IGluIGN1bHBhIHF1aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLg==</X509Certificate> | ||
</X509Data> | ||
</KeyInfo> | ||
</Signature> | ||
</r:issuer> | ||
</r:license> | ||
</msrel:RelData> | ||
</KeyInfo> | ||
</Signature> | ||
</asmv1:assembly> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from pathlib import Path | ||
from unittest import TestCase, mock | ||
|
||
from strelka.scanners.scan_vsto import ScanVsto as ScanUnderTest | ||
from strelka.tests import run_test_scan | ||
|
||
|
||
def test_scan_vsto(mocker): | ||
""" | ||
Pass: Sample event matches output of scanner. | ||
Failure: Unable to load file or sample event fails to match. | ||
""" | ||
test_scan_event = { | ||
"elapsed": mock.ANY, | ||
"dependency": { | ||
"manifest": "TestInstaller.dll.manifest", | ||
"name": "TestIdentityName.dll", | ||
}, | ||
"publisher": "CN=TEST\\test", | ||
"certificate": { | ||
"b64": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVuaWFtLCBxdWlzIG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBuaXNpIHV0IGFsaXF1aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxpdCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBFeGNlcHRldXIgc2ludCBvY2NhZWNhdCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBzdW50IGluIGN1bHBhIHF1aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLg==", | ||
"md5": "db89bb5ceab87f9c0fcc2ab36c189c2c", | ||
}, | ||
"identity": "TestName.vsto", | ||
"flags": [], | ||
} | ||
|
||
scanner_event = run_test_scan( | ||
mocker=mocker, | ||
scan_class=ScanUnderTest, | ||
fixture_path=Path(__file__).parent / "fixtures/test.vsto", | ||
) | ||
|
||
TestCase.maxDiff = None | ||
TestCase().assertDictEqual(test_scan_event, scanner_event) |