SSDeepSimilarity
This script finds similar files that can be related to each other by fuzzy hash (SSDeep).
python · Common Scripts
Source
import tempfile import traceback import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 HEADERS = "ssdeep,1.1--blocksize:hash:hash,filename\n" """ COMMAND FUNCTION """ def _handle_existing_outputs(anchor_hash: str, output_key: str, new_hashes_outputs: list): context = demisto.get(demisto.context(), f"{output_key}") if not context: context = [] elif not isinstance(context, list): context = [context] context = list(filter(lambda item: item.get("SourceHash") == anchor_hash, context)) if context: context = context[0].get("compared_hashes") new_hashes = [current_hash.get("hash") for current_hash in new_hashes_outputs] res = [] for item in context: if item.get("hash") not in new_hashes: res.append(item) res += new_hashes_outputs return res def _handle_inputs(args: dict): anchor_hash = args.get("ssdeep_hash") if not anchor_hash: raise ValueError("Please provide an hash to compare to.") hashes_to_compare = argToList(args.get("ssdeep_hashes_to_compare")) if not hashes_to_compare: raise ValueError("Please provide at least one hash to compare with.") output_key = args.get("output_key", "SSDeepSimilarity") return anchor_hash, hashes_to_compare, output_key def _format_results(results: list) -> List[dict]: """ Args: results: a list of results with the following format: ['"<hash>","<anchor_hash>",<score>'] Returns: a list of dictionaries containing the hash and score """ formatted_res = [] # Remove last empty value returned from the process if not results[-1]: results = results[:-1] for result in results: result = result.split(",") formatted_res.append({"hash": result[0].strip('"'), "similarityValue": int(result[2])}) return formatted_res def run_ssdeep_command(anchor_hash: str, hashes_to_compare: str): with tempfile.NamedTemporaryFile() as anchor_hashes_file, tempfile.NamedTemporaryFile() as hashes_to_compare_file: anchor_hashes_file.write(bytes(anchor_hash, encoding="utf-8")) anchor_hashes_file.flush() hashes_to_compare_file.write(bytes(hashes_to_compare, encoding="utf-8")) hashes_to_compare_file.flush() stream = os.popen(f"ssdeep -k {anchor_hashes_file.name} {hashes_to_compare_file.name} -c -a") # nosec return stream.read().split("\n") def compare_ssdeep(anchor_hash: str, hashes_to_compare: list, output_key: str) -> CommandResults: hashes_list_to_file = HEADERS anchor_hash_to_file = f'{HEADERS}{anchor_hash},"{anchor_hash}"\n' for current_hash in hashes_to_compare: hashes_list_to_file += f'{current_hash},"{current_hash}"\n' res = run_ssdeep_command(anchor_hash_to_file, hashes_list_to_file) hashes_outputs = _format_results(res) hashes_outputs_merged = _handle_existing_outputs(anchor_hash, output_key, hashes_outputs) md = tableToMarkdown(anchor_hash, hashes_outputs) return CommandResults( outputs_prefix=output_key, readable_output=md, outputs_key_field="SourceHash", outputs={"SourceHash": anchor_hash, "compared_hashes": hashes_outputs_merged}, ) """ MAIN FUNCTION """ def main(): try: args = demisto.args() anchor_hash, hashes_to_compare, output_key = _handle_inputs(args) res = compare_ssdeep(anchor_hash, hashes_to_compare, output_key) return_results(res) except Exception as ex: demisto.error(traceback.format_exc()) # print the traceback return_error(f"Failed to compare ssdeep hashes. Error: {ex!s}") if __name__ in ("__main__", "__builtin__", "builtins"): main()
README
This script finds similar files that can be related to each other by fuzzy hash (SSDeep).
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | |
| Cortex XSOAR Version | 5.5.0 |
Inputs
| Argument Name | Description |
|---|---|
| ssdeep_hash | The SSDeep hash to check for similarity against. |
| ssdeep_hashes_to_compare | A list of SSDeep hashes to check for similarity to the ssdeep_hash input. |
| output_key | The context key to which the list of SSDeep hashes will be outputted. In case used, the default outputs will not contain the results. In order to get results, replace the SSDeepSimilarity in default outputs with the output_key provided. |
Outputs
| Path | Description | Type |
|---|---|---|
| SSDeepSimilarity.compared_hashes.similarityValue | The difference calculation score between the ssdeep_hash and the compared hash. | number |
| SSDeepSimilarity.compared_hashes.hash | The hash compared to the ssdeep_hash. | string |
Please note the outputs are changed to use output_key instead of ‘SSDeepSimilarity’ if provided.