Project

General

Profile

Bug #2069 » u2bin.py

alienvault alienvault, 03/24/2017 07:55 AM

 
1
# Copyright (c) 2011 Jason Ish
2
# All rights reserved.
3
#
4
# Redistribution and use in source and binary forms, with or without
5
# modification, are permitted provided that the following conditions
6
# are met:
7
#
8
# 1. Redistributions of source code must retain the above copyright
9
#    notice, this list of conditions and the following disclaimer.
10
# 2. Redistributions in binary form must reproduce the above copyright
11
#    notice, this list of conditions and the following disclaimer in the
12
#    documentation and/or other materials provided with the distribution.
13
#
14
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
18
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24
# POSSIBILITY OF SUCH DAMAGE.
25

    
26
"""Read unified2 log files and output events in "fast" style. """
27

    
28
from __future__ import print_function
29

    
30
import sys
31
import os
32
import os.path
33

    
34
if sys.argv[0] == __file__:
35
    sys.path.insert(
36
        0, os.path.abspath(os.path.join(__file__, "..", "..", "..")))
37

    
38
import time
39
import logging
40

    
41
try:
42
    import argparse
43
except ImportError as err:
44
    from idstools.compat.argparse import argparse
45

    
46
from idstools import unified2
47
from idstools import maps
48

    
49
logging.basicConfig(level=logging.INFO, format="%(message)s")
50
LOG = logging.getLogger()
51

    
52
proto_map = {
53
    1: "ICMP",
54
    6: "TCP",
55
    17: "UDP",
56
}
57

    
58
def print_time(sec, usec):
59
    tt = time.localtime(sec)
60
    return "%04d/%02d/%02d-%02d:%02d:%02d.%06d" % (
61
        tt.tm_year, tt.tm_mon, tt.tm_mday, tt.tm_hour, tt.tm_min, tt.tm_sec,
62
        usec)
63

    
64
def print_event(event, msgmap, classmap):
65
    msg_entry = msgmap.get(event["generator-id"], event["signature-id"])
66
    if msg_entry:
67
        msg = msg_entry["msg"]
68
    else:
69
        msg = "Snort Event"
70

    
71
    class_entry = classmap.get(event["classification-id"])
72
    if class_entry:
73
        class_description = class_entry["description"]
74
    else:
75
        class_description = str(event["classification-id"])
76

    
77
    proto = proto_map.get(event["protocol"], str(event["protocol"]))
78

    
79
    """
80
    print("%s [**] [%d:%d:%d] %s [**] [Classification: %s] [Priority: %d] {%s} %s:%d -> %s:%d" % (
81
            print_time(event["event-second"], event["event-microsecond"]),
82
            event["generator-id"],
83
            event["signature-id"],
84
            event["signature-revision"],
85
            msg,
86
            class_description,
87
            event["priority"],
88
            proto,
89
            event["source-ip"],
90
            event["sport-itype"],
91
            event["destination-ip"],
92
            event["dport-icode"],
93
            ))
94
    """
95
    print( "\n" )
96
    print( event )
97

    
98
def load_from_snort_conf(snort_conf, classmap, msgmap):
99
    snort_etc = os.path.dirname(snort_conf)
100

    
101
    classification_config = os.path.join(snort_etc, "classification.config")
102
    if os.path.exists(classification_config):
103
        LOG.debug("Loading %s.", classification_config)
104
        classmap.load_from_file(open(classification_config))
105

    
106
    genmsg_map = os.path.join(snort_etc, "gen-msg.map")
107
    if os.path.exists(genmsg_map):
108
        LOG.debug("Loading %s.", genmsg_map)
109
        msgmap.load_generator_map(open(genmsg_map))
110

    
111
    sidmsg_map = os.path.join(snort_etc, "sid-msg.map")
112
    if os.path.exists(sidmsg_map):
113
        LOG.debug("Loading %s.", sidmsg_map)
114
        msgmap.load_signature_map(open(sidmsg_map))
115

    
116
def main():
117

    
118
    msgmap = maps.SignatureMap()
119
    classmap = maps.ClassificationMap()
120

    
121
    parser = argparse.ArgumentParser(
122
        fromfile_prefix_chars='@')
123
    parser.add_argument(
124
        "-C", dest="classification_path", metavar="<classification.config>",
125
        help="path to classification config")
126
    parser.add_argument(
127
        "-S", dest="sidmsgmap_path", metavar="<msg-msg.map>",
128
        help="path to sid-msg.map")
129
    parser.add_argument(
130
        "-G", dest="genmsgmap_path", metavar="<gen-msg.map>",
131
        help="path to gen-msg.map")
132
    parser.add_argument(
133
        "--snort-conf", dest="snort_conf", metavar="<snort.conf>",
134
        help="attempt to load classifications and map files based on the "
135
        "location of the snort.conf")
136
    parser.add_argument(
137
        "--directory", metavar="<spool directory>",
138
        help="spool directory (eg: /var/log/snort)")
139
    parser.add_argument(
140
        "--prefix", metavar="<spool file prefix>",
141
        help="spool filename prefix (eg: unified2.log)")
142
    parser.add_argument(
143
        "--bookmark", action="store_true", default=False,
144
        help="enable bookmarking")
145
    parser.add_argument(
146
        "--follow", action="store_true", default=False,
147
        help="follow files/continuous mode (spool mode only)")
148
    parser.add_argument(
149
        "filenames", nargs="*")
150
    args = parser.parse_args()
151

    
152
    if args.snort_conf:
153
        load_from_snort_conf(args.snort_conf, classmap, msgmap)
154

    
155
    if args.classification_path:
156
        classmap.load_from_file(
157
            open(os.path.expanduser(args.classification_path)))
158
    if args.genmsgmap_path:
159
        msgmap.load_generator_map(open(os.path.expanduser(args.genmsgmap_path)))
160
    if args.sidmsgmap_path:
161
        msgmap.load_signature_map(open(os.path.expanduser(args.sidmsgmap_path)))
162

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

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

    
173
    if args.directory and args.prefix:
174
        reader = unified2.SpoolEventReader(
175
            directory=args.directory,
176
            prefix=args.prefix,
177
            follow=args.follow,
178
            bookmark=args.bookmark)
179

    
180
        for event in reader:
181
            print_event(event, msgmap, classmap)
182

    
183
    elif args.filenames:
184
        reader = unified2.FileEventReader(*args.filenames)
185
        for event in reader:
186
            print_event(event, msgmap, classmap)
187

    
188
    else:
189
        parser.print_help()
190
        return 1
191

    
192
if __name__ == "__main__":
193
    sys.exit(main())
(3-3/5)