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,180 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module.
4
+
5
+ Module (type "expansion") to submit files and URLs to Lastline for analysis.
6
+ """
7
+ import base64
8
+ import io
9
+ import json
10
+ import zipfile
11
+
12
+ import lastline_api
13
+
14
+
15
+ misperrors = {
16
+ "error": "Error",
17
+ }
18
+
19
+ mispattributes = {
20
+ "input": [
21
+ "attachment",
22
+ "malware-sample",
23
+ "url",
24
+ ],
25
+ "output": [
26
+ "link",
27
+ ],
28
+ }
29
+
30
+ moduleinfo = {
31
+ 'version': '0.1',
32
+ 'author': 'Stefano Ortolani',
33
+ 'description': 'Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module.\n\nModule to submit a file or URL to Lastline.',
34
+ 'module-type': ['expansion', 'hover'],
35
+ 'name': 'Lastline Submit',
36
+ 'logo': 'lastline.png',
37
+ 'requirements': [],
38
+ 'features': 'The module requires a Lastline Analysis `api_token` and `key`.\nWhen the analysis is completed, it is possible to import the generated report by feeding the analysis link to the [lastline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) module.',
39
+ 'references': ['https://www.lastline.com'],
40
+ 'input': 'File or URL to submit to Lastline.',
41
+ 'output': 'Link to the report generated by Lastline.',
42
+ }
43
+
44
+ moduleconfig = [
45
+ "url",
46
+ "api_token",
47
+ "key",
48
+ ]
49
+
50
+
51
+ DEFAULT_ZIP_PASSWORD = b"infected"
52
+
53
+
54
+ def __unzip(zipped_data, password=None):
55
+ data_file_object = io.BytesIO(zipped_data)
56
+ with zipfile.ZipFile(data_file_object) as zip_file:
57
+ sample_hashname = zip_file.namelist()[0]
58
+ data_zipped = zip_file.read(sample_hashname, password)
59
+ return data_zipped
60
+
61
+
62
+ def __str_to_bool(x):
63
+ return x in ("True", "true", True)
64
+
65
+
66
+ def introspection():
67
+ return mispattributes
68
+
69
+
70
+ def version():
71
+ moduleinfo["config"] = moduleconfig
72
+ return moduleinfo
73
+
74
+
75
+ def handler(q=False):
76
+ if q is False:
77
+ return False
78
+
79
+ request = json.loads(q)
80
+
81
+ # Parse the init parameters
82
+ try:
83
+ config = request.get("config", {})
84
+ auth_data = lastline_api.LastlineAbstractClient.get_login_params_from_dict(config)
85
+ api_url = config.get("url", lastline_api.DEFAULT_LL_ANALYSIS_API_URL)
86
+ except Exception as e:
87
+ misperrors["error"] = "Error parsing configuration: {}".format(e)
88
+ return misperrors
89
+
90
+ # Parse the call parameters
91
+ try:
92
+ call_args = {}
93
+ if "url" in request:
94
+ # URLs are text strings
95
+ api_method = lastline_api.AnalysisClient.submit_url
96
+ call_args["url"] = request.get("url")
97
+ else:
98
+ data = request.get("data")
99
+ # Malware samples are zip-encrypted and then base64 encoded
100
+ if "malware-sample" in request:
101
+ api_method = lastline_api.AnalysisClient.submit_file
102
+ call_args["file_data"] = __unzip(base64.b64decode(data), DEFAULT_ZIP_PASSWORD)
103
+ call_args["file_name"] = request.get("malware-sample").split("|", 1)[0]
104
+ call_args["password"] = DEFAULT_ZIP_PASSWORD
105
+ # Attachments are just base64 encoded
106
+ elif "attachment" in request:
107
+ api_method = lastline_api.AnalysisClient.submit_file
108
+ call_args["file_data"] = base64.b64decode(data)
109
+ call_args["file_name"] = request.get("attachment")
110
+
111
+ else:
112
+ raise ValueError("Input parameters do not specify either an URL or a file")
113
+
114
+ except Exception as e:
115
+ misperrors["error"] = "Error processing input parameters: {}".format(e)
116
+ return misperrors
117
+
118
+ # Make the API call
119
+ try:
120
+ api_client = lastline_api.AnalysisClient(api_url, auth_data)
121
+ response = api_method(api_client, **call_args)
122
+ task_uuid = response.get("task_uuid")
123
+ if not task_uuid:
124
+ raise ValueError("Unable to process returned data")
125
+ if response.get("score") is not None:
126
+ tags = ["workflow:state='complete'"]
127
+ else:
128
+ tags = ["workflow:state='incomplete'"]
129
+
130
+ except Exception as e:
131
+ misperrors["error"] = "Error issuing the API call: {}".format(e)
132
+ return misperrors
133
+
134
+ # Assemble and return
135
+ analysis_link = lastline_api.get_task_link(task_uuid, analysis_url=api_url)
136
+
137
+ return {
138
+ "results": [
139
+ {
140
+ "types": "link",
141
+ "categories": ["External analysis"],
142
+ "values": analysis_link,
143
+ "tags": tags,
144
+ },
145
+ ]
146
+ }
147
+
148
+
149
+ if __name__ == "__main__":
150
+ """Test submitting a test subject to the Lastline backend."""
151
+ import argparse
152
+ import configparser
153
+
154
+ parser = argparse.ArgumentParser()
155
+ parser.add_argument("-c", "--config-file", dest="config_file")
156
+ parser.add_argument("-s", "--section-name", dest="section_name")
157
+ args = parser.parse_args()
158
+ c = configparser.ConfigParser()
159
+ c.read(args.config_file)
160
+ a = lastline_api.LastlineAbstractClient.get_login_params_from_conf(c, args.section_name)
161
+
162
+ j = json.dumps(
163
+ {
164
+ "config": a,
165
+ "url": "https://www.google.exe.com",
166
+ }
167
+ )
168
+ print(json.dumps(handler(j), indent=4, sort_keys=True))
169
+
170
+ with open("./tests/test_files/test.docx", "rb") as f:
171
+ data = f.read()
172
+
173
+ j = json.dumps(
174
+ {
175
+ "config": a,
176
+ "data": base64.b64encode(data).decode("utf-8"),
177
+ "attachment": "test.docx",
178
+ }
179
+ )
180
+ print(json.dumps(handler(j), indent=4, sort_keys=True))
@@ -0,0 +1,130 @@
1
+ import json
2
+
3
+ from maclookup import ApiClient, exceptions
4
+
5
+ misperrors = {
6
+ 'error': 'Error'
7
+ }
8
+
9
+ mispattributes = {
10
+ 'input': ['mac-address'],
11
+ }
12
+
13
+ moduleinfo = {
14
+ 'version': '1.0',
15
+ 'author': 'CodeLine OY - macaddress.io',
16
+ 'description': 'MISP hover module for macaddress.io',
17
+ 'module-type': ['hover'],
18
+ 'name': 'Macaddress.io Lookup',
19
+ 'logo': 'macaddress_io.png',
20
+ 'requirements': ['maclookup: macaddress.io python library', 'An access to the macaddress.io API (apikey)'],
21
+ 'features': 'This module takes a MAC address attribute as input and queries macaddress.io for additional information.\n\nThis information contains data about:\n- MAC address details\n- Vendor details\n- Block details',
22
+ 'references': ['https://macaddress.io/', 'https://github.com/CodeLineFi/maclookup-python'],
23
+ 'input': 'MAC address MISP attribute.',
24
+ 'output': 'Text containing information on the MAC address fetched from a query on macaddress.io.',
25
+ }
26
+
27
+ moduleconfig = ['api_key']
28
+
29
+
30
+ def handler(q=False):
31
+ if q is False:
32
+ return False
33
+
34
+ request = json.loads(q)
35
+
36
+ if request.get('mac-address'):
37
+ mac_address = request['mac-address']
38
+ else:
39
+ return False
40
+
41
+ if request.get('config') and request['config'].get('api_key'):
42
+ api_key = request['config'].get('api_key')
43
+ else:
44
+ misperrors['error'] = 'Authorization required'
45
+ return misperrors
46
+
47
+ api_client = ApiClient(api_key)
48
+
49
+ try:
50
+ response = api_client.get(mac_address)
51
+
52
+ except exceptions.EmptyResponseException:
53
+ misperrors['error'] = 'Empty response'
54
+ return misperrors
55
+
56
+ except exceptions.UnparsableResponseException:
57
+ misperrors['error'] = 'Unparsable response'
58
+ return misperrors
59
+
60
+ except exceptions.ServerErrorException:
61
+ misperrors['error'] = 'Internal server error'
62
+ return misperrors
63
+
64
+ except exceptions.UnknownOutputFormatException:
65
+ misperrors['error'] = 'Unknown output'
66
+ return misperrors
67
+
68
+ except exceptions.AuthorizationRequiredException:
69
+ misperrors['error'] = 'Authorization required'
70
+ return misperrors
71
+
72
+ except exceptions.AccessDeniedException:
73
+ misperrors['error'] = 'Access denied'
74
+ return misperrors
75
+
76
+ except exceptions.InvalidMacOrOuiException:
77
+ misperrors['error'] = 'Invalid MAC or OUI'
78
+ return misperrors
79
+
80
+ except exceptions.NotEnoughCreditsException:
81
+ misperrors['error'] = 'Not enough credits'
82
+ return misperrors
83
+
84
+ except Exception:
85
+ misperrors['error'] = 'Unknown error'
86
+ return misperrors
87
+
88
+ date_created = \
89
+ response.block_details.date_created.strftime('%d %B %Y') if response.block_details.date_created else None
90
+
91
+ date_updated = \
92
+ response.block_details.date_updated.strftime('%d %B %Y') if response.block_details.date_updated else None
93
+
94
+ results = {
95
+ 'results':
96
+ [{'types': ['text'], 'values':
97
+ {
98
+ # Mac address details
99
+ 'Valid MAC address': "True" if response.mac_address_details.is_valid else "False",
100
+ 'Transmission type': response.mac_address_details.transmission_type,
101
+ 'Administration type': response.mac_address_details.administration_type,
102
+
103
+ # Vendor details
104
+ 'OUI': response.vendor_details.oui,
105
+ 'Vendor details are hidden': "True" if response.vendor_details.is_private else "False",
106
+ 'Company name': response.vendor_details.company_name,
107
+ 'Company\'s address': response.vendor_details.company_address,
108
+ 'County code': response.vendor_details.country_code,
109
+
110
+ # Block details
111
+ 'Block found': "True" if response.block_details.block_found else "False",
112
+ 'The left border of the range': response.block_details.border_left,
113
+ 'The right border of the range': response.block_details.border_right,
114
+ 'The total number of MAC addresses in this range': response.block_details.block_size,
115
+ 'Assignment block size': response.block_details.assignment_block_size,
116
+ 'Date when the range was allocated': date_created,
117
+ 'Date when the range was last updated': date_updated
118
+ }}]
119
+ }
120
+
121
+ return results
122
+
123
+
124
+ def introspection():
125
+ return mispattributes
126
+
127
+
128
+ def version():
129
+ moduleinfo['config'] = moduleconfig
130
+ return moduleinfo
@@ -0,0 +1,55 @@
1
+ import requests
2
+ import json
3
+
4
+ misperrors = {'error': 'Error'}
5
+ mispattributes = {'input': ['mac-address'], 'output': ['text']}
6
+ moduleinfo = {
7
+ 'version': '0.1',
8
+ 'author': 'Aurélien Schwab',
9
+ 'description': 'Module to access Macvendors API.',
10
+ 'module-type': ['hover'],
11
+ 'name': 'Macvendors Lookup',
12
+ 'logo': 'macvendors.png',
13
+ 'requirements': [],
14
+ 'features': 'The module takes a MAC address as input and queries macvendors.com for some information about it. The API returns the name of the vendor related to the address.',
15
+ 'references': ['https://macvendors.com/', 'https://macvendors.com/api'],
16
+ 'input': 'A MAC address.',
17
+ 'output': 'Additional information about the MAC address.',
18
+ }
19
+ moduleconfig = ['user-agent']
20
+
21
+ macvendors_api_url = 'https://api.macvendors.com/'
22
+ default_user_agent = 'MISP-Module'
23
+
24
+
25
+ def handler(q=False):
26
+ if q is False:
27
+ return False
28
+ request = json.loads(q)
29
+ for input_type in mispattributes['input']:
30
+ if input_type in request:
31
+ mac = request[input_type]
32
+ break
33
+ else:
34
+ misperrors['error'] = "Unsupported attributes type"
35
+ return misperrors
36
+ user_agent = request['config']['user-agent'] if request.get('config') and request['config'].get('user-agent') else default_user_agent
37
+ r = requests.get(macvendors_api_url + mac, headers={'user-agent': user_agent}) # Real request
38
+ if r.status_code == 200: # OK (record found)
39
+ response = r.text
40
+ if response:
41
+ return {'results': [{'types': mispattributes['output'], 'values': response}]}
42
+ elif r.status_code == 404: # Not found (not an error)
43
+ return {'results': [{'types': mispattributes['output'], 'values': 'Not found'}]}
44
+ else: # Real error
45
+ misperrors['error'] = 'MacVendors API not accessible (HTTP ' + str(r.status_code) + ')'
46
+ return misperrors['error']
47
+
48
+
49
+ def introspection():
50
+ return mispattributes
51
+
52
+
53
+ def version():
54
+ moduleinfo['config'] = moduleconfig
55
+ return moduleinfo
@@ -0,0 +1,107 @@
1
+ import json
2
+ import sys
3
+ import base64
4
+ import io
5
+ import zipfile
6
+ import requests
7
+ import hashlib
8
+ import re
9
+
10
+ misperrors = {'error': 'Error'}
11
+ mispattributes = {'input': ['attachment', 'malware-sample'], 'output': ['link']}
12
+ moduleinfo = {
13
+ 'version': '1',
14
+ 'author': 'Karen Yousefi',
15
+ 'description': 'Module to push malware samples to MalShare',
16
+ 'module-type': ['expansion'],
17
+ 'name': 'MalShare Upload',
18
+ 'requirements': ['requests library'],
19
+ 'logo': '',
20
+ }
21
+
22
+ moduleconfig = ['malshare_apikey']
23
+
24
+
25
+ def handler(q=False):
26
+ if q is False:
27
+ return False
28
+ request = json.loads(q)
29
+
30
+ try:
31
+ data = request.get("data")
32
+ if 'malware-sample' in request:
33
+ sample_filename = request.get("malware-sample").split("|", 1)[0]
34
+ data = base64.b64decode(data)
35
+ fl = io.BytesIO(data)
36
+ zf = zipfile.ZipFile(fl)
37
+ sample_hashname = zf.namelist()[0]
38
+ data = zf.read(sample_hashname, b"infected")
39
+ zf.close()
40
+ elif 'attachment' in request:
41
+ sample_filename = request.get("attachment")
42
+ data = base64.b64decode(data)
43
+ else:
44
+ misperrors['error'] = "No malware sample or attachment supplied"
45
+ return misperrors
46
+ except Exception:
47
+ misperrors['error'] = "Unable to process submitted sample data"
48
+ return misperrors
49
+
50
+ if request["config"].get("malshare_apikey") is None:
51
+ misperrors["error"] = "Missing MalShare API key"
52
+ return misperrors
53
+
54
+ malshare_apikey = request["config"].get("malshare_apikey")
55
+
56
+ try:
57
+ url = "https://malshare.com/api.php"
58
+ params = {'api_key': malshare_apikey, 'action': 'upload'}
59
+ files = {"upload": (sample_filename, data)}
60
+ response = requests.post(url, params=params, files=files)
61
+ response.raise_for_status()
62
+
63
+ response_text = response.text.strip()
64
+
65
+ # Calculate SHA256 of the file
66
+ sha256 = hashlib.sha256(data).hexdigest()
67
+
68
+ if response_text.startswith("Success"):
69
+ # If upload was successful or file already exists
70
+ malshare_link = (
71
+ f"https://malshare.com/sample.php?action=detail&hash={sha256}"
72
+ )
73
+ elif "sample already exists" in response_text:
74
+ # If file already exists, extract SHA256 from response
75
+ match = re.search(r'([a-fA-F0-9]{64})', response_text)
76
+ if match:
77
+ sha256 = match.group(1)
78
+ malshare_link = (
79
+ f"https://malshare.com/sample.php?action=detail&hash={sha256}"
80
+ )
81
+ else:
82
+ # If there's any other error
83
+ raise Exception(f"Upload failed: {response_text}")
84
+
85
+ except Exception as e:
86
+ misperrors['error'] = f"Unable to send sample to MalShare: {str(e)}"
87
+ return misperrors
88
+
89
+ r = {
90
+ 'results': [
91
+ {
92
+ 'types': 'link',
93
+ 'values': malshare_link,
94
+ 'comment': 'Link to MalShare analysis',
95
+ }
96
+ ]
97
+ }
98
+ return r
99
+
100
+
101
+ def introspection():
102
+ return mispattributes
103
+
104
+
105
+ def version():
106
+ moduleinfo['config'] = moduleconfig
107
+ return moduleinfo
@@ -0,0 +1,67 @@
1
+ import json
2
+ import requests
3
+ from . import check_input_attribute, checking_error, standard_error_message
4
+ from pymisp import MISPEvent, MISPObject
5
+
6
+ mispattributes = {'input': ['md5', 'sha1', 'sha256'],
7
+ 'format': 'misp_standard'}
8
+ moduleinfo = {
9
+ 'version': '0.1',
10
+ 'author': 'Christian Studer',
11
+ 'description': 'Query Malware Bazaar to get additional information about the input hash.',
12
+ 'module-type': ['expansion', 'hover'],
13
+ 'name': 'Malware Bazaar Lookup',
14
+ 'logo': '',
15
+ 'requirements': [],
16
+ 'features': "The module takes a hash attribute as input and queries MALWAREbazaar's API to fetch additional data about it. The result, if the payload is known on the databases, is at least one file object describing the file the input hash is related to.\n\nThe module is using the new format of modules able to return object since the result is one or multiple MISP object(s).",
17
+ 'references': ['https://bazaar.abuse.ch/'],
18
+ 'input': 'A hash attribute (md5, sha1 or sha256).',
19
+ 'output': 'File object(s) related to the input attribute found on MALWAREbazaar databases.',
20
+ }
21
+ moduleconfig = []
22
+
23
+
24
+ def parse_response(response):
25
+ mapping = {'file_name': {'type': 'filename', 'object_relation': 'filename'},
26
+ 'file_size': {'type': 'size-in-bytes', 'object_relation': 'size-in-bytes'},
27
+ 'file_type_mime': {'type': 'mime-type', 'object_relation': 'mimetype'},
28
+ 'md5_hash': {'type': 'md5', 'object_relation': 'md5'},
29
+ 'sha1_hash': {'type': 'sha1', 'object_relation': 'sha1'},
30
+ 'sha256_hash': {'type': 'sha256', 'object_relation': 'sha256'},
31
+ 'ssdeep': {'type': 'ssdeep', 'object_relation': 'ssdeep'}}
32
+ misp_event = MISPEvent()
33
+ for data in response:
34
+ misp_object = MISPObject('file')
35
+ for feature, attribute in mapping.items():
36
+ if feature in data:
37
+ misp_attribute = {'value': data[feature]}
38
+ misp_attribute.update(attribute)
39
+ misp_object.add_attribute(**misp_attribute)
40
+ misp_event.add_object(**misp_object)
41
+ return {'results': {'Object': [json.loads(misp_object.to_json()) for misp_object in misp_event.objects]}}
42
+
43
+
44
+ def handler(q=False):
45
+ if q is False:
46
+ return False
47
+ request = json.loads(q)
48
+ if not request.get('attribute') or not check_input_attribute(request['attribute'], requirements=('type', 'value')):
49
+ return {'error': f'{standard_error_message}, {checking_error} that is the hash to submit to Malware Bazaar.'}
50
+ attribute = request['attribute']
51
+ if attribute['type'] not in mispattributes['input']:
52
+ return {'error': 'Unsupported attribute type.'}
53
+ url = 'https://mb-api.abuse.ch/api/v1/'
54
+ response = requests.post(url, data={'query': 'get_info', 'hash': attribute['value']}).json()
55
+ query_status = response['query_status']
56
+ if query_status == 'ok':
57
+ return parse_response(response['data'])
58
+ return {'error': 'Hash not found on MALWAREbazzar' if query_status == 'hash_not_found' else f'Problem encountered during the query: {query_status}'}
59
+
60
+
61
+ def introspection():
62
+ return mispattributes
63
+
64
+
65
+ def version():
66
+ moduleinfo['config'] = moduleconfig
67
+ return moduleinfo