%PDF- %PDF-
| Direktori : /proc/self/root/backups/router/usr/local/lib/suricata/python/suricata/update/ |
| Current File : //proc/self/root/backups/router/usr/local/lib/suricata/python/suricata/update/maps.py |
# Copyright (C) 2017 Open Information Security Foundation
# Copyright (c) 2013 Jason Ish
#
# You can copy, redistribute or modify this Program under the terms of
# the GNU General Public License version 2 as published by the Free
# Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# version 2 along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Provide mappings from ID's to descriptions.
Includes mapping classes for event ID messages and classification
information.
"""
from __future__ import print_function
import re
class SignatureMap(object):
"""SignatureMap maps signature IDs to a signature info dict.
The signature map can be build up from classification.config,
gen-msg.map, and new and old-style sid-msg.map files.
The dict's in the map will have at a minimum the following
fields:
* gid *(int)*
* sid *(int)*
* msg *(string)*
* refs *(list of strings)*
Signatures loaded from a new style sid-msg.map file will also have
*rev*, *classification* and *priority* fields.
Example::
>>> from idstools import maps
>>> sigmap = maps.SignatureMap()
>>> sigmap.load_generator_map(open("tests/gen-msg.map"))
>>> sigmap.load_signature_map(open("tests/sid-msg-v2.map"))
>>> print(sigmap.get(1, 2495))
{'classification': 'misc-attack', 'rev': 8, 'priority': 0, 'gid': 1,
'sid': 2495,
'msg': 'GPL NETBIOS SMB DCEPRC ORPCThis request flood attempt',
'ref': ['bugtraq,8811', 'cve,2003-0813', 'nessus,12206',
'url,www.microsoft.com/technet/security/bulletin/MS04-011.mspx']}
"""
def __init__(self):
self.map = {}
def size(self):
return len(self.map)
def get(self, generator_id, signature_id):
"""Get signature info by generator_id and signature_id.
:param generator_id: The generator id of the signature to lookup.
:param signature_id: The signature id of the signature to lookup.
For convenience, if the generator_id is 3 and the signature is
not found, a second lookup will be done using a generator_id
of 1.
"""
key = (generator_id, signature_id)
sig = self.map.get(key)
if sig is None and generator_id == 3:
return self.get(1, signature_id)
return sig
def load_generator_map(self, fileobj):
"""Load the generator message map (gen-msg.map) from a
file-like object.
"""
for line in fileobj:
line = line.strip()
if not line or line.startswith("#"):
continue
gid, sid, msg = [part.strip() for part in line.split("||")]
entry = {
"gid": int(gid),
"sid": int(sid),
"msg": msg,
"refs": [],
}
self.map[(entry["gid"], entry["sid"])] = entry
def load_signature_map(self, fileobj, defaultgid=1):
"""Load signature message map (sid-msg.map) from a file-like
object.
"""
for line in fileobj:
line = line.strip()
if not line or line.startswith("#"):
continue
parts = [p.strip() for p in line.split("||")]
# If we have at least 6 parts, attempt to parse as a v2
# signature map file.
try:
entry = {
"gid": int(parts[0]),
"sid": int(parts[1]),
"rev": int(parts[2]),
"classification": parts[3],
"priority": int(parts[4]),
"msg": parts[5],
"ref": parts[6:],
}
except:
entry = {
"gid": defaultgid,
"sid": int(parts[0]),
"msg": parts[1],
"ref": parts[2:],
}
self.map[(entry["gid"], entry["sid"])] = entry
class ClassificationMap(object):
"""ClassificationMap maps classification IDs and names to a dict
object describing a classification.
:param fileobj: (Optional) A file like object to load
classifications from on initialization.
The classification dicts stored in the map have the following
fields:
* name *(string)*
* description *(string)*
* priority *(int)*
Example::
>>> from idstools import maps
>>> classmap = maps.ClassificationMap()
>>> classmap.load_from_file(open("tests/classification.config"))
>>> classmap.get(3)
{'priority': 2, 'name': 'bad-unknown', 'description': 'Potentially Bad Traffic'}
>>> classmap.get_by_name("bad-unknown")
{'priority': 2, 'name': 'bad-unknown', 'description': 'Potentially Bad Traffic'}
"""
def __init__(self, fileobj=None):
self.id_map = []
self.name_map = {}
if fileobj:
self.load_from_file(fileobj)
def size(self):
return len(self.id_map)
def add(self, classification):
"""Add a classification to the map."""
self.id_map.append(classification)
self.name_map[classification["name"]] = classification
def get(self, class_id):
"""Get a classification by ID.
:param class_id: The classification ID to get.
:returns: A dict describing the classification or None.
"""
if 0 < class_id <= len(self.id_map):
return self.id_map[class_id - 1]
else:
return None
def get_by_name(self, name):
"""Get a classification by name.
:param name: The name of the classification
:returns: A dict describing the classification or None.
"""
if name in self.name_map:
return self.name_map[name]
else:
return None
def load_from_file(self, fileobj):
"""Load classifications from a Snort style
classification.config file object.
"""
pattern = "config classification: ([^,]+),([^,]+),([^,]+)"
for line in fileobj:
m = re.match(pattern, line.strip())
if m:
self.add({
"name": m.group(1),
"description": m.group(2),
"priority": int(m.group(3))})