示例#1
0
    def test_load_signature_map(self):

        sigmap = maps.SignatureMap()
        with open("tests/sid-msg.map") as infile:
            sigmap.load_signature_map(infile)

        # Get a basic signature.
        sig = sigmap.get(1, 2000356)
        self.assertTrue(sig is not None)
        self.assertEqual(1, sig["gid"])
        self.assertEqual(2000356, sig["sid"])
        self.assertEqual("ET POLICY IRC connection", sig["msg"])
        self.assertEqual(len(sig["ref"]), 1)
        self.assertEqual("url,doc.emergingthreats.net/2000356", sig["ref"][0])

        # Try again but with a gid of 3.
        self.assertEqual(sig, sigmap.get(3, 2000356))

        # This signature has multiple refs.
        sig = sigmap.get(1, 2000373)
        self.assertEqual(3, len(sig["ref"]))

        sig = sigmap.get(1, 71918985)
        self.assertEqual(
            "SN: Inbound TCP traffic from suspect network (AS29073 - NL)",
            sig["msg"])
示例#2
0
 def rehash(self):
     try:
         self.sigmap = maps.SignatureMap()
         self.sigmap.load_generator_map(
             open(self.config['global']['generator_map']))
         self.sigmap.load_signature_map(
             open(self.config['global']['signature_map']))
         self.sigmap_timestamp = os.path.getmtime(
             self.config['global']['signature_map'])
         self.genmap_timestamp = os.path.getmtime(
             self.config['global']['generator_map'])
     except Exception, e:
         raise CharlotteConfigError("Error reading signature maps: %s" % e)
示例#3
0
    def test_load_signature_v2_map(self):

        sigmap = maps.SignatureMap()
        sigmap.load_signature_map(open("tests/sid-msg-v2.map"))

        sig = sigmap.get(1, 2495)
        self.assertEquals(1, sig["gid"])
        self.assertEquals(2495, sig["sid"])
        self.assertEquals("misc-attack", sig["classification"])
        self.assertEquals(0, sig["priority"])
        self.assertEquals(
            "GPL NETBIOS SMB DCEPRC ORPCThis request flood attempt",
            sig["msg"])
        self.assertEquals(4, len(sig["ref"]))
示例#4
0
    def test_load_generator_map(self):

        sigmap = maps.SignatureMap()
        sigmap.load_generator_map(open("tests/gen-msg.map"))

        sig = sigmap.get(1, 1)
        self.assertTrue(sig is not None)
        self.assertEquals(1, sig["gid"])
        self.assertEquals(1, sig["sid"])
        self.assertEquals("snort general alert", sig["msg"])

        sig = sigmap.get(139, 1)
        self.assertTrue(sig is not None)
        self.assertEquals(139, sig["gid"])
        self.assertEquals(1, sig["sid"])
        self.assertEquals(
            "sensitive_data: sensitive data global threshold exceeded",
            sig["msg"])
示例#5
0
    def get_events(cls, path=None, file=None):

        if path is None:
            path = cls.CONFIG['DEFAULT_LOG_PATH']

        if file is None:
            file = cls.CONFIG['DEFAULT_LOG_FILE']

        events = []

        try:
            sigmap = maps.SignatureMap()
            sigmap.load_generator_map(open(cls.CONFIG.get('GEN_MAP_PATH')))
            sigmap.load_signature_map(open(cls.CONFIG.get('SIG_MAP_PATH')))

            reader = unified2.SpoolRecordReader(path, file, follow=False)

            for record in reader:
                if isinstance(record, unified2.Event):

                    event_details = sigmap.get(record['generator-id'],
                                               record['signature-id'])

                    event = NetworkEvent(cls.__name__)
                    events.append(event)

                    event.src_ip = record['source-ip']
                    event.dest_ip = record['destination-ip']
                    event.protocol = record['protocol']
                    event.src_port = record['sport-itype']
                    event.dest_port = record['dport-icode']
                    event.signature = event_details[
                        'msg'] if event_details else 'SID: {}'.format(
                            record['signature-id'])
                    if event_details:
                        event.reference = json.dumps(event_details['ref'])

        except Exception as e:
            flash(e.__class__.__name__, "error")

        return events
示例#6
0
    def test_load_signature_map(self):

        sigmap = maps.SignatureMap()
        sigmap.load_signature_map(open("tests/sid-msg.map"))

        # Get a basic signature.
        sig = sigmap.get(1, 2000356)
        self.assertTrue(sig is not None)
        self.assertEquals(1, sig["gid"])
        self.assertEquals(2000356, sig["sid"])
        self.assertEquals("ET POLICY IRC connection", sig["msg"])
        self.assertEquals(len(sig["ref"]), 1)
        self.assertEquals("url,doc.emergingthreats.net/2000356", sig["ref"][0])

        # Try again but with a gid of 3.
        self.assertEquals(sig, sigmap.get(3, 2000356))

        # This signature has multiple refs.
        sig = sigmap.get(1, 2000373)
        print(sig)
        self.assertEquals(3, len(sig["ref"]))
示例#7
0
def main():

    msgmap = maps.SignatureMap()
    classmap = maps.ClassificationMap()

    parser = argparse.ArgumentParser(
        fromfile_prefix_chars='@', epilog=epilog)
    parser.add_argument(
        "-C", dest="classification_path", metavar="<classification.config>",
        help="path to classification config")
    parser.add_argument(
        "-S", dest="sidmsgmap_path", metavar="<msg-msg.map>",
        help="path to sid-msg.map")
    parser.add_argument(
        "-G", dest="genmsgmap_path", metavar="<gen-msg.map>",
        help="path to gen-msg.map")
    parser.add_argument(
        "--snort-conf", dest="snort_conf", metavar="<snort.conf>",
        help="attempt to load classifications and map files based on the "
        "location of the snort.conf")
    parser.add_argument(
        "--directory", metavar="<spool directory>",
        help="spool directory (eg: /var/log/snort)")
    parser.add_argument(
        "--prefix", metavar="<spool file prefix>",
        help="spool filename prefix (eg: unified2.log)")
    parser.add_argument(
        "--bookmark", action="store_true", default=False,
        help="enable bookmarking")
    parser.add_argument(
        "--follow", action="store_true", default=False,
        help="follow files/continuous mode (spool mode only)")
    parser.add_argument(
        "--delete", action="store_true", default=False,
        help="delete spool files")
    parser.add_argument(
        "-o", "--output", metavar="<filename>",
        help="output filename (eg: /var/log/snort/alerts.json")
    parser.add_argument(
        "--stdout", action="store_true", default=False,
        help="also log to stdout if --output is a file")
    parser.add_argument(
        "--packet-printable", action="store_true", default=False,
        help="add packet_printable field to events")
    parser.add_argument(
        "--packet-hex", action="store_true", default=False,
        help="add packet_hex field to events")
    parser.add_argument(
        "filenames", nargs="*")
    args = parser.parse_args()

    if args.snort_conf:
        load_from_snort_conf(args.snort_conf, classmap, msgmap)

    if args.classification_path:
        classmap.load_from_file(
            open(os.path.expanduser(args.classification_path)))
    if args.genmsgmap_path:
        msgmap.load_generator_map(open(os.path.expanduser(args.genmsgmap_path)))
    if args.sidmsgmap_path:
        msgmap.load_signature_map(open(os.path.expanduser(args.sidmsgmap_path)))

    if msgmap.size() == 0:
        LOG.warning("WARNING: No alert message map entries loaded.")
    else:
        LOG.info("Loaded %s rule message map entries.", msgmap.size())

    if classmap.size() == 0:
        LOG.warning("WARNING: No classifications loaded.")
    else:
        LOG.info("Loaded %s classifications.", classmap.size())

    eve_filter = EveFilter(
        msgmap, classmap, packet_printable=args.packet_printable,
        packet_hex=args.packet_hex)

    outputs = []

    if args.output:
        outputs.append(OutputWrapper(args.output))
        if args.stdout:
            outputs.append(OutputWrapper("-", sys.stdout))
    else:
        outputs.append(OutputWrapper("-", sys.stdout))

    writer = Writer(outputs, eve_filter)

    bookmark = None

    if args.directory and args.prefix:
        init_filename, init_offset = None, None
        if args.bookmark:
            bookmark = unified2.Unified2Bookmark(
                args.directory, args.prefix)
            init_filename, init_offset = bookmark.get()
        rollover_handler = RolloverHandler(args.delete)
        reader = unified2.SpoolRecordReader(
            directory=args.directory,
            prefix=args.prefix,
            follow=args.follow,
            init_filename=init_filename,
            init_offset=init_offset,
            rollover_hook=rollover_handler.on_rollover)
    elif args.filenames:
        if args.bookmark:
            LOG.error("Bookmarking not supported in file mode, exiting.")
            return 1
        reader = unified2.FileRecordReader(*args.filenames)
    else:
        print("nothing to do.")
        return

    event = None
    last_record_time = time.time()
    queue = []

    while True:
        flush = False
        record = reader.next()
        done = False
        if not record:
            if event and time.time() - last_record_time > 1.0:
                queue.append(event)
                event = None
                flush = True
            else:
                if args.follow:
                    time.sleep(0.01)
                else:
                    if event:
                        queue.append(event)
                    flush = True
                    done = True
        else:

            last_record_time = time.time()

            if isinstance(record, unified2.Event):
                if event is not None:
                    queue.append(event)
                    flush = True
                event = record
            elif isinstance(record, unified2.ExtraData):
                if not event:
                    continue
                event["extra-data"].append(record)
            elif isinstance(record, unified2.Packet):
                if not event:
                    queue.append(record)
                    flush = True
                else:
                    if "packet" in event:
                        queue.append(record)
                    else:
                        event["packet"] = record

        if flush:
            for record in queue:
                writer.write(record)
            if args.bookmark and bookmark:
                location = reader.tell()
                bookmark.update(*location)
            queue = []

        if done:
            break
示例#8
0
def main():

    msgmap = maps.SignatureMap()
    classmap = maps.ClassificationMap()

    parser = argparse.ArgumentParser(fromfile_prefix_chars='@', epilog=epilog)
    parser.add_argument("-C",
                        dest="classification_path",
                        metavar="<classification.config>",
                        help="path to classification config")
    parser.add_argument("-S",
                        dest="sidmsgmap_path",
                        metavar="<msg-msg.map>",
                        help="path to sid-msg.map")
    parser.add_argument("-G",
                        dest="genmsgmap_path",
                        metavar="<gen-msg.map>",
                        help="path to gen-msg.map")
    parser.add_argument(
        "--snort-conf",
        dest="snort_conf",
        metavar="<snort.conf>",
        help="attempt to load classifications and map files based on the "
        "location of the snort.conf")
    parser.add_argument("--directory",
                        metavar="<spool directory>",
                        help="spool directory (eg: /var/log/snort)")
    parser.add_argument("--prefix",
                        metavar="<spool file prefix>",
                        help="spool filename prefix (eg: unified2.log)")
    parser.add_argument("--bookmark",
                        metavar="<filename>",
                        help="enable bookmarking")
    parser.add_argument("--follow",
                        action="store_true",
                        default=False,
                        help="follow files/continuous mode (spool mode only)")
    parser.add_argument("--cs",
                        metavar="<cybersift ip>",
                        help="Specify the CyberSift Server IP Address")
    parser.add_argument("--delete",
                        action="store_true",
                        default=False,
                        help="delete spool files")
    parser.add_argument("--output",
                        metavar="<filename>",
                        help="output filename (eg: /var/log/snort/alerts.json")
    parser.add_argument("--stdout",
                        action="store_true",
                        default=False,
                        help="also log to stdout if --output is a file")
    parser.add_argument(
        "--sort-keys",
        dest="sort_keys",
        action="store_true",
        default=False,
        help="the output of dictionaries will be sorted by key")
    parser.add_argument("--verbose",
                        action="store_true",
                        default=False,
                        help="be more verbose")
    parser.add_argument("filenames", nargs="*")
    args = parser.parse_args()

    if args.verbose:
        LOG.setLevel(logging.DEBUG)

    if args.snort_conf:
        load_from_snort_conf(args.snort_conf, classmap, msgmap)

    if args.cs:
        elastic_ip = args.cs
        es = Elasticsearch(
            ["http://" + elastic_ip + ":80/cybersift_elasticsearch/"],
            timeout=600)
    else:
        LOG.error("Cannot proceed without a valid CyberSift IP")
        sys.exit(1)

    if args.classification_path:
        classmap.load_from_file(
            open(os.path.expanduser(args.classification_path)))
    if args.genmsgmap_path:
        msgmap.load_generator_map(open(os.path.expanduser(
            args.genmsgmap_path)))
    if args.sidmsgmap_path:
        msgmap.load_signature_map(open(os.path.expanduser(
            args.sidmsgmap_path)))

    if msgmap.size() == 0:
        LOG.warn("No alert message map entries loaded.")
    else:
        LOG.info("Loaded %s rule message map entries.", msgmap.size())

    if classmap.size() == 0:
        LOG.warn("No classifications loaded.")
    else:
        LOG.info("Loaded %s classifications.", classmap.size())

    outputs = []

    if args.output:
        outputs.append(OutputWrapper(args.output))
        if args.stdout:
            outputs.append(OutputWrapper("-", sys.stdout))
    else:
        outputs.append(OutputWrapper("-", sys.stdout))

    bookmark = None

    if args.filenames:
        if args.bookmark:
            LOG.error("Bookmarking not valid in file mode.")
            return 1
        if args.follow:
            LOG.error("Follow not valid in file mode.")
            return 1
        if args.delete:
            LOG.error("Delete not valid in file mode.")
            return 1
        reader = unified2.FileRecordReader(*args.filenames)
    elif args.directory and args.prefix:
        if args.bookmark:
            current_snort_pid = str(check_output(["pgrep", "-u",
                                                  "snort"])).strip()
            bookmark = unified2.Unified2Bookmark(filename=args.bookmark + '_' +
                                                 current_snort_pid)
            init_filename, init_offset = bookmark.get()
        else:
            init_filename = None
            init_offset = None
        reader = unified2.SpoolRecordReader(
            directory=args.directory,
            prefix=args.prefix,
            follow=args.follow,
            rollover_hook=rollover_hook if args.delete else None,
            init_filename=init_filename,
            init_offset=init_offset)
    else:
        LOG.error("No spool or files provided.")
        return 1

    formatter = Formatter(msgmap=msgmap, classmap=classmap)

    count = 0

    record = True

    try:
        while record is not None:
            record = reader.next()
            if record is not None:
                try:
                    as_json = formatter.format(record)
                    if 'event' in as_json:
                        create_snort_module_alert(as_json, es)
                    count += 1
                except Exception as err:
                    LOG.error("Failed to encode record as JSON: %s: %s" %
                              (str(err), str(record)))
                if bookmark:
                    filename, offset = reader.tell()
                    bookmark.update(filename, offset)
    except unified2.UnknownRecordType as err:
        if count == 0:
            LOG.error("%s: Is this a unified2 file?" % (err))
        else:
            LOG.error(err)
示例#9
0
def main():

    msgmap = maps.SignatureMap()
    classmap = maps.ClassificationMap()

    parser = argparse.ArgumentParser(
        fromfile_prefix_chars='@', epilog=epilog)
    parser.add_argument(
        "-C", dest="classification_path", metavar="<classification.config>",
        help="path to classification config")
    parser.add_argument(
        "-S", dest="sidmsgmap_path", metavar="<msg-msg.map>",
        help="path to sid-msg.map")
    parser.add_argument(
        "-G", dest="genmsgmap_path", metavar="<gen-msg.map>",
        help="path to gen-msg.map")
    parser.add_argument(
        "--snort-conf", dest="snort_conf", metavar="<snort.conf>",
        help="attempt to load classifications and map files based on the "
        "location of the snort.conf")
    parser.add_argument(
        "--directory", metavar="<spool directory>",
        help="spool directory (eg: /var/log/snort)")
    parser.add_argument(
        "--prefix", metavar="<spool file prefix>",
        help="spool filename prefix (eg: unified2.log)")
    parser.add_argument(
        "--bookmark", metavar="<filename>", help="enable bookmarking")
    parser.add_argument(
        "--follow", action="store_true", default=False,
        help="follow files/continuous mode (spool mode only)")
    parser.add_argument(
        "--delete", action="store_true", default=False,
        help="delete spool files")
    parser.add_argument(
        "--output", metavar="<filename>",
        help="output filename (eg: /var/log/snort/alerts.json")
    parser.add_argument(
        "--stdout", action="store_true", default=False,
        help="also log to stdout if --output is a file")
    parser.add_argument(
        "--verbose", action="store_true", default=False,
        help="be more verbose")
    parser.add_argument(
        "filenames", nargs="*")
    args = parser.parse_args()

    if args.verbose:
        LOG.setLevel(logging.DEBUG)

    if args.snort_conf:
        load_from_snort_conf(args.snort_conf, classmap, msgmap)

    if args.classification_path:
        classmap.load_from_file(
            open(os.path.expanduser(args.classification_path)))
    if args.genmsgmap_path:
        msgmap.load_generator_map(open(os.path.expanduser(args.genmsgmap_path)))
    if args.sidmsgmap_path:
        msgmap.load_signature_map(open(os.path.expanduser(args.sidmsgmap_path)))

    if msgmap.size() == 0:
        LOG.warn("No alert message map entries loaded.")
    else:
        LOG.info("Loaded %s rule message map entries.", msgmap.size())

    if classmap.size() == 0:
        LOG.warn("No classifications loaded.")
    else:
        LOG.info("Loaded %s classifications.", classmap.size())

    outputs = []

    if args.output:
        outputs.append(OutputWrapper(args.output))
        if args.stdout:
            outputs.append(OutputWrapper("-", sys.stdout))
    else:
        outputs.append(OutputWrapper("-", sys.stdout))

    bookmark = None

    if args.filenames:
        if args.bookmark:
            LOG.error("Bookmarking not valid in file mode.")
            return 1
        if args.follow:
            LOG.error("Follow not valid in file mode.")
            return 1
        if args.delete:
            LOG.error("Delete not valid in file mode.")
            return 1
        reader = unified2.FileRecordReader(*args.filenames)
    elif args.directory and args.prefix:
        if args.bookmark:
            bookmark = unified2.Unified2Bookmark(filename=args.bookmark)
            init_filename, init_offset = bookmark.get()
        else:
            init_filename = None
            init_offset = None
        reader = unified2.SpoolRecordReader(
            directory=args.directory,
            prefix=args.prefix,
            follow=args.follow,
            rollover_hook=rollover_hook if args.delete else None,
            init_filename=init_filename,
            init_offset=init_offset)
    else:
        LOG.error("No spool or files provided.")
        return 1

    formatter = Formatter(msgmap=msgmap, classmap=classmap)

    count = 0

    try:
        for record in reader:
            try:
                as_json = json.dumps(formatter.format(record))
                for out in outputs:
                    out.write(as_json)
                count += 1
            except Exception as err:
                LOG.error("Failed to encode record as JSON: %s: %s" % (
                    str(err), str(record)))
            if bookmark:
                filename, offset = reader.tell()
                bookmark.update(filename, offset)
    except unified2.UnknownRecordType as err:
        if count == 0:
            LOG.error("%s: Is this a unified2 file?" % (err))
        else:
            LOG.error(err)
示例#10
0
def main():

    msgmap = maps.SignatureMap()
    classmap = maps.ClassificationMap()

    parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
    parser.add_argument("-C",
                        dest="classification_path",
                        metavar="<classification.config>",
                        help="path to classification config")
    parser.add_argument("-S",
                        dest="sidmsgmap_path",
                        metavar="<msg-msg.map>",
                        help="path to sid-msg.map")
    parser.add_argument("-G",
                        dest="genmsgmap_path",
                        metavar="<gen-msg.map>",
                        help="path to gen-msg.map")
    parser.add_argument(
        "--snort-conf",
        dest="snort_conf",
        metavar="<snort.conf>",
        help="attempt to load classifications and map files based on the "
        "location of the snort.conf")
    parser.add_argument("--directory",
                        metavar="<spool directory>",
                        help="spool directory (eg: /var/log/snort)")
    parser.add_argument("--prefix",
                        metavar="<spool file prefix>",
                        help="spool filename prefix (eg: unified2.log)")
    parser.add_argument("--bookmark",
                        action="store_true",
                        default=False,
                        help="enable bookmarking")
    parser.add_argument("--follow",
                        action="store_true",
                        default=False,
                        help="follow files/continuous mode (spool mode only)")
    parser.add_argument("filenames", nargs="*")
    args = parser.parse_args()

    if args.snort_conf:
        load_from_snort_conf(args.snort_conf, classmap, msgmap)

    if args.classification_path:
        classmap.load_from_file(
            open(os.path.expanduser(args.classification_path)))
    if args.genmsgmap_path:
        msgmap.load_generator_map(open(os.path.expanduser(
            args.genmsgmap_path)))
    if args.sidmsgmap_path:
        msgmap.load_signature_map(open(os.path.expanduser(
            args.sidmsgmap_path)))

    if msgmap.size() == 0:
        LOG.warn("WARNING: No alert message map entries loaded.")
    else:
        LOG.info("Loaded %s rule message map entries.", msgmap.size())

    if classmap.size() == 0:
        LOG.warn("WARNING: No classifications loaded.")
    else:
        LOG.info("Loaded %s classifications.", classmap.size())

    if args.directory and args.prefix:
        reader = unified2.SpoolEventReader(directory=args.directory,
                                           prefix=args.prefix,
                                           follow=args.follow,
                                           bookmark=args.bookmark)

        for event in reader:
            print_event(event, msgmap, classmap)

    elif args.filenames:
        reader = unified2.FileEventReader(*args.filenames)
        for event in reader:
            print_event(event, msgmap, classmap)

    else:
        parser.print_help()
        return 1
示例#11
0
 def __init__(self, config_path):
     self.classmap = maps.ClassificationMap()
     self.msgmap = maps.SignatureMap()
     self.load_from_config_path(config_path)
示例#12
0
        required=False,
        type=int,
        help="Spool to the output file every threshold_seconds, 20 by default")

    return parser


parser = create_parser()
args = parser.parse_args()

assert os.path.exists(
    args.directory), args.directory + ': no such file or directory'
assert os.path.exists(os.path.dirname(
    args.output)), os.path.dirname(args.output) + ': no such file or directory'

msgmap = maps.SignatureMap()
classmap = maps.ClassificationMap()
formatter = Formatter(msgmap=msgmap, classmap=classmap)

reader = unified2.SpoolRecordReader(directory=args.directory,
                                    prefix=args.prefix,
                                    follow=True,
                                    init_filename=None,
                                    init_offset=None)

labels = [
    'generator-id', 'signature-id', 'blocked', 'source-ip', 'dport-icode'
]

alert_count = {}
text_collector = {}
示例#13
0
def main():

    msgmap = maps.SignatureMap()
    classmap = maps.ClassificationMap()

    parser = argparse.ArgumentParser(fromfile_prefix_chars='@', epilog=epilog)
    parser.add_argument("-C",
                        dest="classification_path",
                        metavar="<classification.config>",
                        help="path to classification config")
    parser.add_argument("-S",
                        dest="sidmsgmap_path",
                        metavar="<msg-msg.map>",
                        help="path to sid-msg.map")
    parser.add_argument("-G",
                        dest="genmsgmap_path",
                        metavar="<gen-msg.map>",
                        help="path to gen-msg.map")
    parser.add_argument(
        "--snort-conf",
        dest="snort_conf",
        metavar="<snort.conf>",
        help="attempt to load classifications and map files based on the "
        "location of the snort.conf")
    parser.add_argument("--directory",
                        metavar="<spool directory>",
                        help="spool directory (eg: /var/log/snort)")
    parser.add_argument("--prefix",
                        metavar="<spool file prefix>",
                        help="spool filename prefix (eg: unified2.log)")
    parser.add_argument("--bookmark",
                        action="store_true",
                        default=False,
                        help="enable bookmarking")
    parser.add_argument("--follow",
                        action="store_true",
                        default=False,
                        help="follow files/continuous mode (spool mode only)")
    parser.add_argument("--delete",
                        action="store_true",
                        default=False,
                        help="delete spool files")
    parser.add_argument("--output",
                        metavar="<filename>",
                        help="output filename (eg: /var/log/snort/alerts.json")
    parser.add_argument("--stdout",
                        action="store_true",
                        default=False,
                        help="also log to stdout if --output is a file")
    parser.add_argument("filenames", nargs="*")
    args = parser.parse_args()

    if args.snort_conf:
        load_from_snort_conf(args.snort_conf, classmap, msgmap)

    if args.classification_path:
        classmap.load_from_file(
            open(os.path.expanduser(args.classification_path)))
    if args.genmsgmap_path:
        msgmap.load_generator_map(open(os.path.expanduser(
            args.genmsgmap_path)))
    if args.sidmsgmap_path:
        msgmap.load_signature_map(open(os.path.expanduser(
            args.sidmsgmap_path)))

    if msgmap.size() == 0:
        LOG.warn("WARNING: No alert message map entries loaded.")
    else:
        LOG.info("Loaded %s rule message map entries.", msgmap.size())

    if classmap.size() == 0:
        LOG.warn("WARNING: No classifications loaded.")
    else:
        LOG.info("Loaded %s classifications.", classmap.size())

    eve_filter = EveFilter(msgmap, classmap)

    outputs = []

    if args.output:
        outputs.append(OutputWrapper(args.output))
        if args.stdout:
            outputs.append(OutputWrapper("-", sys.stdout))
    else:
        outputs.append(OutputWrapper("-", sys.stdout))

    if args.directory and args.prefix:
        reader = unified2.SpoolEventReader(directory=args.directory,
                                           prefix=args.prefix,
                                           follow=args.follow,
                                           delete=args.delete,
                                           bookmark=args.bookmark)
    elif args.filenames:
        reader = unified2.FileEventReader(*args.filenames)
    else:
        print("nothing to do.")
        return

    for event in reader:
        try:
            encoded = json.dumps(eve_filter.filter(event))
            for out in outputs:
                out.write(encoded)
        except Exception as err:
            LOG.error("Failed to encode record as JSON: %s: %s" %
                      (str(err), str(event)))
示例#14
0
def main():

    module = AnsibleModule(argument_spec=dict(
        rule=dict(required=True, default=None),
        state=dict(choices=['present', 'absent'], required=True),
        rules_file=dict(required=False,
                        default='/etc/snort/rules/ansible_managed.rules'),
    ),
                           supports_check_mode=True)

    if not HAS_IDSTOOLS:
        module.fail_json(
            msg=
            "Python module idstools not found on host, but is required for snort_rule Ansible module"
        )

    try:
        matched_rules = [
            snort_rule
            for snort_rule in rule.parse_file(module.params['rules_file']) if
            to_text(snort_rule) == to_text(rule.parse(module.params['rule']))
        ]
    except IOError:
        module.fail_json(
            msg=
            "rule file {} not found or permission was denied attempting access it"
            .format(module.params['rules_file']))
    rule_found = True if matched_rules else False

    sigmap = maps.SignatureMap()
    try:
        sigmap.load_generator_map(open(GENMAP_FILE, 'r'))
    except IOError:
        module.fail_json(
            msg=
            "generator file {} not found or permission was denied attempting to access it"
            .format(GENMAP_FILE))
    try:
        sigmap.load_signature_map(open(SIGMAP_FILE, 'r'))
    except IOError:
        module.fail_json(
            msg=
            "signature file {} not found or permission was denied attempting to access it"
            .format(SIGMAP_FILE))

    if module.params['state'] == 'present' and rule_found:
        module.exit_json(
            msg="Rule '{}' already present in rules_file {}".format(
                module.params['rule'], module.params['rules_file']),
            changed=False)
    elif module.params['state'] == 'present' and not rule_found:
        if module.check_mode:
            module.exit_json(
                msg="Rule '{}' would be added to rules_file {}".format(
                    module.params['rule'], module.params['rules_file']),
                changed=True)

        new_snort_rule = rule.parse(module.params['rule'])

        with open(module.params['rules_file'], 'a') as rules_file:
            rules_file.write(to_text("\n{}".format(new_snort_rule)))

        with open(SIGMAP_FILE, 'a') as sigmap_file:
            if "ref" in new_snort_rule and len(new_snort_rule["ref"]) > 0:
                sigmap_file.write(
                    to_text("\n{} || {} || {}".format(
                        new_snort_rule['sid'], new_snort_rule['msg'],
                        " || ".join(new_snort_rule['ref']))))
            else:
                sigmap_file.write(
                    to_text("\n{} || {}".format(new_snort_rule['sid'],
                                                new_snort_rule['msg'])))

        module.exit_json(msg="Rule '{}' added to rules_file {}".format(
            module.params['rule'], module.params['rules_file']),
                         changed=True)

    if module.params['state'] == 'absent' and not rule_found:
        module.exit_json(
            msg="Rule '{}' does not exist in rules_file {}".format(
                module.params['rule'], module.params['rules_file']),
            changed=False)
    elif module.params['state'] == 'absent' and rule_found:
        new_snort_rule = rule.parse(module.params['rule'])

        changed = False

        orig_rulefile_contents = []
        orig_sigmapfile_contents = []
        new_rulefile_contents = []
        new_sigmapfile_contents = []
        with open(module.params['rules_file'], 'r') as rules_file:
            orig_rulefile_contents = rules_file.readlines()
        with open(SIGMAP_FILE, 'r') as sigmap_file:
            orig_sigmapfile_contents = sigmap_file.readlines()

        new_rulefile_contents = [
            line for line in orig_rulefile_contents
            if new_snort_rule != rule.parse(line)
        ]

        if "ref" in new_snort_rule and len(new_snort_rule["ref"]) > 0:
            new_sigmapfile_contents = [
                line for line in orig_sigmapfile_contents
                if "{} || {} || {}".format(
                    new_snort_rule['sid'], new_snort_rule['msg'], ' || '.join(
                        new_snort_rule['ref'])) != line.strip()
            ]
        else:
            new_sigmapfile_contents = [
                line for line in orig_sigmapfile_contents
                if "{} || {}".format(new_snort_rule['sid'],
                                     new_snort_rule['msg']) != line.strip()
            ]

        if module.check_mode:
            if len(orig_rulefile_contents) != len(new_rulefile_contents):
                module.exit_json(
                    msg="Rule '{}' would have been removed from rules_file {}".
                    format(module.params['rule'], module.params['rules_file']),
                    changed=True)

        if len(orig_rulefile_contents) != len(new_rulefile_contents):
            changed = True
            with open(module.params['rules_file'], 'w') as rules_file:
                for line in new_rulefile_contents:
                    rules_file.write(line)

        if new_sigmapfile_contents and (len(orig_sigmapfile_contents) !=
                                        len(new_sigmapfile_contents)):
            changed = True
            with open(SIGMAP_FILE, 'w') as sigmap_file:
                for line in new_sigmapfile_contents:
                    sigmap_file.write(line)

        module.exit_json(
            msg="Rule '{}' has been removed from rules_file {}".format(
                module.params['rule'], module.params['rules_file']),
            changed=changed)