modules.processing.snort

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

# Source Code for Module modules.processing.snort

      1  # Copyright (C) 2010-2013 Claudio Guarnieri.
      2  # Copyright (C) 2014-2016 Cuckoo Foundation.
      3  # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
      4  # See the file 'docs/LICENSE' for copying permission.
      5
      6  import datetime
      7  import logging
      8  import os.path
      9  import re
     10  import subprocess
     11
     12  from lib.cuckoo.common.abstracts import Processing
     13  from lib.cuckoo.common.exceptions import CuckooProcessingError
     14
     15  log = logging.getLogger(__name__)
     16
     17 -class Snort(Processing):
     18      """Snort processing module."""
     19
     20      # Thanks to Steve Handerson for the following regex query.
     21      alert_re = re.compile(
     22          r"(?P<timestamp>\d{2}/\d{2}/\d{2}-\d{2}:\d{2}:\d{2}\.\d+)\s+"
     23          r"\[\*\*\]\s+\[\d+:(?P<sid>\d+):(?P<revision>\d+)\] "
     24          r"(?P<message>.+) \[\*\*\]\s+(\[Classification: (?P<classtype>.+)\] )?"
     25          r"\[Priority: (?P<priority>\d+)\] \{(?P<protocol>[:a-zA-Z0-9_-]+)\} "
     26          r"(?P<src>.+) \-\> (?P<dest>.+)"
     27      )
     28
     29 -    def run(self):
     30          self.key = "snort"
     31
     32          results = {
     33              "alerts": [],
     34          }
     35
     36          self.snort = self.options.get("snort", "/usr/local/bin/snort")
     37          self.config_path = self.options.get("conf", "/etc/snort/snort.conf")
     38
     39          if not os.path.isfile(self.pcap_path):
     40              log.warning("Unable to run Snort as no pcap is available")
     41              return results
     42
     43          if not os.path.isfile(self.snort):
     44              raise CuckooProcessingError("Unable to locate Snort binary")
     45
     46          if not os.path.isfile(self.config_path):
     47              raise CuckooProcessingError(
     48                  "Unable to locate Snort configuration")
     49
     50          args = [
     51              self.snort,
     52              "-c", self.config_path,
     53              "-A", "console",
     54              "-r", self.pcap_path,
     55              "-q", "-y",
     56          ]
     57
     58          try:
     59              output = subprocess.check_output(args)
     60          except subprocess.CalledProcessError as e:
     61              raise CuckooProcessingError(
     62                  "Snort returned an error processing this pcap: %s" % e)
     63
     64          for line in output.split("\n"):
     65              if not line:
     66                  continue
     67
     68              x = self.alert_re.match(line)
     69              if not x:
     70                  log.warning("Error matching Snort line: %r", line)
     71                  continue
     72
     73              timestamp = datetime.datetime.strptime(
     74                  x.group("timestamp"), "%m/%d/%y-%H:%M:%S.%f")
     75
     76              if ":" in x.group("src"):
     77                  src_ip, src_port = x.group("src").rsplit(":", 1)
     78              else:
     79                  src_ip = x.group("src")
     80                  src_port = None
     81
     82              if ":" in x.group("dest"):
     83                  dst_ip, dst_port = x.group("dest").rsplit(":", 1)
     84              else:
     85                  dst_ip = x.group("dest")
     86                  dst_port = None
     87
     88              results["alerts"].append({
     89                  "timestamp": timestamp,
     90                  "sid": int(x.group("sid")),
     91                  "priority": int(x.group("priority")),
     92                  "revision": int(x.group("revision")),
     93                  "message": x.group("message"),
     94                  "src_ip": src_ip,
     95                  "src_port": int(src_port) if src_port else None,
     96                  "dst_ip": dst_ip,
     97                  "dst_port": int(dst_port) if dst_port else None,
     98                  "protocol": x.group("protocol"),
     99                  "classtype": x.group("classtype"),
    100              })
    101
    102          return results
    103