misp-modules 2.4.196__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. misp_modules/__init__.py +379 -0
  2. misp_modules/helpers/__init__.py +1 -0
  3. misp_modules/helpers/cache.py +84 -0
  4. misp_modules/lib/__init__.py +4 -0
  5. misp_modules/lib/_vmray/__init__.py +0 -0
  6. misp_modules/lib/_vmray/parser.py +1417 -0
  7. misp_modules/lib/_vmray/rest_api.py +148 -0
  8. misp_modules/lib/cof2misp/LICENSE-2.0.txt +202 -0
  9. misp_modules/lib/cof2misp/__init__.py +0 -0
  10. misp_modules/lib/cof2misp/cof.py +165 -0
  11. misp_modules/lib/joe_mapping.py +114 -0
  12. misp_modules/lib/joe_parser.py +573 -0
  13. misp_modules/lib/lastline_api.py +841 -0
  14. misp_modules/lib/qintel_helper.py +263 -0
  15. misp_modules/lib/stix2misp.py +2080 -0
  16. misp_modules/lib/stix2misp_mapping.py +460 -0
  17. misp_modules/lib/synonymsToTagNames.json +1 -0
  18. misp_modules/lib/vt_graph_parser/__init__.py +8 -0
  19. misp_modules/lib/vt_graph_parser/errors.py +20 -0
  20. misp_modules/lib/vt_graph_parser/helpers/__init__.py +7 -0
  21. misp_modules/lib/vt_graph_parser/helpers/parsers.py +88 -0
  22. misp_modules/lib/vt_graph_parser/helpers/rules.py +304 -0
  23. misp_modules/lib/vt_graph_parser/helpers/wrappers.py +58 -0
  24. misp_modules/lib/vt_graph_parser/importers/__init__.py +7 -0
  25. misp_modules/lib/vt_graph_parser/importers/base.py +98 -0
  26. misp_modules/lib/vt_graph_parser/importers/pymisp_response.py +73 -0
  27. misp_modules/modules/__init__.py +4 -0
  28. misp_modules/modules/action_mod/__init__.py +1 -0
  29. misp_modules/modules/action_mod/_utils/__init__.py +1 -0
  30. misp_modules/modules/action_mod/_utils/utils.py +70 -0
  31. misp_modules/modules/action_mod/mattermost.py +113 -0
  32. misp_modules/modules/action_mod/slack.py +96 -0
  33. misp_modules/modules/action_mod/testaction.py +68 -0
  34. misp_modules/modules/expansion/__init__.py +36 -0
  35. misp_modules/modules/expansion/_dnsdb_query/COPYRIGHT +27 -0
  36. misp_modules/modules/expansion/_dnsdb_query/LICENSE +202 -0
  37. misp_modules/modules/expansion/_dnsdb_query/README.md +162 -0
  38. misp_modules/modules/expansion/_dnsdb_query/__init__.py +0 -0
  39. misp_modules/modules/expansion/_dnsdb_query/dnsdb_query.py +327 -0
  40. misp_modules/modules/expansion/_ransomcoindb/__init__.py +0 -0
  41. misp_modules/modules/expansion/_ransomcoindb/ransomcoindb.py +96 -0
  42. misp_modules/modules/expansion/_vulnerability_parser/__init__.py +0 -0
  43. misp_modules/modules/expansion/_vulnerability_parser/vulnerability_parser.py +118 -0
  44. misp_modules/modules/expansion/abuseipdb.py +146 -0
  45. misp_modules/modules/expansion/apiosintds.py +365 -0
  46. misp_modules/modules/expansion/apivoid.py +133 -0
  47. misp_modules/modules/expansion/assemblyline_query.py +179 -0
  48. misp_modules/modules/expansion/assemblyline_submit.py +100 -0
  49. misp_modules/modules/expansion/backscatter_io.py +84 -0
  50. misp_modules/modules/expansion/btc_scam_check.py +54 -0
  51. misp_modules/modules/expansion/btc_steroids.py +238 -0
  52. misp_modules/modules/expansion/censys_enrich.py +287 -0
  53. misp_modules/modules/expansion/circl_passivedns.py +85 -0
  54. misp_modules/modules/expansion/circl_passivessl.py +113 -0
  55. misp_modules/modules/expansion/clamav.py +129 -0
  56. misp_modules/modules/expansion/cluster25_expand.py +239 -0
  57. misp_modules/modules/expansion/countrycode.py +69 -0
  58. misp_modules/modules/expansion/cpe.py +140 -0
  59. misp_modules/modules/expansion/crowdsec.py +235 -0
  60. misp_modules/modules/expansion/crowdstrike_falcon.py +148 -0
  61. misp_modules/modules/expansion/cuckoo_submit.py +161 -0
  62. misp_modules/modules/expansion/cve.py +57 -0
  63. misp_modules/modules/expansion/cve_advanced.py +185 -0
  64. misp_modules/modules/expansion/cytomic_orion.py +196 -0
  65. misp_modules/modules/expansion/dbl_spamhaus.py +78 -0
  66. misp_modules/modules/expansion/dns.py +71 -0
  67. misp_modules/modules/expansion/docx_enrich.py +71 -0
  68. misp_modules/modules/expansion/domaintools.py +290 -0
  69. misp_modules/modules/expansion/eql.py +91 -0
  70. misp_modules/modules/expansion/eupi.py +86 -0
  71. misp_modules/modules/expansion/extract_url_components.py +83 -0
  72. misp_modules/modules/expansion/farsight_passivedns.py +243 -0
  73. misp_modules/modules/expansion/geoip_asn.py +75 -0
  74. misp_modules/modules/expansion/geoip_city.py +75 -0
  75. misp_modules/modules/expansion/geoip_country.py +73 -0
  76. misp_modules/modules/expansion/google_safe_browsing.py +86 -0
  77. misp_modules/modules/expansion/google_search.py +57 -0
  78. misp_modules/modules/expansion/google_threat_intelligence.py +453 -0
  79. misp_modules/modules/expansion/greynoise.py +346 -0
  80. misp_modules/modules/expansion/hashdd.py +53 -0
  81. misp_modules/modules/expansion/hashlookup.py +118 -0
  82. misp_modules/modules/expansion/hibp.py +62 -0
  83. misp_modules/modules/expansion/html_to_markdown.py +63 -0
  84. misp_modules/modules/expansion/hyasinsight.py +881 -0
  85. misp_modules/modules/expansion/intel471.py +73 -0
  86. misp_modules/modules/expansion/intelmq_eventdb.py.experimental +67 -0
  87. misp_modules/modules/expansion/ip2locationio.py +90 -0
  88. misp_modules/modules/expansion/ipasn.py +70 -0
  89. misp_modules/modules/expansion/ipinfo.py +112 -0
  90. misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py +633 -0
  91. misp_modules/modules/expansion/iprep.py +98 -0
  92. misp_modules/modules/expansion/jinja_template_rendering.py +54 -0
  93. misp_modules/modules/expansion/joesandbox_query.py +91 -0
  94. misp_modules/modules/expansion/joesandbox_submit.py +147 -0
  95. misp_modules/modules/expansion/lastline_query.py +148 -0
  96. misp_modules/modules/expansion/lastline_submit.py +180 -0
  97. misp_modules/modules/expansion/macaddress_io.py +130 -0
  98. misp_modules/modules/expansion/macvendors.py +55 -0
  99. misp_modules/modules/expansion/malshare_upload.py +107 -0
  100. misp_modules/modules/expansion/malwarebazaar.py +67 -0
  101. misp_modules/modules/expansion/mcafee_insights_enrich.py +249 -0
  102. misp_modules/modules/expansion/mmdb_lookup.py +138 -0
  103. misp_modules/modules/expansion/module.py.skeleton +44 -0
  104. misp_modules/modules/expansion/mwdb.py +152 -0
  105. misp_modules/modules/expansion/ocr_enrich.py +74 -0
  106. misp_modules/modules/expansion/ods_enrich.py +71 -0
  107. misp_modules/modules/expansion/odt_enrich.py +61 -0
  108. misp_modules/modules/expansion/onyphe.py +243 -0
  109. misp_modules/modules/expansion/onyphe_full.py +387 -0
  110. misp_modules/modules/expansion/otx.py +167 -0
  111. misp_modules/modules/expansion/passive_ssh.py +150 -0
  112. misp_modules/modules/expansion/passivetotal.py +358 -0
  113. misp_modules/modules/expansion/pdf_enrich.py +58 -0
  114. misp_modules/modules/expansion/pptx_enrich.py +65 -0
  115. misp_modules/modules/expansion/qintel_qsentry.py +229 -0
  116. misp_modules/modules/expansion/qrcode.py +99 -0
  117. misp_modules/modules/expansion/ransomcoindb.py +82 -0
  118. misp_modules/modules/expansion/rbl.py +126 -0
  119. misp_modules/modules/expansion/recordedfuture.py +544 -0
  120. misp_modules/modules/expansion/reversedns.py +77 -0
  121. misp_modules/modules/expansion/securitytrails.py +571 -0
  122. misp_modules/modules/expansion/shodan.py +244 -0
  123. misp_modules/modules/expansion/sigma_queries.py +61 -0
  124. misp_modules/modules/expansion/sigma_syntax_validator.py +49 -0
  125. misp_modules/modules/expansion/sigmf_expand.py +303 -0
  126. misp_modules/modules/expansion/socialscan.py +108 -0
  127. misp_modules/modules/expansion/sophoslabs_intelix.py +146 -0
  128. misp_modules/modules/expansion/sourcecache.py +57 -0
  129. misp_modules/modules/expansion/stairwell.py +156 -0
  130. misp_modules/modules/expansion/stix2_pattern_syntax_validator.py +56 -0
  131. misp_modules/modules/expansion/threatcrowd.py +170 -0
  132. misp_modules/modules/expansion/threatfox.py +75 -0
  133. misp_modules/modules/expansion/threatminer.py +152 -0
  134. misp_modules/modules/expansion/triage_submit.py +119 -0
  135. misp_modules/modules/expansion/trustar_enrich.py +235 -0
  136. misp_modules/modules/expansion/urlhaus.py +164 -0
  137. misp_modules/modules/expansion/urlscan.py +269 -0
  138. misp_modules/modules/expansion/variotdbs.py +133 -0
  139. misp_modules/modules/expansion/virustotal.py +311 -0
  140. misp_modules/modules/expansion/virustotal_public.py +272 -0
  141. misp_modules/modules/expansion/virustotal_upload.py +91 -0
  142. misp_modules/modules/expansion/vmray_submit.py +161 -0
  143. misp_modules/modules/expansion/vmware_nsx.py +628 -0
  144. misp_modules/modules/expansion/vulndb.py +292 -0
  145. misp_modules/modules/expansion/vulnerability_lookup.py +324 -0
  146. misp_modules/modules/expansion/vulners.py +81 -0
  147. misp_modules/modules/expansion/vysion.py +221 -0
  148. misp_modules/modules/expansion/whois.py +72 -0
  149. misp_modules/modules/expansion/whoisfreaks.py +232 -0
  150. misp_modules/modules/expansion/wiki.py +58 -0
  151. misp_modules/modules/expansion/xforceexchange.py +189 -0
  152. misp_modules/modules/expansion/xlsx_enrich.py +63 -0
  153. misp_modules/modules/expansion/yara_query.py +70 -0
  154. misp_modules/modules/expansion/yara_syntax_validator.py +49 -0
  155. misp_modules/modules/expansion/yeti.py +196 -0
  156. misp_modules/modules/export_mod/__init__.py +3 -0
  157. misp_modules/modules/export_mod/cef_export.py +93 -0
  158. misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py +150 -0
  159. misp_modules/modules/export_mod/defender_endpoint_export.py +141 -0
  160. misp_modules/modules/export_mod/goamlexport.py +255 -0
  161. misp_modules/modules/export_mod/liteexport.py +97 -0
  162. misp_modules/modules/export_mod/mass_eql_export.py +106 -0
  163. misp_modules/modules/export_mod/nexthinkexport.py +131 -0
  164. misp_modules/modules/export_mod/osqueryexport.py +125 -0
  165. misp_modules/modules/export_mod/pdfexport.py +107 -0
  166. misp_modules/modules/export_mod/testexport.py +73 -0
  167. misp_modules/modules/export_mod/threatStream_misp_export.py +114 -0
  168. misp_modules/modules/export_mod/threat_connect_export.py +125 -0
  169. misp_modules/modules/export_mod/virustotal_collections.py +141 -0
  170. misp_modules/modules/export_mod/vt_graph.py +120 -0
  171. misp_modules/modules/export_mod/yara_export.py +290 -0
  172. misp_modules/modules/import_mod/__init__.py +22 -0
  173. misp_modules/modules/import_mod/cof2misp.py +264 -0
  174. misp_modules/modules/import_mod/csvimport.py +319 -0
  175. misp_modules/modules/import_mod/cuckooimport.py +749 -0
  176. misp_modules/modules/import_mod/email_import.py +294 -0
  177. misp_modules/modules/import_mod/goamlimport.py +188 -0
  178. misp_modules/modules/import_mod/import_blueprint.py +93 -0
  179. misp_modules/modules/import_mod/joe_import.py +74 -0
  180. misp_modules/modules/import_mod/lastline_import.py +160 -0
  181. misp_modules/modules/import_mod/mispjson.py +73 -0
  182. misp_modules/modules/import_mod/ocr.py +122 -0
  183. misp_modules/modules/import_mod/openiocimport.py +99 -0
  184. misp_modules/modules/import_mod/taxii21.py +383 -0
  185. misp_modules/modules/import_mod/testimport.py +73 -0
  186. misp_modules/modules/import_mod/threatanalyzer_import.py +552 -0
  187. misp_modules/modules/import_mod/url_import.py +97 -0
  188. misp_modules/modules/import_mod/vmray_import.py +96 -0
  189. misp_modules/modules/import_mod/vmray_summary_json_import.py +87 -0
  190. misp_modules-2.4.196.dist-info/LICENSE +661 -0
  191. misp_modules-2.4.196.dist-info/METADATA +281 -0
  192. misp_modules-2.4.196.dist-info/RECORD +194 -0
  193. misp_modules-2.4.196.dist-info/WHEEL +4 -0
  194. misp_modules-2.4.196.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,108 @@
1
+ import json
2
+ from socialscan.platforms import Platforms
3
+ from socialscan.util import sync_execute_queries
4
+
5
+ moduleinfo = {
6
+ 'version': '1',
7
+ 'author': 'Christian Studer',
8
+ 'description': 'A hover module to get information on the availability of an email address or username on some online platforms.',
9
+ 'module-type': ['hover'],
10
+ 'name': 'Socialscan Lookup',
11
+ 'logo': '',
12
+ 'requirements': ['The socialscan python library'],
13
+ 'features': 'The module takes an email address or username as input and check its availability on some online platforms. The results for each platform are then returned to see if the email address or the username is used, available or if there is an issue with it.',
14
+ 'references': ['https://github.com/iojw/socialscan'],
15
+ 'input': 'An email address or usename attribute.',
16
+ 'output': 'Text containing information about the availability of an email address or a username in some online platforms.',
17
+ }
18
+ mispattributes = {
19
+ 'input': [
20
+ 'github-username',
21
+ 'target-user',
22
+ 'email',
23
+ 'email-src',
24
+ 'email-dst',
25
+ 'target-email',
26
+ 'whois-registrant-email'
27
+ ],
28
+ 'output': ['text']
29
+ }
30
+ moduleconfig = []
31
+
32
+ _PLATFORMS = [
33
+ Platforms.INSTAGRAM,
34
+ Platforms.TWITTER,
35
+ Platforms.GITHUB,
36
+ Platforms.TUMBLR,
37
+ Platforms.LASTFM
38
+ ]
39
+ _EMAIL_PLATFORMS = [
40
+ Platforms.PINTEREST,
41
+ Platforms.SPOTIFY,
42
+ Platforms.FIREFOX
43
+ ]
44
+ _EMAIL_PLATFORMS.extend(_PLATFORMS)
45
+ _USERNAME_PLATFORMS = [
46
+ Platforms.SNAPCHAT,
47
+ Platforms.GITLAB,
48
+ Platforms.REDDIT,
49
+ Platforms.YAHOO
50
+ ]
51
+ _USERNAME_PLATFORMS.extend(_PLATFORMS)
52
+
53
+
54
+ def parse_results(query_results, feature):
55
+ results = []
56
+ for result in query_results:
57
+ if not result.success:
58
+ results.append(f'Unable to retrieve the {feature} on {result.platform}.')
59
+ continue
60
+ if not result.valid:
61
+ results.append(f'Invalid response from {result.platform}, or invalid {feature}.')
62
+ continue
63
+ statement = 'No account' if result.available else 'There is an account'
64
+ results.append(f'{statement} linked to the {feature} on {result.platform}.')
65
+ to_return = [
66
+ {
67
+ 'types': mispattributes['output'],
68
+ 'values': result
69
+ } for result in results
70
+ ]
71
+ return {'results': to_return}
72
+
73
+
74
+ def parse_email(email):
75
+ results = sync_execute_queries([email], platforms=_EMAIL_PLATFORMS)
76
+ return parse_results(results, 'email address')
77
+
78
+
79
+ def parse_username(username, platforms=_USERNAME_PLATFORMS):
80
+ results = sync_execute_queries([username], platforms=platforms)
81
+ return parse_results(results, 'username')
82
+
83
+
84
+ def parse_github_username(username):
85
+ return parse_username(username, platforms=[Platforms.GITHUB])
86
+
87
+
88
+ def handler(q=False):
89
+ if q is False:
90
+ return False
91
+ request = json.loads(q)
92
+ if request.get('github-username'):
93
+ return parse_github_username(request['github-username'])
94
+ if request.get('target-user'):
95
+ return parse_username(request['target-user'])
96
+ for attribute_type in mispattributes['input'][2:]:
97
+ if request.get(attribute_type):
98
+ return parse_email(request[attribute_type])
99
+ return {'error': 'Unsupported attributes type'}
100
+
101
+
102
+ def introspection():
103
+ return mispattributes
104
+
105
+
106
+ def version():
107
+ moduleinfo['config'] = moduleconfig
108
+ return moduleinfo
@@ -0,0 +1,146 @@
1
+ import json
2
+ import requests
3
+ import base64
4
+ from . import check_input_attribute, checking_error, standard_error_message
5
+ from pymisp import MISPEvent, MISPObject
6
+ from urllib.parse import quote
7
+
8
+ moduleinfo = {
9
+ 'version': '1.0',
10
+ 'author': 'Ben Verschaeren',
11
+ 'description': 'An expansion module to query the Sophoslabs intelix API to get additional information about an ip address, url, domain or sha256 attribute.',
12
+ 'module-type': ['expansion'],
13
+ 'name': 'SophosLabs Intelix Lookup',
14
+ 'logo': 'sophoslabs_intelix.svg',
15
+ 'requirements': ['A client_id and client_secret pair to authenticate to the SophosLabs Intelix API'],
16
+ 'features': 'The module takes an ip address, url, domain or sha256 attribute and queries the SophosLabs Intelix API with the attribute value. The result of this query is a SophosLabs Intelix hash report, or an ip or url lookup, that is then parsed and returned in a MISP object.',
17
+ 'references': ['https://aws.amazon.com/marketplace/pp/B07SLZPMCS'],
18
+ 'input': 'An ip address, url, domain or sha256 attribute.',
19
+ 'output': 'SophosLabs Intelix report and lookup objects',
20
+ }
21
+
22
+ moduleconfig = ['client_id', 'client_secret']
23
+
24
+ misperrors = {'error': 'Error'}
25
+
26
+ misp_types_in = ['sha256', 'ip', 'ip-src', 'ip-dst', 'uri', 'url', 'domain', 'hostname']
27
+
28
+ mispattributes = {'input': misp_types_in,
29
+ 'format': 'misp_standard'}
30
+
31
+
32
+ class SophosLabsApi():
33
+ def __init__(self, client_id, client_secret):
34
+ self.misp_event = MISPEvent()
35
+ self.client_id = client_id
36
+ self.client_secret = client_secret
37
+ self.authToken = f"{self.client_id}:{self.client_secret}"
38
+ self.baseurl = 'de.api.labs.sophos.com'
39
+ d = {'grant_type': 'client_credentials'}
40
+ h = {'Authorization': f"Basic {base64.b64encode(self.authToken.encode('UTF-8')).decode('ascii')}",
41
+ 'Content-Type': 'application/x-www-form-urlencoded'}
42
+ r = requests.post('https://api.labs.sophos.com/oauth2/token', headers=h, data=d)
43
+ if r.status_code == 200:
44
+ j = json.loads(r.text)
45
+ self.accessToken = j['access_token']
46
+
47
+ def get_result(self):
48
+ event = json.loads(self.misp_event.to_json())
49
+ results = {key: event[key] for key in ('Attribute', 'Object') if (key in event and event[key])}
50
+ return {'results': results}
51
+
52
+ def hash_lookup(self, filehash):
53
+ sophos_object = MISPObject('SOPHOSLabs Intelix SHA256 Report')
54
+ h = {"Authorization": f"{self.accessToken}"}
55
+ r = requests.get(f"https://{self.baseurl}/lookup/files/v1/{filehash}", headers=h)
56
+ if r.status_code == 200:
57
+ j = json.loads(r.text)
58
+ if 'reputationScore' in j:
59
+ sophos_object.add_attribute('Reputation Score', type='text', value=j['reputationScore'])
60
+ if 0 <= j['reputationScore'] <= 19:
61
+ sophos_object.add_attribute('Decision', type='text', value='This file is malicious')
62
+ if 20 <= j['reputationScore'] <= 29:
63
+ sophos_object.add_attribute('Decision', type='text', value='This file is potentially unwanted')
64
+ if 30 <= j['reputationScore'] <= 69:
65
+ sophos_object.add_attribute('Decision', type='text', value='This file is unknown and suspicious')
66
+ if 70 <= j['reputationScore'] <= 100:
67
+ sophos_object.add_attribute('Decision', type='text', value='This file is known good')
68
+ if 'detectionName' in j:
69
+ sophos_object.add_attribute('Detection Name', type='text', value=j['detectionName'])
70
+ else:
71
+ sophos_object.add_attribute('Detection Name', type='text', value='No name associated with this IoC')
72
+ self.misp_event.add_object(**sophos_object)
73
+
74
+ def ip_lookup(self, ip):
75
+ sophos_object = MISPObject('SOPHOSLabs Intelix IP Category Lookup')
76
+ h = {"Authorization": f"{self.accessToken}"}
77
+ r = requests.get(f"https://{self.baseurl}/lookup/ips/v1/{ip}", headers=h)
78
+ if r.status_code == 200:
79
+ j = json.loads(r.text)
80
+ if 'category' in j:
81
+ for c in j['category']:
82
+ sophos_object.add_attribute('IP Address Categorisation', type='text', value=c)
83
+ else:
84
+ sophos_object.add_attribute('IP Address Categorisation', type='text', value='No category assocaited with IoC')
85
+ self.misp_event.add_object(**sophos_object)
86
+
87
+ def url_lookup(self, url):
88
+ sophos_object = MISPObject('SOPHOSLabs Intelix URL Lookup')
89
+ h = {"Authorization": f"{self.accessToken}"}
90
+ r = requests.get(f"https://{self.baseurl}/lookup/urls/v1/{quote(url, safe='')}", headers=h)
91
+ if r.status_code == 200:
92
+ j = json.loads(r.text)
93
+ if 'productivityCategory' in j:
94
+ sophos_object.add_attribute('URL Categorisation', type='text', value=j['productivityCategory'])
95
+ else:
96
+ sophos_object.add_attribute('URL Categorisation', type='text', value='No category assocaited with IoC')
97
+
98
+ if 'riskLevel' in j:
99
+ sophos_object.add_attribute('URL Risk Level', type='text', value=j['riskLevel'])
100
+ else:
101
+ sophos_object.add_attribute('URL Risk Level', type='text', value='No risk level associated with IoC')
102
+
103
+ if 'securityCategory' in j:
104
+ sophos_object.add_attribute('URL Security Category', type='text', value=j['securityCategory'])
105
+ else:
106
+ sophos_object.add_attribute('URL Security Category', type='text', value='No Security Category associated with IoC')
107
+ self.misp_event.add_object(**sophos_object)
108
+
109
+
110
+ def handler(q=False):
111
+ if q is False:
112
+ return False
113
+ j = json.loads(q)
114
+ if not j.get('config') or not j['config'].get('client_id') or not j['config'].get('client_secret'):
115
+ misperrors['error'] = "Missing client_id or client_secret value for SOPHOSLabs Intelix. \
116
+ It's free to sign up here https://aws.amazon.com/marketplace/pp/B07SLZPMCS."
117
+ return misperrors
118
+ to_check = (('type', 'value'), ('type', 'value1'))
119
+ if not j.get('attribute') or not any(check_input_attribute(j['attribute'], requirements=check) for check in to_check):
120
+ return {'error': f'{standard_error_message}, {checking_error}.'}
121
+ attribute = j['attribute']
122
+ if attribute['type'] not in misp_types_in:
123
+ return {'error': 'Unsupported attribute type.'}
124
+ client = SophosLabsApi(j['config']['client_id'], j['config']['client_secret'])
125
+ mapping = {
126
+ 'sha256': 'hash_lookup',
127
+ 'ip-dst': 'ip_lookup',
128
+ 'ip-src': 'ip_lookup',
129
+ 'ip': 'ip_lookup',
130
+ 'uri': 'url_lookup',
131
+ 'url': 'url_lookup',
132
+ 'domain': 'url_lookup',
133
+ 'hostname': 'url_lookup'
134
+ }
135
+ attribute_value = attribute['value'] if 'value' in attribute else attribute['value1']
136
+ getattr(client, mapping[attribute['type']])(attribute_value)
137
+ return client.get_result()
138
+
139
+
140
+ def introspection():
141
+ return mispattributes
142
+
143
+
144
+ def version():
145
+ moduleinfo['config'] = moduleconfig
146
+ return moduleinfo
@@ -0,0 +1,57 @@
1
+ import json
2
+ from url_archiver import url_archiver
3
+
4
+ misperrors = {'error': 'Error'}
5
+ mispattributes = {'input': ['link', 'url'], 'output': ['attachment', 'malware-sample']}
6
+ moduleinfo = {
7
+ 'version': '0.1',
8
+ 'author': 'Alexandre Dulaunoy',
9
+ 'description': 'Module to cache web pages of analysis reports, OSINT sources. The module returns a link of the cached page.',
10
+ 'module-type': ['expansion'],
11
+ 'name': 'URL Archiver',
12
+ 'logo': '',
13
+ 'requirements': ['urlarchiver: python library to fetch and archive URL on the file-system'],
14
+ 'features': 'This module takes a link or url attribute as input and caches the related web page. It returns then a link of the cached page.',
15
+ 'references': ['https://github.com/adulau/url_archiver'],
16
+ 'input': 'A link or url attribute.',
17
+ 'output': 'A malware-sample attribute describing the cached page.',
18
+ }
19
+ moduleconfig = ['archivepath']
20
+
21
+
22
+ def handler(q=False):
23
+ if q is False:
24
+ return False
25
+ request = json.loads(q)
26
+ if (request.get('config')):
27
+ archive_path = request['config']['archivepath']
28
+ else:
29
+ archive_path = '/tmp/'
30
+ if request.get('link'):
31
+ tocache = request['link']
32
+ data = __archiveLink(archive_path, tocache)
33
+ mispattributes['output'] = ['attachment']
34
+ elif request.get('url'):
35
+ tocache = request['url']
36
+ data = __archiveLink(archive_path, tocache)
37
+ mispattributes['output'] = ['malware-sample']
38
+ else:
39
+ misperrors['error'] = "Link is missing"
40
+ return misperrors
41
+ enc_data = data.decode('ascii')
42
+ r = {'results': [{'types': mispattributes['output'], 'values': tocache, 'data': enc_data}]}
43
+ return r
44
+
45
+
46
+ def __archiveLink(archive_path, tocache):
47
+ archiver = url_archiver.Archive(archive_path=archive_path)
48
+ return archiver.fetch(url=tocache, armor=True)
49
+
50
+
51
+ def introspection():
52
+ return mispattributes
53
+
54
+
55
+ def version():
56
+ moduleinfo['config'] = moduleconfig
57
+ return moduleinfo
@@ -0,0 +1,156 @@
1
+ import json
2
+ import re
3
+ import requests
4
+ from pymisp import MISPEvent, MISPObject
5
+ from . import check_input_attribute, checking_error, standard_error_message
6
+
7
+
8
+ misperrors = {
9
+ 'error': 'Error'
10
+ }
11
+ mispattributes = {
12
+ 'input': [
13
+ 'md5',
14
+ 'sha1',
15
+ 'sha256'
16
+ ],
17
+ 'format': 'misp_standard'
18
+ }
19
+ moduleinfo = {
20
+ 'version': '0.1',
21
+ 'author': 'goodlandsecurity',
22
+ 'description': 'Module to query the Stairwell API to get additional information about the input hash attribute',
23
+ 'module-type': ['expansion'],
24
+ 'name': 'Stairwell Lookup',
25
+ 'logo': 'stairwell.png',
26
+ 'requirements': ['Access to Stairwell platform (apikey)'],
27
+ 'features': "The module takes a hash attribute as input and queries Stariwell's API to fetch additional data about it. The result, if the payload is observed in Stariwell, is a file object describing the file the input hash is related to.",
28
+ 'references': ['https://stairwell.com', 'https://docs.stairwell.com'],
29
+ 'input': 'A hash attribute (md5, sha1, sha256).',
30
+ 'output': 'File object related to the input attribute found on Stairwell platform.',
31
+ }
32
+ moduleconfig = ["apikey"]
33
+
34
+
35
+ def parse_response(response: dict):
36
+ attribute_mapping = {
37
+ 'environments': {'type': 'comment', 'object_relation': 'environment', 'distribution': 5},
38
+ 'imphash': {'type': 'imphash', 'object_relation': 'impash', 'distribution': 5},
39
+ 'magic': {'type': 'comment', 'object_relation': 'magic', 'distribution': 5},
40
+ 'malEval': {
41
+ 'probabilityBucket': {'type': 'comment', 'object_relation': 'malEval-probability', 'distribution': 5},
42
+ 'severity': {'type': 'comment', 'object_relation': 'malEval-severity', 'distribution': 5}
43
+ },
44
+ 'md5': {'type': 'md5', 'object_relation': 'md5', 'distribution': 5},
45
+ 'mimeType': {'type': 'mime-type', 'object_relation': 'mime-type', 'distribution': 5},
46
+ 'sha1': {'type': 'sha1', 'object_relation': 'sha1', 'distribution': 5},
47
+ 'sha256': {'type': 'sha256', 'object_relation': 'sha256', 'distribution': 5},
48
+ 'shannonEntropy': {'type': 'float', 'object_relation': 'entropy', 'distribution': 5},
49
+ 'size': {'type': 'size-in-bytes', 'object_relation': 'size-in-bytes', 'distribution': 5},
50
+ 'stairwellFirstSeenTime': {'type': 'datetime', 'object_relation': 'stairwell-first-seen', 'distribution': 5},
51
+ 'tlsh': {'type': 'tlsh', 'object_relation': 'tlsh', 'distribution': 5},
52
+ 'yaraRuleMatches': {'type': 'text', 'object_relation': 'yara-rule-match', 'comment': 'matching Stairwell yara rule name', 'distribution': 5}
53
+ }
54
+ environments_mapping = {
55
+ "NCS2SM-YHB2KT-SAFUDX-JC7F6WYA": "Florian's Open Rules",
56
+ "VR9Z98-4KU7ZC-PCNFEG-FURQ66FW": "Jotti",
57
+ "D7W6M6-BA9BS4-BQ23Z4-NKCNWQ96": "Malshare",
58
+ "D4447Q-WJJL6P-W7ME89-WHXJK8TW": "Malware Bazaar",
59
+ "XAKLND-DKWP3Z-56RL88-6XJ5NH46": "Pro Rules",
60
+ "GMEELM-K226XF-F95XZL-7VEJFKZ6": "Public Samples",
61
+ "5HEG8N-9T7UPG-8SZJ7T-2J4XSDC6": "RH-ISAC",
62
+ "2NN2BJ-HDVQHS-49824H-2SEDBBLJ": "RH-ISAC Malware Sharing",
63
+ "VCZTNF-8S76AK-LUU53W-2SWFFZWJ": "Stairwell Experimental Rules",
64
+ "GEG6FU-MRARGF-TLTM6X-H6MGDT5E": "Stairwell Methodology Rules",
65
+ "EB3DXY-3ZYFVH-6HNKJQ-GAPKHESS": "Stairwell OSINT Rules",
66
+ "NQNJM6-5LSCAF-3MC5FJ-W8EKGW6N": "Stairwell Research Rules",
67
+ "TT9GM5-JUMD8H-9828FL-GAW5NNXE": "stairwell-public-verdicts",
68
+ "MKYSAR-3XN9MB-3VAK3R-888ZJUTJ": "Threat Report Feeds",
69
+ "6HP5R3-ZM7DAN-RB4732-X6QPCJ36": "Virusshare",
70
+ "TV6WCV-7Y79LE-BK79EY-C8GUEY46": "vxintel"
71
+ }
72
+
73
+ misp_event = MISPEvent()
74
+ misp_object = MISPObject('stairwell')
75
+ for feature, attribute in attribute_mapping.items():
76
+ if feature in response.keys() and response[feature]:
77
+ if feature == 'yaraRuleMatches':
78
+ for rule in response[feature]:
79
+ env_pattern = r'\b[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{8}\b'
80
+ env = re.findall(env_pattern, rule.split('yaraRules/')[0])[0]
81
+ misp_attribute = {
82
+ 'value': rule.split('yaraRules/')[1],
83
+ 'comment': f'Rule from: {environments_mapping.get(env, "Unknown UUID!")}'
84
+ }
85
+ misp_attribute.update(attribute)
86
+ misp_object.add_attribute(**misp_attribute)
87
+ elif feature == 'environments':
88
+ for env in response[feature]:
89
+ misp_attribute = {
90
+ 'value': environments_mapping.get(env, f'Unknown Environment: {env}'),
91
+ 'comment': 'Hash observed in'
92
+ }
93
+ misp_attribute.update(attribute)
94
+ misp_object.add_attribute(**misp_attribute)
95
+ elif feature == 'malEval':
96
+ for attr in attribute:
97
+ misp_attribute = {'value': response[feature][attr]}
98
+ misp_attribute.update(attribute[attr])
99
+ misp_object.add_attribute(**misp_attribute)
100
+ else:
101
+ misp_attribute = {'value': response[feature]}
102
+ misp_attribute.update(attribute)
103
+ attr = misp_object.add_attribute(**misp_attribute)
104
+ if feature in ('md5', 'sha1', 'sha256'):
105
+ for label in response['malEval']['labels']:
106
+ attr.add_tag(label)
107
+ misp_event.add_object(**misp_object)
108
+
109
+ event = json.loads(misp_event.to_json())
110
+ results = {'Object': event['Object']}
111
+
112
+ return {'results': results}
113
+
114
+
115
+ def handler(q=False):
116
+ if q is False:
117
+ return False
118
+ request = json.loads(q)
119
+ if not request.get('config') or not request['config'].get('apikey'):
120
+ misperrors['error'] = 'A Stairwell api key is required for this module!'
121
+ return misperrors
122
+ if not request.get('attribute') or not check_input_attribute(request['attribute'], requirements=('type', 'value')):
123
+ misperrors['error'] = f'{standard_error_message}, {checking_error}.'
124
+ return misperrors
125
+ attribute = request['attribute']
126
+ if attribute['type'] not in mispattributes['input']:
127
+ misperrors['error'] = 'Unsupported attribute type!'
128
+ return misperrors
129
+
130
+ headers = {
131
+ "Accept": "application/json",
132
+ "Authorization": request['config']['apikey'],
133
+ "User-Agent": f"misp-module {__file__} {moduleinfo['version']}"
134
+ }
135
+ url = f"https://app.stairwell.com/v1/objects/{attribute['value']}/metadata"
136
+ response = requests.get(url=url, headers=headers).json()
137
+
138
+ if response.get('code') == 16: # bad auth
139
+ return {'error': f"{response['message']} Is api key valid?"}
140
+ elif response.get('code') == 5: # not found
141
+ return {'error': f"{attribute['type']}:{attribute['value']} {response['message']}"}
142
+ elif response.get('code') == 2: # encoding/hex: invalid byte
143
+ return {'error': response['message']}
144
+ elif response.get('code'): # catchall for potential unforeseen errors
145
+ return {'error': response['message'], 'code': response['code']}
146
+ else:
147
+ return parse_response(response)
148
+
149
+
150
+ def introspection():
151
+ return mispattributes
152
+
153
+
154
+ def version():
155
+ moduleinfo['config'] = moduleconfig
156
+ return moduleinfo
@@ -0,0 +1,56 @@
1
+ import json
2
+ try:
3
+ from stix2patterns.validator import run_validator
4
+ except ImportError:
5
+ print("stix2 patterns python library is missing, use 'pip3 install stix2-patterns' to install it.")
6
+
7
+ misperrors = {'error': 'Error'}
8
+ mispattributes = {'input': ['stix2-pattern'], 'output': ['text']}
9
+ moduleinfo = {
10
+ 'version': '0.1',
11
+ 'author': 'Christian Studer',
12
+ 'module-type': ['hover'],
13
+ 'name': 'STIX2 Pattern Syntax Validator',
14
+ 'description': 'An expansion hover module to perform a syntax check on stix2 patterns.',
15
+ 'logo': 'stix.png',
16
+ 'requirements': ['stix2patterns python library'],
17
+ 'features': 'This module takes a STIX2 pattern attribute as input and performs a syntax check on it.\n\nIt displays then that the rule is valid if it is the case, and the error related to the rule otherwise.',
18
+ 'references': ['[STIX2.0 patterning specifications](http://docs.oasis-open.org/cti/stix/v2.0/cs01/part5-stix-patterning/stix-v2.0-cs01-part5-stix-patterning.html)'],
19
+ 'input': 'A STIX2 pattern attribute.',
20
+ 'output': 'Text describing the validity of the STIX2 pattern.',
21
+ }
22
+ moduleconfig = []
23
+
24
+
25
+ def handler(q=False):
26
+ if q is False:
27
+ return False
28
+ request = json.loads(q)
29
+ if not request.get('stix2-pattern'):
30
+ misperrors['error'] = 'STIX2 pattern missing'
31
+ return misperrors
32
+ pattern = request.get('stix2-pattern')
33
+ syntax_errors = []
34
+ for p in pattern[1:-1].split(' AND '):
35
+ syntax_validator = run_validator("[{}]".format(p))
36
+ if syntax_validator:
37
+ for error in syntax_validator:
38
+ syntax_errors.append(error)
39
+ if syntax_errors:
40
+ s = 's' if len(syntax_errors) > 1 else ''
41
+ s_errors = ""
42
+ for error in syntax_errors:
43
+ s_errors += "{}\n".format(error[6:])
44
+ result = "Syntax error{}: \n{}".format(s, s_errors[:-1])
45
+ else:
46
+ result = "Syntax valid"
47
+ return {'results': [{'types': mispattributes['output'], 'values': result}]}
48
+
49
+
50
+ def introspection():
51
+ return mispattributes
52
+
53
+
54
+ def version():
55
+ moduleinfo['config'] = moduleconfig
56
+ return moduleinfo