modules.processing.misp

Package modules :: Package processing :: Module misp |
[hide private]
[frames] | no frames]

# Source Code for Module modules.processing.misp

      1  # Copyright (C) 2010-2016 Cuckoo Foundation.
      2  # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
      3  # See the file 'docs/LICENSE' for copying permission.
      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
     25 -    def search_ioc(self, ioc):
     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
     53 -    def _parse_date(self, row):
     54          if not row.get("date"):
     55              return datetime.datetime.now()
     56
     57          return datetime.datetime.strptime(row["date"], "%Y-%m-%d")
     58
     59 -    def run(self):
     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          # Remove empty entries and turn the collection into a list.
     96          iocs = list(iocs.difference((None, "")))
     97
     98          # Acquire all information related to IOCs.
     99          for ioc in iocs[:maxioc]:
    100              self.search_ioc(ioc)
    101
    102          # Sort IOC information by date and return all information.
    103          return sorted(
    104              self.iocs.values(), key=self._parse_date, reverse=True
    105          )
    106