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,150 @@
1
+ ######################################################
2
+ # #
3
+ # Author: Stanislav Klevtsov, Ukraine; Feb 2019. #
4
+ # #
5
+ # #
6
+ # Script was tested on the following configuration: #
7
+ # MISP v2.4.90 #
8
+ # Cisco Firesight Manager Console v6.2.3 (bld 84) #
9
+ # #
10
+ ######################################################
11
+
12
+ import json
13
+ import base64
14
+ from urllib.parse import quote
15
+
16
+ misperrors = {'error': 'Error'}
17
+
18
+ moduleinfo = {
19
+ 'version': '1',
20
+ 'author': 'Stanislav Klevtsov',
21
+ 'description': 'Module to export malicious network activity attributes to Cisco fireSIGHT manager block rules.',
22
+ 'module-type': ['export'],
23
+ 'name': 'Cisco fireSIGHT blockrule Export',
24
+ 'logo': 'cisco.png',
25
+ 'requirements': ['Firesight manager console credentials'],
26
+ 'features': 'The module goes through the attributes to find all the network activity ones in order to create block rules for the Cisco fireSIGHT manager.',
27
+ 'references': [],
28
+ 'input': 'Network activity attributes (IPs, URLs).',
29
+ 'output': 'Cisco fireSIGHT manager block rules.',
30
+ }
31
+
32
+
33
+ moduleconfig = ['fmc_ip_addr', 'fmc_login', 'fmc_pass', 'domain_id', 'acpolicy_id']
34
+
35
+ fsmapping = {"ip-dst": "dst", "url": "request"}
36
+
37
+ mispattributes = {'input': list(fsmapping.keys())}
38
+
39
+ # options: event, attribute, event-collection, attribute-collection
40
+ inputSource = ['event']
41
+
42
+ outputFileExtension = 'sh'
43
+ responseType = 'application/txt'
44
+
45
+ # .sh file templates
46
+ SH_FILE_HEADER = """#!/bin/sh\n\n"""
47
+
48
+ BLOCK_JSON_TMPL = """
49
+ BLOCK_RULE='{{ "action": "BLOCK", "enabled": true, "type": "AccessRule", "name": "{rule_name}", "destinationNetworks": {{ "literals": [ {dst_networks} ] }}, "urls": {{ "literals": [ {urls} ] }}, "newComments": [ "{event_info_comment}" ] }}'\n
50
+ """
51
+
52
+ BLOCK_DST_JSON_TMPL = """{{ "type": "Host", "value": "{ipdst}" }} """
53
+ BLOCK_URL_JSON_TMPL = """{{ "type": "Url", "url": "{url}" }} """
54
+
55
+ CURL_ADD_RULE_TMPL = """
56
+ curl -X POST -v -k -H 'Content-Type: application/json' -H \"Authorization: Basic $LOGINPASS_BASE64\" -H \"X-auth-access-token: $ACC_TOKEN\" -i \"https://$FIRESIGHT_IP_ADDR/api/fmc_config/v1/domain/$DOMAIN_ID/policy/accesspolicies/$ACPOLICY_ID/accessrules\" --data \"$BLOCK_RULE\" """
57
+
58
+
59
+ def handler(q=False):
60
+ if q is False:
61
+ return False
62
+
63
+ r = {'results': []}
64
+ request = json.loads(q)
65
+
66
+ if "config" in request:
67
+ config = request["config"]
68
+
69
+ # check if config is empty
70
+ if not config['fmc_ip_addr']:
71
+ config['fmc_ip_addr'] = "0.0.0.0"
72
+ if not config['fmc_login']:
73
+ config['fmc_login'] = "login"
74
+ if not config['fmc_pass']:
75
+ config['fmc_pass'] = "password"
76
+ if not config['domain_id']:
77
+ config['domain_id'] = "SET_FIRESIGHT_DOMAIN_ID"
78
+ if not config['acpolicy_id']:
79
+ config['acpolicy_id'] = "SET_FIRESIGHT_ACPOLICY_ID"
80
+
81
+ data = request["data"]
82
+ output = ""
83
+ ipdst = []
84
+ urls = []
85
+
86
+ # populate the ACL rule with attributes
87
+ for ev in data:
88
+
89
+ event = ev["Attribute"]
90
+ event_id = ev["Event"]["id"]
91
+ event_info = ev["Event"]["info"]
92
+
93
+ for index, attr in enumerate(event):
94
+ if attr["to_ids"] is True:
95
+ if attr["type"] in fsmapping:
96
+ if attr["type"] == "ip-dst":
97
+ ipdst.append(BLOCK_DST_JSON_TMPL.format(ipdst=attr["value"]))
98
+ else:
99
+ urls.append(BLOCK_URL_JSON_TMPL.format(url=quote(attr["value"], safe='@/:;?&=-_.,+!*')))
100
+
101
+ # building the .sh file
102
+ output += SH_FILE_HEADER
103
+ output += "FIRESIGHT_IP_ADDR='{}'\n".format(config['fmc_ip_addr'])
104
+
105
+ output += "LOGINPASS_BASE64=`echo -n '{}:{}' | base64`\n".format(config['fmc_login'], config['fmc_pass'])
106
+ output += "DOMAIN_ID='{}'\n".format(config['domain_id'])
107
+ output += "ACPOLICY_ID='{}'\n\n".format(config['acpolicy_id'])
108
+
109
+ output += "ACC_TOKEN=`curl -X POST -v -k -sD - -o /dev/null -H \"Authorization: Basic $LOGINPASS_BASE64\" -i \"https://$FIRESIGHT_IP_ADDR/api/fmc_platform/v1/auth/generatetoken\" | grep -i x-auth-acc | sed 's/.*:\\ //g' | tr -d '[:space:]' | tr -d '\\n'`\n"
110
+
111
+ output += BLOCK_JSON_TMPL.format(rule_name="misp_event_{}".format(event_id),
112
+ dst_networks=', '.join(ipdst),
113
+ urls=', '.join(urls),
114
+ event_info_comment=event_info) + "\n"
115
+
116
+ output += CURL_ADD_RULE_TMPL
117
+ # END building the .sh file
118
+
119
+ r = {"data": base64.b64encode(output.encode('utf-8')).decode('utf-8')}
120
+ return r
121
+
122
+
123
+ def introspection():
124
+ modulesetup = {}
125
+ try:
126
+ responseType
127
+ modulesetup['responseType'] = responseType
128
+ except NameError:
129
+ pass
130
+ try:
131
+ userConfig
132
+ modulesetup['userConfig'] = userConfig
133
+ except NameError:
134
+ pass
135
+ try:
136
+ outputFileExtension
137
+ modulesetup['outputFileExtension'] = outputFileExtension
138
+ except NameError:
139
+ pass
140
+ try:
141
+ inputSource
142
+ modulesetup['inputSource'] = inputSource
143
+ except NameError:
144
+ pass
145
+ return modulesetup
146
+
147
+
148
+ def version():
149
+ moduleinfo['config'] = moduleconfig
150
+ return moduleinfo
@@ -0,0 +1,141 @@
1
+ """
2
+ Export module for coverting MISP events into Defender for Endpoint KQL queries.
3
+ Config['Period'] : allows to define period over witch to look for IOC from now
4
+ """
5
+
6
+ import base64
7
+ import json
8
+
9
+ misperrors = {"error": "Error"}
10
+
11
+ types_to_use = ['sha256', 'sha1', 'md5', 'domain', 'ip-src', 'ip-dst', 'url']
12
+
13
+ userConfig = {
14
+
15
+ }
16
+
17
+ moduleconfig = ["Period"]
18
+ inputSource = ['event']
19
+
20
+ outputFileExtension = 'kql'
21
+ responseType = 'application/txt'
22
+
23
+ moduleinfo = {
24
+ 'version': '1.1',
25
+ 'author': 'Julien Bachmann, Hacknowledge, Maik Wuerth',
26
+ 'description': 'Defender for Endpoint KQL hunting query export module',
27
+ 'module-type': ['export'],
28
+ 'name': 'Microsoft Defender for Endpoint KQL Export',
29
+ 'logo': 'defender_endpoint.png',
30
+ 'requirements': [],
31
+ 'features': 'This module export an event as Defender for Endpoint KQL queries that can then be used in your own python3 or Powershell tool. If you are using Microsoft Sentinel, you can directly connect your MISP instance to Sentinel and then create queries using the `ThreatIntelligenceIndicator` table to match events against imported IOC.',
32
+ 'references': ['https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/advanced-hunting-schema-reference'],
33
+ 'input': 'MISP Event attributes',
34
+ 'output': 'Defender for Endpoint KQL queries',
35
+ }
36
+
37
+
38
+ def handle_sha256(value, period):
39
+ query = f"""find in (DeviceEvents, DeviceAlertEvents,AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents)
40
+ where (SHA256 == '{value}' or InitiatingProcessSHA1 == '{value}') and
41
+ Timestamp between(ago({period}) .. now())"""
42
+ return query.replace('\n', ' ')
43
+
44
+
45
+ def handle_sha1(value, period):
46
+ query = f"""find in (DeviceEvents, DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents)
47
+ where (SHA1 == '{value}' or InitiatingProcessSHA1 == '{value}') and
48
+ Timestamp between(ago({period}) .. now())"""
49
+ return query.replace('\n', ' ')
50
+
51
+
52
+ def handle_md5(value, period):
53
+ query = f"""find in (DeviceEvents, DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents)
54
+ where (MD5 == '{value}' or InitiatingProcessMD5 == '{value}') and
55
+ Timestamp between(ago({period}) .. now())"""
56
+ return query.replace('\n', ' ')
57
+
58
+
59
+ def handle_domain(value, period):
60
+ query = f"""find in (DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceNetworkEvents)
61
+ where RemoteUrl contains '{value}' and
62
+ Timestamp between(ago({period}) .. now())"""
63
+ return query.replace('\n', ' ')
64
+
65
+
66
+ def handle_ip(value, period):
67
+ query = f"""find in (DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceNetworkEvents)
68
+ where RemoteIP == '{value}' and
69
+ Timestamp between(ago({period}) .. now())"""
70
+ return query.replace('\n', ' ')
71
+
72
+
73
+ def handle_url(value, period):
74
+ query = f"""let url = '{value}';
75
+ search in (EmailUrlInfo,UrlClickEvents,DeviceNetworkEvents,DeviceFileEvents,DeviceEvents,BehaviorEntities, AlertInfo, AlertEvidence, DeviceAlertEvents)
76
+ Timestamp between(ago({period}) .. now()) and
77
+ RemoteUrl has url
78
+ or FileOriginUrl has url
79
+ or FileOriginReferrerUrl has url
80
+ or Url has url"""
81
+ return query.replace('\n', ' ')
82
+
83
+
84
+ handlers = {
85
+ 'sha256': handle_sha256,
86
+ 'sha1': handle_sha1,
87
+ 'md5': handle_md5,
88
+ 'domain': handle_url,
89
+ 'ip-src': handle_ip,
90
+ 'ip-dst': handle_ip,
91
+ 'url': handle_url
92
+ }
93
+
94
+
95
+ def handler(q=False):
96
+ if q is False:
97
+ return False
98
+ request = json.loads(q)
99
+ config = request.get("config", {"Period": ""})
100
+ output = ''
101
+
102
+ for event in request["data"]:
103
+ for attribute in event["Attribute"]:
104
+ if attribute['type'] in types_to_use:
105
+ output = output + handlers[attribute['type']](attribute['value'], config['Period']) + '\n'
106
+ for obj in event["Object"]:
107
+ for attribute in obj["Attribute"]:
108
+ if attribute['type'] in types_to_use:
109
+ output = output + handlers[attribute['type']](attribute['value'], config['Period']) + '\n'
110
+ r = {"response": [], "data": str(base64.b64encode(bytes(output, 'utf-8')), 'utf-8')}
111
+ return r
112
+
113
+
114
+ def introspection():
115
+ modulesetup = {}
116
+ try:
117
+ responseType
118
+ modulesetup['responseType'] = responseType
119
+ except NameError:
120
+ pass
121
+ try:
122
+ userConfig
123
+ modulesetup['userConfig'] = userConfig
124
+ except NameError:
125
+ pass
126
+ try:
127
+ outputFileExtension
128
+ modulesetup['outputFileExtension'] = outputFileExtension
129
+ except NameError:
130
+ pass
131
+ try:
132
+ inputSource
133
+ modulesetup['inputSource'] = inputSource
134
+ except NameError:
135
+ pass
136
+ return modulesetup
137
+
138
+
139
+ def version():
140
+ moduleinfo['config'] = moduleconfig
141
+ return moduleinfo
@@ -0,0 +1,255 @@
1
+ import json
2
+ import base64
3
+ from pymisp import MISPEvent
4
+ from collections import defaultdict, Counter
5
+
6
+ misperrors = {'error': 'Error'}
7
+ moduleinfo = {
8
+ 'version': '1',
9
+ 'author': 'Christian Studer',
10
+ 'description': 'This module is used to export MISP events containing transaction objects into GoAML format.',
11
+ 'module-type': ['export'],
12
+ 'name': 'GoAML Export',
13
+ 'require_standard_format': True,
14
+ 'logo': 'goAML.jpg',
15
+ 'requirements': ['PyMISP', 'MISP objects'],
16
+ 'features': "The module works as long as there is at least one transaction object in the Event.\n\nThen in order to have a valid GoAML document, please follow these guidelines:\n- For each transaction object, use either a bank-account, person, or legal-entity object to describe the origin of the transaction, and again one of them to describe the target of the transaction.\n- Create an object reference for both origin and target objects of the transaction.\n- A bank-account object needs a signatory, which is a person object, put as object reference of the bank-account.\n- A person can have an address, which is a geolocation object, put as object reference of the person.\n\nSupported relation types for object references that are recommended for each object are the folowing:\n- transaction:\n\t- 'from', 'from_my_client': Origin of the transaction - at least one of them is required.\n\t- 'to', 'to_my_client': Target of the transaction - at least one of them is required.\n\t- 'address': Location of the transaction - optional.\n- bank-account:\n\t- 'signatory': Signatory of a bank-account - the reference from bank-account to a signatory is required, but the relation-type is optional at the moment since this reference will always describe a signatory.\n\t- 'entity': Entity owning the bank account - optional.\n- person:\n\t- 'address': Address of a person - optional.",
17
+ 'references': ['http://goaml.unodc.org/'],
18
+ 'input': 'MISP objects (transaction, bank-account, person, legal-entity, geolocation), with references, describing financial transactions and their origin and target.',
19
+ 'output': 'GoAML format file, describing financial transactions, with their origin and target (bank accounts, persons or entities).',
20
+ }
21
+ moduleconfig = ['rentity_id']
22
+ mispattributes = {'input': ['MISPEvent'], 'output': ['xml file']}
23
+ outputFileExtension = "xml"
24
+ responseType = "application/xml"
25
+
26
+ objects_to_parse = ['transaction', 'bank-account', 'person', 'entity', 'geolocation']
27
+
28
+ goAMLmapping = {'bank-account': {'bank-account': 't_account', 'institution-name': 'institution_name',
29
+ 'institution-code': 'institution_code', 'iban': 'iban', 'swift': 'swift',
30
+ 'branch': 'branch', 'non-banking-institution': 'non_bank_institution',
31
+ 'account': 'account', 'currency-code': 'currency_code',
32
+ 'account-name': 'account_name', 'client-number': 'client_number',
33
+ 'personal-account-type': 'personal_account_type', 'opened': 'opened',
34
+ 'closed': 'closed', 'balance': 'balance', 'status-code': 'status_code',
35
+ 'beneficiary': 'beneficiary', 'beneficiary-comment': 'beneficiary_comment',
36
+ 'comments': 'comments'},
37
+ 'person': {'person': 't_person', 'text': 'comments', 'first-name': 'first_name',
38
+ 'middle-name': 'middle_name', 'last-name': 'last_name', 'title': 'title',
39
+ 'mothers-name': 'mothers_name', 'alias': 'alias', 'date-of-birth': 'birthdate',
40
+ 'place-of-birth': 'birth_place', 'gender': 'gender', 'nationality': 'nationality1',
41
+ 'passport-number': 'passport_number', 'passport-country': 'passport_country',
42
+ 'social-security-number': 'ssn', 'identity-card-number': 'id_number'},
43
+ 'geolocation': {'geolocation': 'location', 'city': 'city', 'region': 'state',
44
+ 'country': 'country_code', 'address': 'address', 'zipcode': 'zip'},
45
+ 'transaction': {'transaction': 'transaction', 'transaction-number': 'transactionnumber',
46
+ 'date': 'date_transaction', 'location': 'transaction_location',
47
+ 'transmode-code': 'transmode_code', 'amount': 'amount_local',
48
+ 'transmode-comment': 'transmode_comment', 'date-posting': 'date_posting',
49
+ 'teller': 'teller', 'authorized': 'authorized',
50
+ 'text': 'transaction_description'},
51
+ 'legal-entity': {'legal-entity': 'entity', 'name': 'name', 'business': 'business',
52
+ 'commercial-name': 'commercial_name', 'phone-number': 'phone',
53
+ 'legal-form': 'incorporation_legal_form',
54
+ 'registration-number': 'incorporation_number'}}
55
+
56
+ referencesMapping = {'bank-account': {'aml_type': '{}_account', 'bracket': 't_{}'},
57
+ 'person': {'transaction': {'aml_type': '{}_person', 'bracket': 't_{}'}, 'bank-account': {'aml_type': 't_person', 'bracket': 'signatory'}},
58
+ 'legal-entity': {'transaction': {'aml_type': '{}_entity', 'bracket': 't_{}'}, 'bank-account': {'aml_type': 't_entity'}},
59
+ 'geolocation': {'aml_type': 'address', 'bracket': 'addresses'}}
60
+
61
+
62
+ class GoAmlGeneration(object):
63
+ def __init__(self, config):
64
+ self.config = config
65
+ self.parsed_uuids = defaultdict(list)
66
+
67
+ def from_event(self, event):
68
+ self.misp_event = MISPEvent()
69
+ self.misp_event.load(event)
70
+
71
+ def parse_objects(self):
72
+ uuids = defaultdict(list)
73
+ report_code = []
74
+ currency_code = []
75
+ for obj in self.misp_event.objects:
76
+ obj_type = obj.name
77
+ uuids[obj_type].append(obj.uuid)
78
+ if obj_type == 'bank-account':
79
+ try:
80
+ report_code.append(obj.get_attributes_by_relation('report-code')[0].value.split(' ')[0])
81
+ currency_code.append(obj.get_attributes_by_relation('currency-code')[0].value)
82
+ except IndexError:
83
+ print('report_code or currency_code error')
84
+ self.uuids, self.report_codes, self.currency_codes = uuids, report_code, currency_code
85
+
86
+ def build_xml(self):
87
+ self.xml = {'header': "<report><rentity_id>{}</rentity_id><submission_code>E</submission_code>".format(self.config),
88
+ 'data': ""}
89
+ if "STR" in self.report_codes:
90
+ report_code = "STR"
91
+ else:
92
+ report_code = Counter(self.report_codes).most_common(1)[0][0]
93
+ self.xml['header'] += "<report_code>{}</report_code>".format(report_code)
94
+ submission_date = str(self.misp_event.timestamp).replace(' ', 'T')
95
+ self.xml['header'] += "<submission_date>{}</submission_date>".format(submission_date)
96
+ self.xml['header'] += "<currency_code_local>{}</currency_code_local>".format(Counter(self.currency_codes).most_common(1)[0][0])
97
+ for trans_uuid in self.uuids.get('transaction'):
98
+ self.itterate('transaction', 'transaction', trans_uuid, 'data')
99
+ person_to_parse = [person_uuid for person_uuid in self.uuids.get('person') if person_uuid not in self.parsed_uuids.get('person')]
100
+ if len(person_to_parse) == 1:
101
+ self.itterate('person', 'reporting_person', person_to_parse[0], 'header')
102
+ try:
103
+ location_to_parse = [location_uuid for location_uuid in self.uuids.get('geolocation') if location_uuid not in self.parsed_uuids.get('geolocation')]
104
+ if len(location_to_parse) == 1:
105
+ self.itterate('geolocation', 'location', location_to_parse[0], 'header')
106
+ except TypeError:
107
+ pass
108
+ self.xml['data'] += "</report>"
109
+
110
+ def itterate(self, object_type, aml_type, uuid, xml_part):
111
+ obj = self.misp_event.get_object_by_uuid(uuid)
112
+ if object_type == 'transaction':
113
+ self.xml[xml_part] += "<{}>".format(aml_type)
114
+ self.fill_xml_transaction(object_type, obj.attributes, xml_part)
115
+ self.parsed_uuids[object_type].append(uuid)
116
+ if obj.ObjectReference:
117
+ self.parseObjectReferences(object_type, xml_part, obj.ObjectReference)
118
+ self.xml[xml_part] += "</{}>".format(aml_type)
119
+ else:
120
+ if 'to_' in aml_type or 'from_' in aml_type:
121
+ relation_type = aml_type.split('_')[0]
122
+ self.xml[xml_part] += "<{0}_funds_code>{1}</{0}_funds_code>".format(relation_type, self.from_and_to_fields[relation_type]['funds'].split(' ')[0])
123
+ self.itterate_normal_case(object_type, obj, aml_type, uuid, xml_part)
124
+ self.xml[xml_part] += "<{0}_country>{1}</{0}_country>".format(relation_type, self.from_and_to_fields[relation_type]['country'])
125
+ else:
126
+ self.itterate_normal_case(object_type, obj, aml_type, uuid, xml_part)
127
+
128
+ def itterate_normal_case(self, object_type, obj, aml_type, uuid, xml_part):
129
+ self.xml[xml_part] += "<{}>".format(aml_type)
130
+ self.fill_xml(object_type, obj, xml_part)
131
+ self.parsed_uuids[object_type].append(uuid)
132
+ if obj.ObjectReference:
133
+ self.parseObjectReferences(object_type, xml_part, obj.ObjectReference)
134
+ self.xml[xml_part] += "</{}>".format(aml_type)
135
+
136
+ def parseObjectReferences(self, object_type, xml_part, references):
137
+ for ref in references:
138
+ next_uuid = ref.referenced_uuid
139
+ next_object_type = ref.Object.get('name')
140
+ relationship_type = ref.relationship_type
141
+ self.parse_references(object_type, next_object_type, next_uuid, relationship_type, xml_part)
142
+
143
+ def fill_xml_transaction(self, object_type, attributes, xml_part):
144
+ from_and_to_fields = {'from': {}, 'to': {}}
145
+ for attribute in attributes:
146
+ object_relation = attribute.object_relation
147
+ attribute_value = attribute.value
148
+ if object_relation == 'date-posting':
149
+ self.xml[xml_part] += "<late_deposit>True</late_deposit>"
150
+ elif object_relation in ('from-funds-code', 'to-funds-code'):
151
+ relation_type, field, _ = object_relation.split('-')
152
+ from_and_to_fields[relation_type][field] = attribute_value
153
+ continue
154
+ elif object_relation in ('from-country', 'to-country'):
155
+ relation_type, field = object_relation.split('-')
156
+ from_and_to_fields[relation_type][field] = attribute_value
157
+ continue
158
+ try:
159
+ self.xml[xml_part] += "<{0}>{1}</{0}>".format(goAMLmapping[object_type][object_relation], attribute_value)
160
+ except KeyError:
161
+ pass
162
+ self.from_and_to_fields = from_and_to_fields
163
+
164
+ def fill_xml(self, object_type, obj, xml_part):
165
+ if obj.name == 'bank-account':
166
+ for attribute in obj.attributes:
167
+ if attribute.object_relation in ('personal-account-type', 'status-code'):
168
+ attribute_value = attribute.value.split(' - ')[0]
169
+ else:
170
+ attribute_value = attribute.value
171
+ try:
172
+ self.xml[xml_part] += "<{0}>{1}</{0}>".format(goAMLmapping[object_type][attribute.object_relation], attribute_value)
173
+ except KeyError:
174
+ pass
175
+ else:
176
+ for attribute in obj.attributes:
177
+ try:
178
+ self.xml[xml_part] += "<{0}>{1}</{0}>".format(goAMLmapping[object_type][attribute.object_relation], attribute.value)
179
+ except KeyError:
180
+ pass
181
+
182
+ def parse_references(self, object_type, next_object_type, uuid, relationship_type, xml_part):
183
+ reference = referencesMapping[next_object_type]
184
+ try:
185
+ next_aml_type = reference[object_type].get('aml_type').format(relationship_type.split('_')[0])
186
+ try:
187
+ bracket = reference[object_type].get('bracket').format(relationship_type)
188
+ self.xml[xml_part] += "<{}>".format(bracket)
189
+ self.itterate(next_object_type, next_aml_type, uuid, xml_part)
190
+ self.xml[xml_part] += "</{}>".format(bracket)
191
+ except KeyError:
192
+ self.itterate(next_object_type, next_aml_type, uuid, xml_part)
193
+ except KeyError:
194
+ next_aml_type = reference.get('aml_type').format(relationship_type.split('_')[0])
195
+ bracket = reference.get('bracket').format(relationship_type)
196
+ self.xml[xml_part] += "<{}>".format(bracket)
197
+ self.itterate(next_object_type, next_aml_type, uuid, xml_part)
198
+ self.xml[xml_part] += "</{}>".format(bracket)
199
+
200
+
201
+ def handler(q=False):
202
+ if q is False:
203
+ return False
204
+ request = json.loads(q)
205
+ if 'data' not in request:
206
+ return False
207
+ if not request.get('config') and not request['config'].get('rentity_id'):
208
+ misperrors['error'] = "Configuration error."
209
+ return misperrors
210
+ config = request['config'].get('rentity_id')
211
+ export_doc = GoAmlGeneration(config)
212
+ export_doc.from_event(request['data'][0])
213
+ if not export_doc.misp_event.Object:
214
+ misperrors['error'] = "There is no object in this event."
215
+ return misperrors
216
+ types = []
217
+ for obj in export_doc.misp_event.Object:
218
+ types.append(obj.name)
219
+ if 'transaction' not in types:
220
+ misperrors['error'] = "There is no transaction object in this event."
221
+ return misperrors
222
+ export_doc.parse_objects()
223
+ export_doc.build_xml()
224
+ exp_doc = "{}{}".format(export_doc.xml.get('header'), export_doc.xml.get('data'))
225
+ return {'response': [], 'data': str(base64.b64encode(bytes(exp_doc, 'utf-8')), 'utf-8')}
226
+
227
+
228
+ def introspection():
229
+ modulesetup = {}
230
+ try:
231
+ responseType
232
+ modulesetup['responseType'] = responseType
233
+ except NameError:
234
+ pass
235
+ try:
236
+ userConfig
237
+ modulesetup['userConfig'] = userConfig
238
+ except NameError:
239
+ pass
240
+ try:
241
+ outputFileExtension
242
+ modulesetup['outputFileExtension'] = outputFileExtension
243
+ except NameError:
244
+ pass
245
+ try:
246
+ inputSource
247
+ moduleSetup['inputSource'] = inputSource
248
+ except NameError:
249
+ pass
250
+ return modulesetup
251
+
252
+
253
+ def version():
254
+ moduleinfo['config'] = moduleconfig
255
+ return moduleinfo
@@ -0,0 +1,97 @@
1
+ import json
2
+ import base64
3
+
4
+ misperrors = {'error': 'Error'}
5
+
6
+ moduleinfo = {
7
+ 'version': '1',
8
+ 'author': 'TM',
9
+ 'description': 'Lite export of a MISP event.',
10
+ 'module-type': ['export'],
11
+ 'name': 'Lite Export',
12
+ 'logo': '',
13
+ 'requirements': [],
14
+ 'features': 'This module is simply producing a json MISP event format file, but exporting only Attributes from the Event. Thus, MISP Events exported with this module should have attributes that are not internal references, otherwise the resulting event would be empty.',
15
+ 'references': [],
16
+ 'input': 'MISP Event attributes',
17
+ 'output': 'Lite MISP Event',
18
+ }
19
+
20
+ moduleconfig = ["indent_json_export"]
21
+
22
+ mispattributes = {}
23
+ outputFileExtension = "json"
24
+ responseType = "application/json"
25
+
26
+
27
+ def handler(q=False):
28
+ if q is False:
29
+ return False
30
+
31
+ request = json.loads(q)
32
+
33
+ config = {}
34
+ if "config" in request:
35
+ config = request["config"]
36
+ else:
37
+ config = {"indent_json_export": None}
38
+
39
+ if config['indent_json_export'] is not None:
40
+ try:
41
+ config['indent_json_export'] = int(config['indent_json_export'])
42
+ except Exception:
43
+ config['indent_json_export'] = None
44
+
45
+ if 'data' not in request:
46
+ return False
47
+
48
+ # ~ Misp json structur
49
+ liteEvent = {'Event': {}}
50
+
51
+ for evt in request['data']:
52
+ rawEvent = evt['Event']
53
+ liteEvent['Event']['info'] = rawEvent['info']
54
+ liteEvent['Event']['Attribute'] = []
55
+
56
+ attrs = evt['Attribute']
57
+ for attr in attrs:
58
+ if 'Internal reference' not in attr['category']:
59
+ liteAttr = {}
60
+ liteAttr['category'] = attr['category']
61
+ liteAttr['type'] = attr['type']
62
+ liteAttr['value'] = attr['value']
63
+ liteEvent['Event']['Attribute'].append(liteAttr)
64
+
65
+ return {'response': [],
66
+ 'data': str(base64.b64encode(bytes(
67
+ json.dumps(liteEvent, indent=config['indent_json_export']), 'utf-8')), 'utf-8')}
68
+
69
+
70
+ def introspection():
71
+ modulesetup = {}
72
+ try:
73
+ responseType
74
+ modulesetup['responseType'] = responseType
75
+ except NameError:
76
+ pass
77
+ try:
78
+ userConfig
79
+ modulesetup['userConfig'] = userConfig
80
+ except NameError:
81
+ pass
82
+ try:
83
+ outputFileExtension
84
+ modulesetup['outputFileExtension'] = outputFileExtension
85
+ except NameError:
86
+ pass
87
+ try:
88
+ inputSource
89
+ modulesetup['inputSource'] = inputSource
90
+ except NameError:
91
+ pass
92
+ return modulesetup
93
+
94
+
95
+ def version():
96
+ moduleinfo['config'] = moduleconfig
97
+ return moduleinfo