├── README.md
└── misp_stix.py
/README.md:
--------------------------------------------------------------------------------
1 | # MISP-STIX-ESM
2 | [](https://opensource.org/licenses/Apache-2.0)
3 |
4 | This Script will download MISP events in STIX format. McAfee ESM will be configured to pull STIX files from the folder location via SCP and run automated triage processes.
5 |
6 |
7 |
8 | ## Component Description
9 |
10 | **McAfee Enterprise Security Manager (ESM)** is a security information and event management (SIEM) solution that delivers actionable intelligence and integrations to prioritize, investigate, and respond to threats.
11 | https://www.mcafee.com/enterprise/en-us/products/enterprise-security-manager.html
12 |
13 | **MISP** threat sharing platform is free and open source software helping information sharing of threat and cyber security indicators.
14 | https://github.com/MISP/MISP
15 |
16 | ## Prerequisites
17 |
18 | Download the [Latest Release](https://github.com/mohlcyber/MISP-STIX-ESM/releases)
19 | * Extract the release .zip file
20 |
21 | MISP platform installation ([Link](https://github.com/MISP/MISP)) (tested with MISP 2.4.121)
22 |
23 | Requests ([Link](http://docs.python-requests.org/en/master/user/install/#install))
24 |
25 | PyMISP library installation ([Link](https://github.com/MISP/PyMISP))
26 | ```sh
27 | git clone https://github.com/MISP/PyMISP.git
28 | cd PyMISP/
29 | python setup.py install
30 | ```
31 | ## Configuration
32 | MISP receives intelligence feeds from multiple sources. The provided script will export tagged events as STIX files and McAfee ESM will pull these STIX files for automated investigations.
33 |
34 | ### misp_stix.py
35 | The misp_stix.py script will export tagged events as STIX files to a given location.
36 |
37 | Enter the MISP IP/URL, API key, MISP Tag to look for and the location where the STIX files should be stored (line 12 - 15).
38 |
39 |
40 |
41 | ### ESM Configuration
42 |
43 | Log into the McAfee ESM platform and open ESM properties.
44 | Go to the Cyber Threat Feeds and add a new feed. In the source enter the IP, username, password and path to the folder that contains the STIX files that got previous downloaded through the misp_stix.py script.
45 |
46 |
47 |
48 | Define the frequency, watchlist and backtrace options to automate triage steps.
49 |
50 | McAfee ESM will pull new STIX file and check if any events have been seen in the past related to the artifacts.
51 |
--------------------------------------------------------------------------------
/misp_stix.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # Written by mohlcyber v.0.3 12/02/2020
3 |
4 | import sys
5 | import requests
6 | import time
7 |
8 | from pymisp import ExpandedPyMISP
9 |
10 | requests.packages.urllib3.disable_warnings()
11 |
12 | misp_url = 'https://1.1.1.1/'
13 | misp_verify = False
14 | misp_key = 'API Key'
15 | misp_tag = 'McAfee: Export to ESM'
16 | misp_path = 'stix/'
17 |
18 |
19 | class MISP():
20 | def __init__(self):
21 | self.misp = ExpandedPyMISP(misp_url, misp_key, False)
22 | self.headers = {
23 | 'Authorization': misp_key,
24 | 'Accept': 'application/xml',
25 | 'User-Agent': 'PyMISP'
26 | }
27 |
28 | def get_events(self, **kwargs):
29 | tags = kwargs.pop('tags', None)
30 | format = kwargs.pop('format', None)
31 | eid = kwargs.pop('eid', None)
32 | res = self.misp.search(eventid=eid, tags=tags, return_format=format)
33 | return res
34 |
35 | def get_stix(self, eventid, format):
36 | payload = {
37 | "returnFormat": format,
38 | "eventid": eventid
39 | }
40 | stix = requests.post(misp_url + 'events/restSearch', headers=self.headers, data=payload, verify=misp_verify)
41 | return stix.content
42 |
43 | def main(self):
44 | results = self.get_events(tags=misp_tag, format='json')
45 | try:
46 | if results:
47 | for result in results:
48 | eventid = result['Event']['id']
49 | euuid = result['Event']['uuid']
50 |
51 | stix = self.get_stix(eventid, 'stix')
52 | with open(misp_path + 'misp_stix_{0}.xml'.format(str(eventid)), 'w') as esm_stix:
53 | esm_stix.write(stix.decode())
54 | esm_stix.close()
55 | print('SUCCESS: Successful exported the STIX file for event {0}.'.format(str(eventid)))
56 |
57 | objects = result['Event']['Object']
58 | for fields in objects:
59 | for attributes in fields['Attribute']:
60 | attuuid = attributes['uuid']
61 |
62 | if 'Tag' in attributes:
63 | for tags in attributes['Tag']:
64 | atttag = tags['name']
65 | if atttag == misp_tag:
66 | self.misp.untag(attuuid, misp_tag)
67 |
68 | attributes = result['Event']['Attribute']
69 | for fields in attributes:
70 | attuuid = fields['uuid']
71 |
72 | if 'Tag' in fields:
73 | for tags in fields['Tag']:
74 | atttag = tags['name']
75 | if atttag == misp_tag:
76 | self.misp.untag(attuuid, misp_tag)
77 |
78 | self.misp.untag(euuid, misp_tag)
79 |
80 | else:
81 | print('STATUS: Could not find Events that are tagged with {0}.'.format(str(misp_tag)))
82 | except Exception as e:
83 | exc_type, exc_obj, exc_tb = sys.exc_info()
84 | print("ERROR: Error in {location}.{funct_name}() - line {line_no} : {error}"
85 | .format(location=__name__, funct_name=sys._getframe().f_code.co_name, line_no=exc_tb.tb_lineno,
86 | error=str(e)))
87 |
88 |
89 | if __name__ == '__main__':
90 |
91 | while True:
92 | misp = MISP()
93 | misp.main()
94 | time.sleep(60)
--------------------------------------------------------------------------------