From 57af98720d950d4880436fb888dca702bb7aba76 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Tue, 7 Aug 2018 18:13:25 +0200 Subject: [PATCH 01/16] fix: [cleanup] Quick clean up on exception type --- misp_modules/modules/expansion/rbl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misp_modules/modules/expansion/rbl.py b/misp_modules/modules/expansion/rbl.py index da8c5fb..49de421 100644 --- a/misp_modules/modules/expansion/rbl.py +++ b/misp_modules/modules/expansion/rbl.py @@ -6,7 +6,7 @@ try: resolver = dns.resolver.Resolver() resolver.timeout = 0.2 resolver.lifetime = 0.2 -except: +except ModuleNotFoundError: print("dnspython3 is missing, use 'pip install dnspython3' to install it.") sys.exit(0) From bb6002a3ff48432915d96e97351e092b78a3c149 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Tue, 7 Aug 2018 18:14:29 +0200 Subject: [PATCH 02/16] fix: [cleanup] Quick clean up on yaml load function --- misp_modules/modules/expansion/sigma_syntax_validator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misp_modules/modules/expansion/sigma_syntax_validator.py b/misp_modules/modules/expansion/sigma_syntax_validator.py index 0d5226f..6452654 100644 --- a/misp_modules/modules/expansion/sigma_syntax_validator.py +++ b/misp_modules/modules/expansion/sigma_syntax_validator.py @@ -21,7 +21,7 @@ def handler(q=False): return misperrors config = SigmaConfiguration() try: - parser = SigmaParser(yaml.load(request.get('sigma')), config) + parser = SigmaParser(yaml.safe_load(request.get('sigma')), config) result = ("Syntax valid: {}".format(parser.values)) except Exception as e: result = ("Syntax error: {}".format(str(e))) From 0666a60b3dbc1a5f2b54e546ff70b08e7f359fba Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Tue, 7 Aug 2018 18:15:15 +0200 Subject: [PATCH 03/16] fix: [cleanup] Quick clean up on exception type --- misp_modules/modules/expansion/yara_syntax_validator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misp_modules/modules/expansion/yara_syntax_validator.py b/misp_modules/modules/expansion/yara_syntax_validator.py index 4953c41..57c71ea 100644 --- a/misp_modules/modules/expansion/yara_syntax_validator.py +++ b/misp_modules/modules/expansion/yara_syntax_validator.py @@ -2,7 +2,7 @@ import json import requests try: import yara -except: +except ModuleNotFoundError: print("yara is missing, use 'pip3 install yara' to install it.") misperrors = {'error': 'Error'} From d15cbe58fe47d137554883084e02540b7f2ab9a8 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Thu, 30 Aug 2018 20:41:49 +0200 Subject: [PATCH 04/16] fix: Quick cleanup --- misp_modules/modules/export_mod/goamlexport.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/misp_modules/modules/export_mod/goamlexport.py b/misp_modules/modules/export_mod/goamlexport.py index 961a11b..f09f2e6 100644 --- a/misp_modules/modules/export_mod/goamlexport.py +++ b/misp_modules/modules/export_mod/goamlexport.py @@ -1,4 +1,5 @@ -import json, datetime, base64 +import json +import base64 from pymisp import MISPEvent from collections import defaultdict, Counter @@ -67,7 +68,7 @@ class GoAmlGeneration(object): try: report_code.append(obj.get_attributes_by_relation('report-code')[0].value.split(' ')[0]) currency_code.append(obj.get_attributes_by_relation('currency-code')[0].value) - except: + except IndexError: print('report_code or currency_code error') self.uuids, self.report_codes, self.currency_codes = uuids, report_code, currency_code From 35f3a5e43f92eff195f98fc312fa53f922155090 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Thu, 30 Aug 2018 20:45:29 +0200 Subject: [PATCH 05/16] fix: Quick cleanup --- misp_modules/modules/expansion/rbl.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/misp_modules/modules/expansion/rbl.py b/misp_modules/modules/expansion/rbl.py index 49de421..7aac103 100644 --- a/misp_modules/modules/expansion/rbl.py +++ b/misp_modules/modules/expansion/rbl.py @@ -96,13 +96,12 @@ def handler(q=False): txt = resolver.query(query,'TXT') listed.append(query) info.append(str(txt[0])) - except: + except Exception: continue result = {} for l, i in zip(listed, info): result[l] = i - r = {'results': [{'types': mispattributes.get('output'), 'values': json.dumps(result)}]} - return r + return {'results': [{'types': mispattributes.get('output'), 'values': json.dumps(result)}]} def introspection(): return mispattributes From 179430d69db5e45fa0c0e815a934fd87b69135c1 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Fri, 31 Aug 2018 21:38:53 +0200 Subject: [PATCH 06/16] fix: Some cleanup and output types fixed - hashes types specified in output --- misp_modules/modules/expansion/virustotal.py | 304 ++++++++----------- 1 file changed, 133 insertions(+), 171 deletions(-) mode change 100755 => 100644 misp_modules/modules/expansion/virustotal.py diff --git a/misp_modules/modules/expansion/virustotal.py b/misp_modules/modules/expansion/virustotal.py old mode 100755 new mode 100644 index 3997ee6..404f621 --- a/misp_modules/modules/expansion/virustotal.py +++ b/misp_modules/modules/expansion/virustotal.py @@ -2,201 +2,163 @@ import json import requests from requests import HTTPError import base64 +from collections import defaultdict misperrors = {'error': 'Error'} mispattributes = {'input': ['hostname', 'domain', "ip-src", "ip-dst", "md5", "sha1", "sha256", "sha512"], 'output': ['domain', "ip-src", "ip-dst", "text", "md5", "sha1", "sha256", "sha512", "ssdeep", - "authentihash", "filename"] - } + "authentihash", "filename"]} # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '2', 'author': 'Hannah Ward', +moduleinfo = {'version': '3', 'author': 'Hannah Ward', 'description': 'Get information from virustotal', 'module-type': ['expansion']} # config fields that your code expects from the site admin moduleconfig = ["apikey", "event_limit"] -limit = 5 # Default -comment = '%s: Enriched via VT' +comment = '{}: Enriched via VirusTotal' +hash_types = ["md5", "sha1", "sha256", "sha512"] + +class VirusTotalRequest(object): + def __init__(self, config): + self.apikey = config['apikey'] + self.limit = int(config.get('event_limit', 5)) + self.base_url = "https://www.virustotal.com/vtapi/v2/{}/report" + self.results = defaultdict(set) + self.to_return = [] + self.input_types_mapping = {'ip-src': self.get_ip, 'ip-dst': self.get_ip, + 'domain': self.get_domain, 'hostname': self.get_domain, + 'md5': self.get_hash, 'sha1': self.get_hash, + 'sha256': self.get_hash, 'sha512': self.get_hash} + self.output_types_mapping = {'submission_names': 'filename', 'ssdeep': 'ssdeep', + 'authentihash': 'authentihash', 'ITW_urls': 'url'} + + def parse_request(self, attribute_type, attribute_value): + error = self.input_types_mapping[attribute_type](attribute_value) + if error is not None: + return error + for key, values in self.results.items(): + if isinstance(key, tuple): + types, comment = key + self.to_return.append({'types': list(types), 'values': list(values), 'comment': comment}) + else: + self.to_return.append({'types': key, 'values': list(values)}) + return self.to_return + def get_domain(self, domain, do_not_recurse=False): + req = requests.get(self.base_url.format('domain'), params={'domain': domain, 'apikey': self.apikey}) + try: + req.raise_for_status() + req = req.json() + except HTTPError as e: + return str(e) + if req["response_code"] == 0: + # Nothing found + return [] + if "resolutions" in req: + for res in req["resolutions"][:self.limit]: + ip_address = res["ip_address"] + self.results[(("ip-dst", "ip-src"), comment.format(domain))].add(ip_address) + # Pivot from here to find all domain info + if not do_not_recurse: + error = self.get_ip(ip_address, True) + if error is not None: + return error + self.get_more_info(req) + + def get_hash(self, _hash): + req = requests.get(self.base_url.format('file'), params={'resource': _hash, 'apikey': self.apikey, 'allinfo': 1}) + try: + req.raise_for_status() + req = req.json() + except HTTPError as e: + return str(e) + if req["response_code"] == 0: + # Nothing found + return [] + self.get_more_info(req) + + def get_ip(self, ip, do_not_recurse=False): + req = requests.get(self.base_url.format('ip-address'), params={'ip': ip, 'apikey': self.apikey}) + try: + req.raise_for_status() + req = req.json() + except HTTPError as e: + return str(e) + if req["response_code"] == 0: + # Nothing found + return [] + if "resolutions" in req: + for res in req["resolutions"][:self.limit]: + hostname = res["hostname"] + self.results[(("domain",), comment.format(ip))].add(hostname) + # Pivot from here to find all domain info + if not do_not_recurse: + error = self.get_domain(hostname, True) + if error is not None: + return error + self.get_more_info(req) + + def find_all(self, data): + hashes = [] + if isinstance(data, dict): + for key, value in data.items(): + if key in hash_types: + print(key) + self.results[key].add(value) + hashes.append(value) + else: + if isinstance(value, (dict, list)): + hashes.extend(self.find_all(value)) + elif isinstance(data, list): + for d in data: + hashes.extend(self.find_all(d)) + return hashes + + def get_more_info(self, req): + # Get all hashes first + hashes = self.find_all(req) + for h in hashes[:self.limit]: + # Search VT for some juicy info + try: + data = requests.get(self.base_url.format('file'), params={'resource': h, 'apikey': apikey, 'allinfo': 1}).json() + except Exception: + continue + # Go through euch key and check if it exists + for VT_type, MISP_type in self.output_types_mapping.items(): + if VT_type in data: + self.results[((MISP_type,), comment.format(h))].add(data[VT_type]) + # Get the malware sample + sample = requests.get(self.base_url[:-6].format('file/download'), params={'hash': h, 'apikey': apikey}) + malsample = sample.content + # It is possible for VT to not give us any submission names + if "submission_names" in data: + self.to_return.append({"types": ["malware-sample"], "categories": ["Payload delivery"], + "values": data["submimssion_names"], "data": str(base64.b64encore(malsample), 'utf-8')}) def handler(q=False): - global limit if q is False: return False - q = json.loads(q) - - key = q["config"]["apikey"] - limit = int(q["config"].get("event_limit", 5)) - - r = {"results": []} - - if "ip-src" in q: - r["results"] += getIP(q["ip-src"], key) - if "ip-dst" in q: - r["results"] += getIP(q["ip-dst"], key) - if "domain" in q: - r["results"] += getDomain(q["domain"], key) - if 'hostname' in q: - r["results"] += getDomain(q['hostname'], key) - if 'md5' in q: - r["results"] += getHash(q['md5'], key) - if 'sha1' in q: - r["results"] += getHash(q['sha1'], key) - if 'sha256' in q: - r["results"] += getHash(q['sha256'], key) - if 'sha512' in q: - r["results"] += getHash(q['sha512'], key) - - uniq = [] - for res in r["results"]: - if res not in uniq: - uniq.append(res) - r["results"] = uniq - return r - - -def getHash(hash, key, do_not_recurse=False): - req = requests.get("https://www.virustotal.com/vtapi/v2/file/report", - params={"allinfo": 1, "apikey": key, 'resource': hash}) - try: - req.raise_for_status() - req = req.json() - except HTTPError as e: - misperrors['error'] = str(e) + if not q.get('config') or not q['config'].get('apikey'): + misperrors['error']: "A VirusTotal api key is required for this module." return misperrors - - if req["response_code"] == 0: - # Nothing found - return [] - - return getMoreInfo(req, key) - - -def getIP(ip, key, do_not_recurse=False): - global limit - toReturn = [] - req = requests.get("https://www.virustotal.com/vtapi/v2/ip-address/report", - params={"ip": ip, "apikey": key}) - try: - req.raise_for_status() - req = req.json() - except HTTPError as e: - misperrors['error'] = str(e) + del q['module'] + query = VirusTotalRequest(q.pop('config')) + r = query.parse_request(*list(q.items())[0]) + if isinstance(r, str): + misperrors['error'] = r return misperrors + return {'results': r} - if req["response_code"] == 0: - # Nothing found - return [] - - if "resolutions" in req: - for res in req["resolutions"][:limit]: - toReturn.append({"types": ["domain"], "values": [res["hostname"]], "comment": comment % ip}) - # Pivot from here to find all domain info - if not do_not_recurse: - toReturn += getDomain(res["hostname"], key, True) - - toReturn += getMoreInfo(req, key) - return toReturn - - -def getDomain(domain, key, do_not_recurse=False): - global limit - toReturn = [] - req = requests.get("https://www.virustotal.com/vtapi/v2/domain/report", - params={"domain": domain, "apikey": key}) - try: - req.raise_for_status() - req = req.json() - except HTTPError as e: - misperrors['error'] = str(e) - return misperrors - - if req["response_code"] == 0: - # Nothing found - return [] - - if "resolutions" in req: - for res in req["resolutions"][:limit]: - toReturn.append({"types": ["ip-dst", "ip-src"], "values": [res["ip_address"]], "comment": comment % domain}) - # Pivot from here to find all info on IPs - if not do_not_recurse: - toReturn += getIP(res["ip_address"], key, True) - if "subdomains" in req: - for subd in req["subdomains"]: - toReturn.append({"types": ["domain"], "values": [subd], "comment": comment % domain}) - toReturn += getMoreInfo(req, key) - return toReturn - - -def findAll(data, keys): - a = [] - if isinstance(data, dict): - for key in data.keys(): - if key in keys: - a.append(data[key]) - else: - if isinstance(data[key], (dict, list)): - a += findAll(data[key], keys) - if isinstance(data, list): - for i in data: - a += findAll(i, keys) - - return a - - -def getMoreInfo(req, key): - global limit - r = [] - # Get all hashes first - hashes = [] - hashes = findAll(req, ["md5", "sha1", "sha256", "sha512"]) - r.append({"types": ["freetext"], "values": hashes}) - for hsh in hashes[:limit]: - # Search VT for some juicy info - try: - data = requests.get("http://www.virustotal.com/vtapi/v2/file/report", - params={"allinfo": 1, "apikey": key, "resource": hsh} - ).json() - except: - continue - - # Go through each key and check if it exists - if "submission_names" in data: - r.append({'types': ["filename"], "values": data["submission_names"], "comment": comment % hsh}) - - if "ssdeep" in data: - r.append({'types': ["ssdeep"], "values": [data["ssdeep"]], "comment": comment % hsh}) - - if "authentihash" in data: - r.append({"types": ["authentihash"], "values": [data["authentihash"]], "comment": comment % hsh}) - - if "ITW_urls" in data: - r.append({"types": ["url"], "values": data["ITW_urls"], "comment": comment % hsh}) - - # Get the malware sample - sample = requests.get("https://www.virustotal.com/vtapi/v2/file/download", - params={"hash": hsh, "apikey": key}) - - malsample = sample.content - - # It is possible for VT to not give us any submission names - if "submission_names" in data: - r.append({"types": ["malware-sample"], - "categories": ["Payload delivery"], - "values": data["submission_names"], - "data": str(base64.b64encode(malsample), 'utf-8') - } - ) - - return r - +def get_ip(ip, key): + params = {'ip': ip, 'apikey': key} + req = requests.get('https://www.virustotal.com/vtapi/v2/ip-address/report', params=params) + return json.dumps(req.json(), indent=2) def introspection(): return mispattributes - def version(): moduleinfo['config'] = moduleconfig return moduleinfo From 2af947a2deba46ddf2e92cc8f1b0c08be07e1429 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Mon, 3 Sep 2018 10:23:05 +0200 Subject: [PATCH 07/16] fix: Removed print --- misp_modules/modules/expansion/virustotal.py | 1 - 1 file changed, 1 deletion(-) diff --git a/misp_modules/modules/expansion/virustotal.py b/misp_modules/modules/expansion/virustotal.py index 404f621..de91e09 100644 --- a/misp_modules/modules/expansion/virustotal.py +++ b/misp_modules/modules/expansion/virustotal.py @@ -104,7 +104,6 @@ class VirusTotalRequest(object): if isinstance(data, dict): for key, value in data.items(): if key in hash_types: - print(key) self.results[key].add(value) hashes.append(value) else: From 936e30b15b97643828b95011bbf7e349acd9f146 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Mon, 3 Sep 2018 12:03:42 +0200 Subject: [PATCH 08/16] fix: Multiple attributes parsing support - Fixing one of my previous changes not processing multiple attributes parsing --- misp_modules/modules/expansion/virustotal.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/misp_modules/modules/expansion/virustotal.py b/misp_modules/modules/expansion/virustotal.py index de91e09..4ebbd43 100644 --- a/misp_modules/modules/expansion/virustotal.py +++ b/misp_modules/modules/expansion/virustotal.py @@ -33,10 +33,14 @@ class VirusTotalRequest(object): self.output_types_mapping = {'submission_names': 'filename', 'ssdeep': 'ssdeep', 'authentihash': 'authentihash', 'ITW_urls': 'url'} - def parse_request(self, attribute_type, attribute_value): - error = self.input_types_mapping[attribute_type](attribute_value) - if error is not None: - return error + def parse_request(self, q): + for attribute_type, attribute_value in q.items(): + try: + error = self.input_types_mapping[attribute_type](attribute_value) + except KeyError: + continue + if error is not None: + return error for key, values in self.results.items(): if isinstance(key, tuple): types, comment = key @@ -144,7 +148,7 @@ def handler(q=False): return misperrors del q['module'] query = VirusTotalRequest(q.pop('config')) - r = query.parse_request(*list(q.items())[0]) + r = query.parse_request(q) if isinstance(r, str): misperrors['error'] = r return misperrors From 0ab38feade0e2ead2628c19b12a7ba42709b5141 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Mon, 3 Sep 2018 13:17:48 +0200 Subject: [PATCH 09/16] fix: Cleaned up test function not used anymore --- misp_modules/modules/expansion/virustotal.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/misp_modules/modules/expansion/virustotal.py b/misp_modules/modules/expansion/virustotal.py index 4ebbd43..cd4efcd 100644 --- a/misp_modules/modules/expansion/virustotal.py +++ b/misp_modules/modules/expansion/virustotal.py @@ -154,11 +154,6 @@ def handler(q=False): return misperrors return {'results': r} -def get_ip(ip, key): - params = {'ip': ip, 'apikey': key} - req = requests.get('https://www.virustotal.com/vtapi/v2/ip-address/report', params=params) - return json.dumps(req.json(), indent=2) - def introspection(): return mispattributes From 33181bc52baee54433c2cf710ad5f4d6c38c4e61 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Mon, 3 Sep 2018 14:29:42 +0200 Subject: [PATCH 10/16] fix: Fixed quick variable issue --- misp_modules/modules/expansion/virustotal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misp_modules/modules/expansion/virustotal.py b/misp_modules/modules/expansion/virustotal.py index cd4efcd..a917f6f 100644 --- a/misp_modules/modules/expansion/virustotal.py +++ b/misp_modules/modules/expansion/virustotal.py @@ -124,7 +124,7 @@ class VirusTotalRequest(object): for h in hashes[:self.limit]: # Search VT for some juicy info try: - data = requests.get(self.base_url.format('file'), params={'resource': h, 'apikey': apikey, 'allinfo': 1}).json() + data = requests.get(self.base_url.format('file'), params={'resource': h, 'apikey': self.apikey, 'allinfo': 1}).json() except Exception: continue # Go through euch key and check if it exists @@ -132,7 +132,7 @@ class VirusTotalRequest(object): if VT_type in data: self.results[((MISP_type,), comment.format(h))].add(data[VT_type]) # Get the malware sample - sample = requests.get(self.base_url[:-6].format('file/download'), params={'hash': h, 'apikey': apikey}) + sample = requests.get(self.base_url[:-6].format('file/download'), params={'hash': h, 'apikey': self.apikey}) malsample = sample.content # It is possible for VT to not give us any submission names if "submission_names" in data: From cdf2f434ce66c2a1c21ecfceb13ac200eeaccf9c Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Mon, 3 Sep 2018 14:30:33 +0200 Subject: [PATCH 11/16] fix: Avoiding adding attributes that are already in the event --- misp_modules/modules/expansion/virustotal.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/misp_modules/modules/expansion/virustotal.py b/misp_modules/modules/expansion/virustotal.py index a917f6f..614b8d0 100644 --- a/misp_modules/modules/expansion/virustotal.py +++ b/misp_modules/modules/expansion/virustotal.py @@ -34,7 +34,9 @@ class VirusTotalRequest(object): 'authentihash': 'authentihash', 'ITW_urls': 'url'} def parse_request(self, q): + req_values = set() for attribute_type, attribute_value in q.items(): + req_values.add(attribute_value) try: error = self.input_types_mapping[attribute_type](attribute_value) except KeyError: @@ -42,11 +44,13 @@ class VirusTotalRequest(object): if error is not None: return error for key, values in self.results.items(): - if isinstance(key, tuple): - types, comment = key - self.to_return.append({'types': list(types), 'values': list(values), 'comment': comment}) - else: - self.to_return.append({'types': key, 'values': list(values)}) + values = values.difference(req_values) + if values: + if isinstance(key, tuple): + types, comment = key + self.to_return.append({'types': list(types), 'values': list(values), 'comment': comment}) + else: + self.to_return.append({'types': key, 'values': list(values)}) return self.to_return def get_domain(self, domain, do_not_recurse=False): From ba728f712076986d425c7dbcca0357b4488158d4 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Mon, 3 Sep 2018 14:43:51 +0200 Subject: [PATCH 12/16] fix: Fixed 1 variable misuse + cleaned up variable names - Fixed use of 'domain' variable instead of 'email' - Cleaned up variable names to avoid redefinition of built-in variables --- misp_modules/modules/expansion/otx.py | 35 +++++++++++++-------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/misp_modules/modules/expansion/otx.py b/misp_modules/modules/expansion/otx.py index 214e7f0..86685eb 100755 --- a/misp_modules/modules/expansion/otx.py +++ b/misp_modules/modules/expansion/otx.py @@ -32,16 +32,15 @@ def valid_ip(ip): def findAll(data, keys): a = [] if isinstance(data, dict): - for key in data.keys(): + for key, value in data.items(): if key == keys: - a.append(data[key]) + a.append(value) else: - if isinstance(data[key], (dict, list)): - a += findAll(data[key], keys) + if isinstance(value, (dict, list)): + a.extend(findAll(value, keys)) if isinstance(data, list): for i in data: - a += findAll(i, keys) - + a.extend(findAll(i, keys)) return a def valid_email(email): @@ -82,10 +81,10 @@ def handler(q=False): return r -def getHash(hash, key): +def getHash(_hash, key): ret = [] - req = json.loads(requests.get("https://otx.alienvault.com/otxapi/indicator/file/analysis/" + hash).text) + req = json.loads(requests.get("https://otx.alienvault.com/otxapi/indicator/file/analysis/" + _hash).text) for ip in findAll(req, "dst"): if not isBlacklisted(ip) and valid_ip(ip): @@ -102,8 +101,8 @@ def getIP(ip, key): ret = [] req = json.loads( requests.get("https://otx.alienvault.com/otxapi/indicator/ip/malware/" + ip + "?limit=1000").text ) - for hash in findAll(req, "hash"): - ret.append({"types": ["sha256"], "values": [hash]}) + for _hash in findAll(req, "hash"): + ret.append({"types": ["sha256"], "values": [_hash]}) req = json.loads( requests.get("https://otx.alienvault.com/otxapi/indicator/ip/passive_dns/" + ip).text ) @@ -122,21 +121,21 @@ def getDomain(domain, key): req = json.loads( requests.get("https://otx.alienvault.com/otxapi/indicator/domain/malware/" + domain + "?limit=1000").text ) - for hash in findAll(req, "hash"): - ret.append({"types": ["sha256"], "values": [hash]}) + for _hash in findAll(req, "hash"): + ret.append({"types": ["sha256"], "values": [_hash]}) req = json.loads(requests.get("https://otx.alienvault.com/otxapi/indicator/domain/whois/" + domain).text) - for domain in findAll(req, "domain"): - ret.append({"types": ["hostname"], "values": [domain]}) + for _domain in findAll(req, "domain"): + ret.append({"types": ["hostname"], "values": [_domain]}) for email in findAll(req, "value"): if valid_email(email): - ret.append({"types": ["email"], "values": [domain]}) + ret.append({"types": ["email"], "values": [email]}) - for domain in findAll(req, "hostname"): - if "." in domain and not isBlacklisted(domain): - ret.append({"types": ["hostname"], "values": [domain]}) + for _domain in findAll(req, "hostname"): + if "." in _domain and not isBlacklisted(_domain): + ret.append({"types": ["hostname"], "values": [_domain]}) req = json.loads(requests.get("https://otx.alienvault.com/otxapi/indicator/hostname/passive_dns/" + domain).text) for ip in findAll(req, "address"): From 26647a164bba1bf7b14cca6e89108e84c1ca9955 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Fri, 7 Sep 2018 17:43:46 +0200 Subject: [PATCH 13/16] fix: Fixed indentation error --- misp_modules/modules/expansion/virustotal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misp_modules/modules/expansion/virustotal.py b/misp_modules/modules/expansion/virustotal.py index 614b8d0..2889d7b 100644 --- a/misp_modules/modules/expansion/virustotal.py +++ b/misp_modules/modules/expansion/virustotal.py @@ -128,7 +128,7 @@ class VirusTotalRequest(object): for h in hashes[:self.limit]: # Search VT for some juicy info try: - data = requests.get(self.base_url.format('file'), params={'resource': h, 'apikey': self.apikey, 'allinfo': 1}).json() + data = requests.get(self.base_url.format('file'), params={'resource': h, 'apikey': self.apikey, 'allinfo': 1}).json() except Exception: continue # Go through euch key and check if it exists From 48fcf9a85eae5ed2a52dfd65f79dddc0180435e9 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Fri, 7 Sep 2018 17:49:28 +0200 Subject: [PATCH 14/16] fix: Fixed syntax error --- misp_modules/modules/expansion/virustotal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misp_modules/modules/expansion/virustotal.py b/misp_modules/modules/expansion/virustotal.py index 2889d7b..524bc49 100644 --- a/misp_modules/modules/expansion/virustotal.py +++ b/misp_modules/modules/expansion/virustotal.py @@ -148,7 +148,7 @@ def handler(q=False): return False q = json.loads(q) if not q.get('config') or not q['config'].get('apikey'): - misperrors['error']: "A VirusTotal api key is required for this module." + misperrors['error'] = "A VirusTotal api key is required for this module." return misperrors del q['module'] query = VirusTotalRequest(q.pop('config')) From a18db2ed1d2985ef55a6fc4cf7161fbb74273ee9 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Fri, 7 Sep 2018 17:56:25 +0200 Subject: [PATCH 15/16] fix: Fixed exception type --- misp_modules/modules/expansion/yara_syntax_validator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misp_modules/modules/expansion/yara_syntax_validator.py b/misp_modules/modules/expansion/yara_syntax_validator.py index 57c71ea..18e2de0 100644 --- a/misp_modules/modules/expansion/yara_syntax_validator.py +++ b/misp_modules/modules/expansion/yara_syntax_validator.py @@ -2,7 +2,7 @@ import json import requests try: import yara -except ModuleNotFoundError: +except (OSError, ModuleNotFoundError): print("yara is missing, use 'pip3 install yara' to install it.") misperrors = {'error': 'Error'} From cfbd63f14ec8c348a749bb37f0ea543605535aa8 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Fri, 7 Sep 2018 18:06:01 +0200 Subject: [PATCH 16/16] fix: Fixed exception type for python 3.5 --- misp_modules/modules/expansion/yara_syntax_validator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misp_modules/modules/expansion/yara_syntax_validator.py b/misp_modules/modules/expansion/yara_syntax_validator.py index 18e2de0..c68d934 100644 --- a/misp_modules/modules/expansion/yara_syntax_validator.py +++ b/misp_modules/modules/expansion/yara_syntax_validator.py @@ -2,7 +2,7 @@ import json import requests try: import yara -except (OSError, ModuleNotFoundError): +except (OSError, ImportError): print("yara is missing, use 'pip3 install yara' to install it.") misperrors = {'error': 'Error'}