1
2
3
4
5 import datetime
6 import logging
7 import os.path
8
9 from lib.cuckoo.common.abstracts import Processing
10 from lib.cuckoo.common.exceptions import CuckooDependencyError
11 from lib.cuckoo.common.exceptions import CuckooProcessingError
12
13 try:
14 from pymisp import PyMISP
15 HAVE_MISP = True
16 except ImportError:
17 HAVE_MISP = False
18
19 log = logging.getLogger(__name__)
20
21 -class MISP(Processing):
22 """Enrich Cuckoo results with MISP data."""
23 order = 3
24
26 try:
27 r = self.misp.search_all(ioc)
28 except Exception as e:
29 log.debug("Error searching for IOC (%r) on MISP: %s", ioc, e)
30 return
31
32 if not r:
33 return
34
35 for row in r.get("response", []):
36 event = row.get("Event", {})
37 event_id = event.get("id")
38
39 if event_id not in self.iocs:
40 url = os.path.join(self.url, "events/view", "%s" % event_id)
41 self.iocs[event_id] = {
42 "event_id": event_id,
43 "date": event.get("date"),
44 "url": url,
45 "level": event.get("threat_level_id"),
46 "info": event.get("info", "").strip(),
47 "iocs": [],
48 }
49
50 if ioc not in self.iocs[event_id]["iocs"]:
51 self.iocs[event_id]["iocs"].append(ioc)
52
54 if not row.get("date"):
55 return datetime.datetime.now()
56
57 return datetime.datetime.strptime(row["date"], "%Y-%m-%d")
58
60 """Run analysis.
61 @return: MISP results dict.
62 """
63
64 if not HAVE_MISP:
65 raise CuckooDependencyError(
66 "Unable to import PyMISP (install with `pip install pymisp`)"
67 )
68
69 self.url = self.options.get("url", "")
70 self.apikey = self.options.get("apikey", "")
71 maxioc = int(self.options.get("maxioc", 100))
72
73 if not self.url or not self.apikey:
74 raise CuckooProcessingError(
75 "Please configure the URL and API key for your MISP instance."
76 )
77
78 self.key = "misp"
79 self.iocs = {}
80
81 self.misp = PyMISP(self.url, self.apikey, False, "json")
82 iocs = set()
83
84 iocs.add(self.results.get("target", {}).get("file", {}).get("md5"))
85
86 for dropped in self.results.get("dropped", []):
87 iocs.add(dropped.get("md5"))
88
89 iocs.update(self.results.get("network", {}).get("hosts", []))
90
91 for block in self.results.get("network", {}).get("domains", []):
92 iocs.add(block.get("ip"))
93 iocs.add(block.get("domain"))
94
95
96 iocs = list(iocs.difference((None, "")))
97
98
99 for ioc in iocs[:maxioc]:
100 self.search_ioc(ioc)
101
102
103 return sorted(
104 self.iocs.values(), key=self._parse_date, reverse=True
105 )
106