From 83fd44ed1347880efe52e233f52d74201cd5d24f Mon Sep 17 00:00:00 2001 From: Jason Zhang Date: Thu, 29 Jul 2021 12:13:31 +0100 Subject: [PATCH] add vmware_nsx module --- Pipfile | 2 + README.md | 1 + documentation/logos/vmware_nsx.png | Bin 0 -> 53372 bytes .../website/expansion/lastline_query.json | 2 +- .../website/expansion/lastline_submit.json | 2 +- .../website/expansion/vmware_nsx.json | 14 + .../website/import_mod/lastline_import.json | 2 +- .../modules/expansion/lastline_query.py | 2 + .../modules/expansion/lastline_submit.py | 2 + misp_modules/modules/expansion/vmware_nsx.py | 615 ++++++++++++++++++ .../modules/import_mod/lastline_import.py | 2 + 11 files changed, 641 insertions(+), 3 deletions(-) create mode 100644 documentation/logos/vmware_nsx.png create mode 100644 documentation/website/expansion/vmware_nsx.json create mode 100644 misp_modules/modules/expansion/vmware_nsx.py diff --git a/Pipfile b/Pipfile index f445eb0..4057e4f 100644 --- a/Pipfile +++ b/Pipfile @@ -65,6 +65,8 @@ socialscan = "*" dnsdb2 = "*" clamd = "*" aiohttp = ">=3.7.4" +tau-clients = "*" +vt-py = ">=0.7.1" [requires] python_version = "3" diff --git a/README.md b/README.md index 3d21bef..777fd8d 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ For more information: [Extending MISP with Python modules](https://www.misp-proj * [virustotal](misp_modules/modules/expansion/virustotal.py) - an expansion module to query the [VirusTotal](https://www.virustotal.com/gui/home) API with a high request rate limit required. (More details about the API: [here](https://developers.virustotal.com/reference)) * [virustotal_public](misp_modules/modules/expansion/virustotal_public.py) - an expansion module to query the [VirusTotal](https://www.virustotal.com/gui/home) API with a public key and a low request rate limit. (More details about the API: [here](https://developers.virustotal.com/reference)) * [VMray](misp_modules/modules/expansion/vmray_submit.py) - a module to submit a sample to VMray. +* [VMware NSX](misp_modules/modules/expansion/vmware_nsx.py) - a module to enrich a file or URL with VMware NSX Defender. * [VulnDB](misp_modules/modules/expansion/vulndb.py) - a module to query [VulnDB](https://www.riskbasedsecurity.com/). * [Vulners](misp_modules/modules/expansion/vulners.py) - an expansion module to expand information about CVEs using Vulners API. * [whois](misp_modules/modules/expansion/whois.py) - a module to query a local instance of [uwhois](https://github.com/rafiot/uwhoisd). diff --git a/documentation/logos/vmware_nsx.png b/documentation/logos/vmware_nsx.png new file mode 100644 index 0000000000000000000000000000000000000000..4d4ba96e16ffdded17202903cda9962ce13e6d44 GIT binary patch literal 53372 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 c_qI>ZYy_l9G?%w&a pymisp.MISPEvent: + """ + Parse the analysis result into a MISP event. + + :param str analysis_link: the analysis link + :param dict[str, any] result: the JSON returned by the analysis client. + :rtype: pymisp.MISPEvent + :return: a MISP event + """ + misp_event = pymisp.MISPEvent() + + # Add analysis subject info + if "url" in result["analysis_subject"]: + o = pymisp.MISPObject("url") + o.add_attribute("url", result["analysis_subject"]["url"]) + else: + o = pymisp.MISPObject("file") + o.add_attribute("md5", type="md5", value=result["analysis_subject"]["md5"]) + o.add_attribute("sha1", type="sha1", value=result["analysis_subject"]["sha1"]) + o.add_attribute("sha256", type="sha256", value=result["analysis_subject"]["sha256"]) + o.add_attribute( + "mimetype", + category="Payload delivery", + type="mime-type", + value=result["analysis_subject"]["mime_type"] + ) + misp_event.add_object(o) + + # Add HTTP requests from url analyses + network_dict = result.get("report", {}).get("analysis", {}).get("network", {}) + for request in network_dict.get("requests", []): + parsed_uri = parse.urlparse(request["url"]) + o = pymisp.MISPObject(name="http-request") + o.add_attribute("host", parsed_uri.netloc) + o.add_attribute("method", "GET") + o.add_attribute("uri", request["url"]) + o.add_attribute("ip-dst", request["ip"]) + misp_event.add_object(o) + + # Add network behaviors from files + for subject in result.get("report", {}).get("analysis_subjects", []): + + # Add DNS requests + for dns_query in subject.get("dns_queries", []): + hostname = dns_query.get("hostname") + # Skip if it is an IP address + try: + if hostname == "wpad" or hostname == "localhost": + continue + # Invalid hostname, e.g., hostname: '2.2.0.10.in-addr.arpa. + if hostname[-1] == ".": + continue + _ = ipaddress.ip_address(hostname) + continue + except ValueError: + pass + + o = pymisp.MISPObject(name="domain-ip") + o.add_attribute("hostname", type="hostname", value=hostname) + for ip in dns_query.get("results", []): + o.add_attribute("ip", type="ip-dst", value=ip) + + misp_event.add_object(o) + + # Add HTTP conversations (as network connection and as http request) + for http_conversation in subject.get("http_conversations", []): + o = pymisp.MISPObject(name="network-connection") + o.add_attribute("ip-src", http_conversation["src_ip"]) + o.add_attribute("ip-dst", http_conversation["dst_ip"]) + o.add_attribute("src-port", http_conversation["src_port"]) + o.add_attribute("dst-port", http_conversation["dst_port"]) + o.add_attribute("hostname-dst", http_conversation["dst_host"]) + o.add_attribute("layer3-protocol", "IP") + o.add_attribute("layer4-protocol", "TCP") + o.add_attribute("layer7-protocol", "HTTP") + misp_event.add_object(o) + + method, path, http_version = http_conversation["url"].split(" ") + if http_conversation["dst_port"] == 80: + uri = "http://{}{}".format(http_conversation["dst_host"], path) + else: + uri = "http://{}:{}{}".format( + http_conversation["dst_host"], + http_conversation["dst_port"], + path + ) + o = pymisp.MISPObject(name="http-request") + o.add_attribute("host", http_conversation["dst_host"]) + o.add_attribute("method", method) + o.add_attribute("uri", uri) + o.add_attribute("ip-dst", http_conversation["dst_ip"]) + misp_event.add_object(o) + + # Add sandbox info like score and sandbox type + o = pymisp.MISPObject(name="sandbox-report") + sandbox_type = "saas" if tau_clients.is_task_hosted(analysis_link) else "on-premise" + o.add_attribute("score", result["score"]) + o.add_attribute("sandbox-type", sandbox_type) + o.add_attribute("{}-sandbox".format(sandbox_type), "vmware-nsx-defender") + o.add_attribute("permalink", analysis_link) + misp_event.add_object(o) + + # Add behaviors + o = pymisp.MISPObject(name="sb-signature") + o.add_attribute("software", "VMware NSX Defender") + for activity in result.get("malicious_activity", []): + a = pymisp.MISPAttribute() + a.from_dict(type="text", value=activity) + o.add_attribute("signature", **a) + misp_event.add_object(o) + + # Add mitre techniques + for techniques in result.get("activity_to_mitre_techniques", {}).values(): + for technique in techniques: + for misp_technique_id, misp_technique_name in self.techniques_galaxy.items(): + if technique["id"].casefold() in misp_technique_id.casefold(): + # If report details a sub-technique, trust the match + # Otherwise trust it only if the MISP technique is not a sub-technique + if "." in technique["id"] or "." not in misp_technique_id: + misp_event.add_tag(misp_technique_name) + break + return misp_event + + +def _parse_submission_response(response: Dict[str, Any]) -> Tuple[str, List[str]]: + """ + Parse the response from "submit_*" methods. + + :param dict[str, any] response: the client response + :rtype: tuple(str, list[str]) + :return: the task_uuid and whether the analysis is available + :raises ValueError: in case of any error + """ + task_uuid = response.get("task_uuid") + if not task_uuid: + raise ValueError("Submission failed, unable to process the data") + if response.get("score") is not None: + tags = [WORKFLOW_COMPLETE_TAG] + else: + tags = [WORKFLOW_INCOMPLETE_TAG] + return task_uuid, tags + + +def _unzip(zipped_data: bytes, password: bytes = DEFAULT_ZIP_PASSWORD) -> bytes: + """ + Unzip the data. + + :param bytes zipped_data: the zipped data + :param bytes password: the password + :rtype: bytes + :return: the unzipped data + :raises ValueError: in case of any error + """ + try: + data_file_object = io.BytesIO(zipped_data) + with zipfile.ZipFile(data_file_object) as zip_file: + sample_hash_name = zip_file.namelist()[0] + return zip_file.read(sample_hash_name, password) + except (IOError, ValueError) as e: + raise ValueError(str(e)) + + +def _download_from_vt(client: vt.Client, file_hash: str) -> bytes: + """ + Download file from VT. + + :param vt.Client client: the VT client + :param str file_hash: the file hash + :rtype: bytes + :return: the downloaded data + :raises ValueError: in case of any error + """ + try: + buffer = io.BytesIO() + client.download_file(file_hash, buffer) + buffer.seek(0, 0) + return buffer.read() + except (IOError, vt.APIError) as e: + raise ValueError(str(e)) + finally: + # vt.Client likes to free resources at shutdown, and it can be used as context to ease that + # Since the structure of the module does not play well with how MISP modules are organized + # let's play nice and close connections pro-actively (opened by "download_file") + if client: + client.close() + + +def _get_analysis_tags( + clients: Dict[str, nsx_defender.AnalysisClient], + task_uuid: str, +) -> List[str]: + """ + Get the analysis tags of a task. + + :param dict[str, nsx_defender.AnalysisClient] clients: the analysis clients + :param str task_uuid: the task uuid + :rtype: list[str] + :return: the analysis tags + :raises exceptions.ApiError: in case of client errors + :raises exceptions.CommunicationError: in case of client communication errors + """ + client = clients[DEFAULT_ENDPOINT] + response = client.get_analysis_tags(task_uuid) + tags = set([]) + for tag in response.get("analysis_tags", []): + tag_header = None + tag_type = tag["data"]["type"] + if tag_type == "av_family": + tag_header = "av-fam" + elif tag_type == "av_class": + tag_header = "av-cls" + elif tag_type == "lastline_malware": + tag_header = "nsx" + if tag_header: + tags.add("{}:{}".format(tag_header, tag["data"]["value"])) + return sorted(tags) + + +def _get_latest_analysis( + clients: Dict[str, nsx_defender.AnalysisClient], + file_hash: str, +) -> Optional[str]: + """ + Get the latest analysis. + + :param dict[str, nsx_defender.AnalysisClient] clients: the analysis clients + :param str file_hash: the hash of the file + :rtype: str|None + :return: the task uuid if present, None otherwise + :raises exceptions.ApiError: in case of client errors + :raises exceptions.CommunicationError: in case of client communication errors + """ + def _parse_expiration(task_info: Dict[str, str]) -> datetime.datetime: + """ + Parse expiration time of a task + + :param dict[str, str] task_info: the task + :rtype: datetime.datetime + :return: the parsed datetime object + """ + return datetime.datetime.strptime(task_info["expires"], "%Y-%m-%d %H:%M:%S") + results = [] + for data_center, client in clients.items(): + response = client.query_file_hash(file_hash=file_hash) + for task in response.get("tasks", []): + results.append(task) + if results: + return sorted(results, key=_parse_expiration)[-1]["task_uuid"] + else: + return None + + +def _get_mitre_techniques_galaxy(misp_client: pymisp.PyMISP) -> Dict[str, str]: + """ + Get all the MITRE techniques from the MISP galaxy. + + :param pymisp.PyMISP misp_client: the MISP client + :rtype: dict[str, str] + :return: all techniques indexed by their id + """ + galaxy_attack_patterns = misp_client.get_galaxy( + galaxy=GALAXY_ATTACK_PATTERNS_UUID, + withCluster=True, + pythonify=True, + ) + ret = {} + for cluster in galaxy_attack_patterns.clusters: + ret[cluster.value] = cluster.tag_name + return ret + + +def introspection() -> Dict[str, Union[str, List[str]]]: + """ + Implement interface. + + :return: the supported MISP attributes + :rtype: dict[str, list[str]] + """ + return mispattributes + + +def version() -> Dict[str, Union[str, List[str]]]: + """ + Implement interface. + + :return: the module config inside another dictionary + :rtype: dict[str, list[str]] + """ + moduleinfo["config"] = moduleconfig + return moduleinfo + + +def handler(q: Union[bool, str] = False) -> Union[bool, Dict[str, Any]]: + """ + Implement interface. + + :param bool|str q: the input received + :rtype: bool|dict[str, any] + """ + if q is False: + return False + + request = json.loads(q) + config = request.get("config", {}) + + # Load the client to connect to VMware NSX ATA (hard-fail) + try: + analysis_url = config.get("analysis_url") + login_params = { + "key": config["analysis_key"], + "api_token": config["analysis_api_token"], + } + # If 'analysis_url' is specified we are connecting on-premise + if analysis_url: + analysis_clients = { + DEFAULT_ENDPOINT: nsx_defender.AnalysisClient( + api_url=analysis_url, + login_params=login_params, + verify_ssl=bool(config.get("analysis_verify_ssl", True)), + ) + } + logger.info("Connected NSX AnalysisClient to on-premise infrastructure") + else: + analysis_clients = { + data_center: nsx_defender.AnalysisClient( + api_url=tau_clients.NSX_DEFENDER_ANALYSIS_URLS[data_center], + login_params=login_params, + verify_ssl=bool(config.get("analysis_verify_ssl", True)), + ) for data_center in [ + tau_clients.NSX_DEFENDER_DC_WESTUS, + tau_clients.NSX_DEFENDER_DC_NLEMEA, + ] + } + logger.info("Connected NSX AnalysisClient to hosted infrastructure") + except KeyError as ke: + logger.error("Integration with VMware NSX ATA failed to connect: %s", str(ke)) + return {"error": "Error connecting to VMware NSX ATA: {}".format(ke)} + + # Load the client to connect to MISP (soft-fail) + try: + misp_client = pymisp.PyMISP( + url=config["misp_url"], + key=config["misp_key"], + ssl=bool(config.get("misp_verify_ssl", True)), + ) + except (KeyError, pymisp.PyMISPError): + logger.error("Integration with pyMISP disabled: no MITRE techniques tags") + misp_client = None + + # Load the client to connect to VT (soft-fail) + try: + vt_client = vt.Client(apikey=config["vt_key"]) + except (KeyError, ValueError): + logger.error("Integration with VT disabled: no automatic download of samples") + vt_client = None + + # Decode and issue the request + try: + if request["attribute"]["type"] == "url": + sample_url = request["attribute"]["value"] + response = analysis_clients[DEFAULT_ENDPOINT].submit_url(sample_url) + task_uuid, tags = _parse_submission_response(response) + else: + if request["attribute"]["type"] == "malware-sample": + # Raise TypeError + file_data = _unzip(base64.b64decode(request["attribute"]["data"])) + file_name = request["attribute"]["value"].split("|", 1)[0] + hash_value = hashlib.sha1(file_data).hexdigest() + elif request["attribute"]["type"] == "attachment": + # Raise TypeError + file_data = base64.b64decode(request["attribute"]["data"]) + file_name = request["attribute"].get("value") + hash_value = hashlib.sha1(file_data).hexdigest() + else: + hash_value = request["attribute"]["value"] + file_data = None + file_name = "{}.bin".format(hash_value) + # Check whether we have a task for that file + tags = [] + task_uuid = _get_latest_analysis(analysis_clients, hash_value) + if not task_uuid: + # If we have no analysis, download the sample from VT + if not file_data: + if not vt_client: + raise ValueError("No file available locally and VT is disabled") + file_data = _download_from_vt(vt_client, hash_value) + tags.append(VT_DOWNLOAD_TAG) + # ... and submit it (_download_from_vt fails if no sample availabe) + response = analysis_clients[DEFAULT_ENDPOINT].submit_file(file_data, file_name) + task_uuid, _tags = _parse_submission_response(response) + tags.extend(_tags) + except KeyError as e: + logger.error("Error parsing input: %s", request["attribute"]) + return {"error": "Error parsing input: {}".format(e)} + except TypeError as e: + logger.error("Error decoding input: %s", request["attribute"]) + return {"error": "Error decoding input: {}".format(e)} + except ValueError as e: + logger.error("Error processing input: %s", request["attribute"]) + return {"error": "Error processing input: {}".format(e)} + except (exceptions.CommunicationError, exceptions.ApiError) as e: + logger.error("Error issuing API call: %s", str(e)) + return {"error": "Error issuing API call: {}".format(e)} + else: + analysis_link = tau_clients.get_task_link( + uuid=task_uuid, + analysis_url=analysis_clients[DEFAULT_ENDPOINT].base, + prefer_load_balancer=True, + ) + + # Return partial results if the analysis has yet to terminate + try: + tags.extend(_get_analysis_tags(analysis_clients, task_uuid)) + report = analysis_clients[DEFAULT_ENDPOINT].get_result(task_uuid) + except (exceptions.CommunicationError, exceptions.ApiError) as e: + logger.error("Error retrieving the report: %s", str(e)) + return { + "results": { + "types": "link", + "categories": ["External analysis"], + "values": analysis_link, + "tags": tags, + } + } + + # Return the enrichment + try: + techniques_galaxy = None + if misp_client: + techniques_galaxy = _get_mitre_techniques_galaxy(misp_client) + result_parser = ResultParser(techniques_galaxy=techniques_galaxy) + misp_event = result_parser.parse(analysis_link, report) + for tag in tags: + if tag not in frozenset([WORKFLOW_COMPLETE_TAG]): + misp_event.add_tag(tag) + return { + "results": { + key: json.loads(misp_event.to_json())[key] + for key in ("Attribute", "Object", "Tag") + if (key in misp_event and misp_event[key]) + } + } + except pymisp.PyMISPError as e: + logger.error("Error parsing the report: %s", str(e)) + return {"error": "Error parsing the report: {}".format(e)} + + +def main(): + """Main function used to test basic functionalities of the module.""" + parser = argparse.ArgumentParser() + parser.add_argument( + "-c", + "--config-file", + dest="config_file", + required=True, + help="the configuration file used for testing", + ) + parser.add_argument( + "-t", + "--test-attachment", + dest="test_attachment", + default=None, + help="the path to a test attachment", + ) + args = parser.parse_args() + conf = configparser.ConfigParser() + conf.read(args.config_file) + config = { + "analysis_verify_ssl": conf.getboolean("analysis", "analysis_verify_ssl"), + "analysis_key": conf.get("analysis", "analysis_key"), + "analysis_api_token": conf.get("analysis", "analysis_api_token"), + "vt_key": conf.get("vt", "vt_key"), + "misp_url": conf.get("misp", "misp_url"), + "misp_verify_ssl": conf.getboolean("misp", "misp_verify_ssl"), + "misp_key": conf.get("misp", "misp_key"), + } + + # TEST 1: submit a URL + j = json.dumps( + { + "config": config, + "attribute": { + "type": "url", + "value": "https://www.google.com", + } + } + ) + print(json.dumps(handler(j), indent=4, sort_keys=True)) + + # TEST 2: submit a file attachment + if args.test_attachment: + with open(args.test_attachment, "rb") as f: + data = f.read() + j = json.dumps( + { + "config": config, + "attribute": { + "type": "attachment", + "value": "test.docx", + "data": base64.b64encode(data).decode("utf-8"), + } + } + ) + print(json.dumps(handler(j), indent=4, sort_keys=True)) + + # TEST 3: submit a file hash that is known by NSX ATA + j = json.dumps( + { + "config": config, + "attribute": { + "type": "md5", + "value": "002c56165a0e78369d0e1023ce044bf0", + } + } + ) + print(json.dumps(handler(j), indent=4, sort_keys=True)) + + # TEST 4 : submit a file hash that is NOT known byt NSX ATA + j = json.dumps( + { + "config": config, + "attribute": { + "type": "sha1", + "value": "2aac25ecdccf87abf6f1651ef2ffb30fcf732250", + } + } + ) + print(json.dumps(handler(j), indent=4, sort_keys=True)) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/misp_modules/modules/import_mod/lastline_import.py b/misp_modules/modules/import_mod/lastline_import.py index 37f6249..3307852 100644 --- a/misp_modules/modules/import_mod/lastline_import.py +++ b/misp_modules/modules/import_mod/lastline_import.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 """ +Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. + Module (type "import") to import a Lastline report from an analysis link. """ import json