def test_add_two_ip_at_once(): # arrange verdict = Verdict() # act verdict.add_ip_addresses(['192.168.0.1', '8.8.8.8']) # assert assert verdict.ip_addresses == ['192.168.0.1', '8.8.8.8']
def test_set_scanner_psc_version(): # arrange verdict = Verdict().set_malware_family("Eicar") # act verdict.set_scanner(polyswarmclient_version="1.1.1") # assert assert verdict.scanner == {"polyswarmclient_version": "1.1.1"}
def test_empty_verdict(): # arrange verdict = Verdict() # act # assert with pytest.raises(ValueError): verdict.json()
def test_add_domain(): # arrange verdict = Verdict() # act verdict.add_domain('polyswarm.io') # assert assert verdict.domains == ['polyswarm.io']
def test_add_ip(): # arrange verdict = Verdict() # act verdict.add_ip_address('192.168.0.1') # assert assert verdict.ip_addresses == ['192.168.0.1']
def test_set_scanner_with_vendor_version(): # arrange verdict = Verdict().set_malware_family("Eicar") # act verdict.set_scanner(vendor_version="1.1.1") # assert assert verdict.scanner == {"vendor_version": "1.1.1"}
def test_add_two_domains_at_once(): # arrange verdict = Verdict() # act verdict.add_domains(['polyswarm.io', 'polyswarm.network']) # assert assert verdict.domains == ['polyswarm.io', 'polyswarm.network']
def test_set_scanner_with_signature_version(): # arrange verdict = Verdict().set_malware_family("Eicar") # act verdict.set_scanner(signatures_version="05-12-2019") # assert assert verdict.scanner == {"signatures_version": "05-12-2019"}
def test_set_malware_family(): # arrange verdict = Verdict() # act verdict.set_malware_family("Eicar") # assert assert verdict.malware_family == "Eicar"
def extract_verdict(scan: 'ScanResult') -> 'Optional[Verdict]': """Try to parse ``scan.metadata`` as a Verdict""" meta = getattr(scan, 'metadata', None) if isinstance(meta, str): return Verdict.parse_raw(meta) elif isinstance(meta, Mapping): return Verdict.parse_obj(meta) return meta
def test_add_extra_object(): # arrange verdict = Verdict().set_malware_family("Eicar") # act verdict.add_extra("new_key", {"other_key": "string_value"}) # assert k, v = verdict.extra[0] assert k == 'new_key' assert v == {"other_key": "string_value"}
def test_add_extra_array(): # arrange verdict = Verdict().set_malware_family("Eicar") # act verdict.add_extra("new_key", ["string_value"]) # assert k, v = verdict.extra[0] assert k == 'new_key' assert v == ["string_value"]
def test_add_stix_string(): # arrange verdict = Verdict() # act verdict.add_stix_signature( 'oasis-open/cti-stix2-json-schemas/master/schemas/common/hex.json', "a0") # assert assert verdict.stix[0][ 'schema'] == 'oasis-open/cti-stix2-json-schemas/master/schemas/common/hex.json' assert verdict.stix[0]['signature'] == "a0"
def test_set_scanner_arch(): # arrange verdict = Verdict().set_malware_family("Eicar") # act verdict.set_scanner(architecture="x86") # assert assert verdict.scanner == { "environment": { "operating_system": None, "architecture": "x86" } }
def test_set_scanner_os(): # arrange verdict = Verdict().set_malware_family("Eicar") # act verdict.set_scanner(operating_system="windows") # assert assert verdict.scanner == { "environment": { "operating_system": "windows", "architecture": None } }
async def scan(self, guid, artifact_type, content, metadata, chain): """Scan an artifact with ClamAV Args: guid (str): GUID of the bounty under analysis, use to track artifacts in the same bounty artifact_type (ArtifactType): Artifact type for the bounty being scanned content (bytes): Content of the artifact to be scan metadata (dict) Dict of metadata for the artifact chain (str): Chain we are operating on Returns: ScanResult: Result of this scan """ result = await self.clamd.instream(BytesIO(content)) stream_result = result.get('stream', []) vendor = await self.clamd.version() metadata = Verdict().set_scanner(operating_system=platform.system(), architecture=platform.machine(), vendor_version=vendor.strip('\n')) if len(stream_result) >= 2 and stream_result[0] == 'FOUND': metadata.set_malware_family(stream_result[1].strip('\n')) return ScanResult(bit=True, verdict=True, confidence=1.0, metadata=metadata.json()) metadata.set_malware_family('') return ScanResult(bit=True, verdict=False, metadata=metadata.json())
async def scan(self, guid, artifact_type, content, metadata, chain): """Scan an artifact with Yara. Args: guid (str): GUID of the bounty under analysis, use to track artifacts in the same bounty artifact_type (ArtifactType): Artifact type for the bounty being scanned content (bytes): Content of the artifact to be scan metadata (dict) Dict of metadata for the artifact chain (str): Chain we are operating on Returns: ScanResult: Result of this scan """ matches = self.rules.match(data=content) sysname, _, _, _, machine = os.uname() metadata = Verdict().set_scanner(operating_system=sysname, architecture=machine, vendor_version=yara.__version__) if matches: # author responsible for distilling multiple metadata values into a value for ScanResult metadata.set_malware_family(matches[0].rule) return ScanResult(bit=True, verdict=True, metadata=metadata.json()) metadata.set_malware_family('') return ScanResult(bit=True, verdict=False, metadata=metadata.json())
def test_add_two_extras_at_once(): # arrange verdict = Verdict().set_malware_family("Eicar") # act verdict.add_extras([("new_key", "string_value"), ("new_key1", { "other_key": "string_value" })]) # assert k, v = verdict.extra[0] assert k == 'new_key' assert v == "string_value" k, v = verdict.extra[1] assert k == 'new_key1' assert v == {"other_key": "string_value"}
def test_extra_array_scanner(): # arrange blob = { "malware_family": "Eicar", "domains": ["polyswarm.io"], "ip_addresses": ["192.168.0.1"], "stix": [{ "schema": "oasis-open/cti-stix2-json-schemas/master/schemas/common/hex.json", "signature": "a0" }], "scanner": { "extra": ["test"], "version": "1.0.0", "polyswarmclient_version": "2.0.2", "signatures_version": "2019", "vendor_version": "1.0.0", "environment": { "operating_system": "windows", "architecture": "x86" } }, } # assert assert Verdict.validate(blob)
def test_validate_all_output(): # arrange verdict = Verdict().set_malware_family("Eicar")\ .add_domain('polyswarm.io')\ .add_ip_address('192.168.0.1')\ .add_stix_signature( 'oasis-open/cti-stix2-json-schemas/master/schemas/common/hex.json', "a0" ) \ .set_scanner(operating_system="windows", architecture="x86", version="1.0.0", polyswarmclient_version="2.0.2", signatures_version="2019", vendor_version="1.0.0")\ .add_extra("new_key", {"other_key": "string_value"})\ .add_extra("new_key1", ["string_value"])\ .add_extra("new_key2", "string_value") result = { "malware_family": "Eicar", "domains": ["polyswarm.io"], "ip_addresses": ["192.168.0.1"], "stix": [{ "schema": "oasis-open/cti-stix2-json-schemas/master/schemas/common/hex.json", "signature": "a0" }], "scanner": { "version": "1.0.0", "polyswarmclient_version": "2.0.2", "signatures_version": "2019", "vendor_version": "1.0.0", "environment": { "operating_system": "windows", "architecture": "x86" } }, "new_key": { "other_key": "string_value", }, "new_key1": ["string_value"], "new_key2": "string_value" } # act blob = json.loads(verdict.json()) # assert assert Verdict.validate(blob) assert blob == result
def attach_siginfo(scan: 'ScanResult') -> 'ScanResult': """Attach shared engine metadata to ``scan`` metadata""" with suppress(AttributeError): scanner_info = engine_info.scanner_info() if scanner_info: meta = extract_verdict(scan) or Verdict().set_malware_family('') scan.metadata = meta.set_scanner(**scanner_info) return scan
def test_add_stix_object(): # arrange verdict = Verdict() # act verdict.add_stix_signature( 'oasis-open/cti-stix2-json-schemas/master/schemas/common/kill-chain-phase.json', { "kill_chain_name": 'asdf', "phase_name": "full" }) # assert assert verdict.stix[0][ 'schema'] == 'oasis-open/cti-stix2-json-schemas/master/schemas/common/kill-chain-phase.json' assert verdict.stix[0]['signature'] == { "kill_chain_name": 'asdf', "phase_name": "full" }
def test_builder_one_scanners_is_valid(): # arrange artifact = Verdict()\ .set_malware_family("Eicar") # act assertion = Assertion()\ .add_artifact(artifact) # assert assert Assertion.validate(json.loads(assertion.json()))
def test_add_artifact(): # arrange artifact = Verdict() \ .set_malware_family("Eicar") assertion = Assertion() # act assertion.add_artifact(artifact) # assert assert assertion.artifacts and assertion.artifacts[0] == artifact
def test_scanalytics(statsd, engine_info, use_async, scan_result, verbose_metrics, artifact_kind): is_error = isinstance(scan_result, Exception) args = (None, str(uuid4()), artifact_kind, b'content', {}, 'home') type_tag = 'type:%s' % ArtifactType.to_string(artifact_kind) if use_async: @scanalytics(statsd=statsd, engine_info=engine_info, verbose=verbose_metrics) async def scanfn(self, guid, artifact_type, content, metadata, chain): if is_error: raise scan_result return scan_result result = asyncio.run(scanfn(*args)) else: @scanalytics(statsd=statsd, engine_info=engine_info, verbose=verbose_metrics) def scanfn(self, guid, artifact_type, content, metadata, chain): if is_error: raise scan_result return scan_result result = scanfn(*args) statsd.timing.assert_called_once() assert isinstance(result.metadata, str) result_meta = Verdict.parse_raw(result.metadata) assert result_meta.scanner.signatures_version == engine_info.definitions_version assert result_meta.scanner.vendor_version == engine_info.engine_version if is_error: assert result_meta.__dict__['scan_error'] == scan_result.event_name assert result.bit is False statsd.increment.assert_called_once_with( SCAN_FAIL, tags=[type_tag, f'scan_error:{scan_result.event_name}'] ) else: assert result.verdict is scan_result.verdict assert result.bit is scan_result.bit verdict_tag = 'verdict:malicious' if scan_result.verdict else 'verdict:benign' if scan_result.bit is True: statsd.increment.assert_any_call(SCAN_SUCCESS, tags=[type_tag, verdict_tag]) if verbose_metrics: statsd.increment.assert_any_call( SCAN_VERDICT, tags=[type_tag, verdict_tag], ) assert statsd.increment.call_count == 2 else: assert statsd.increment.call_count == 1 elif scan_result.bit is False: if verbose_metrics: statsd.increment.assert_called_once_with(SCAN_NO_RESULT, tags=[type_tag])
async def scan(self, guid, artifact_type, content, metadata, chain): """Scan an artifact Args: guid (str): GUID of the bounty under analysis, use to track artifacts in the same bounty artifact_type (ArtifactType): Artifact type for the bounty being scanned content (bytes): Content of the artifact to be scan metadata (dict) Dict of metadata for the artifact chain (str): Chain we are operating on Returns: ScanResult: Result of this scan """ results = await asyncio.gather(*[ backend.scan(guid, artifact_type, content, chain) for backend in self.backends ]) # Unpack the results bits = [r.bit for r in results] verdicts = [r.verdict for r in results] confidences = [r.confidence for r in results] metadatas = [r.metadata for r in results] asserted_confidences = [c for b, c in zip(bits, confidences) if b] avg_confidence = sum(asserted_confidences) / len(asserted_confidences) # author responsible for distilling multiple metadata values into a value for ScanResult metadata = metadatas[0] try: metadatas = [ json.loads(metadata) for metadata in metadatas if metadata and Verdict.validate(json.loads(metadata)) ] if metadatas: metadata = Verdict().set_malware_family(metadatas[0].get( 'malware_family', '')).json() except json.JSONDecodeError: logger.exception(f'Error decoding sub metadata') return ScanResult(bit=any(bits), verdict=any(verdicts), confidence=avg_confidence, metadata=metadata)
def test_invalid_artifact_throws_value_error(): # arrange artifact = Verdict()\ .add_domain("polyswarm.io") # act assertion = Assertion()\ .add_artifact(artifact) # assert with pytest.raises(ValueError): assertion.json()
def test_add_artifacts(): # arrange artifact = Verdict() \ .set_malware_family("Eicar") assertion = Assertion() # act assertion.add_artifacts([artifact for i in range(0, 3)]) # assert assert assertion.artifacts assert len(assertion.artifacts) == 3 assert assertion.artifacts[0] == artifact
def test_scanner_null_environemnt(): # arrange verdict = Verdict().set_malware_family("Eicar") # act verdict.set_scanner(version="1.0.0", polyswarmclient_version="2.0.2", signatures_version="2019", vendor_version="1.0.0") # assert Verdict.validate(json.loads(verdict.json()))
def test_validate_two_domains_at_once(): # arrange verdict = Verdict().set_malware_family("Eicar") # act verdict.add_domains(['polyswarm.io', 'polyswarm.network']) # assert assert Verdict.validate(json.loads(verdict.json()))