Skip to content
Snippets Groups Projects
Commit 7e182e44 authored by Pavel Eis's avatar Pavel Eis
Browse files

TippingPoint connector - remake of id_taxonomy conversion to IDEA. Also...

TippingPoint connector - remake of id_taxonomy conversion to IDEA. Also corrected some mistakes in IDEA conversion and done some refractoring.
parent 1d673a65
Branches
Tags
No related merge requests found
# python ./tpToIdea.py --origdata --oneshot -d /root/Dokumenty/PycharmProjects/TippingPoint/IdeaLogTest -n cz.cesnet.server.tippingpoint /root/Dokumenty/PycharmProjects/TippingPoint/tp-test-log.txt /root/Dokumenty/PycharmProjects/TippingPoint/tp-log2.txt --test #!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2018 Cesnet z.s.p.o
# Use of this source is governed by a 3-clause BSD-style license, see LICENSE file.
import json import json
from uuid import uuid4 from uuid import uuid4
...@@ -13,7 +16,9 @@ import resource ...@@ -13,7 +16,9 @@ import resource
import os.path as pth import os.path as pth
import atexit import atexit
import time import time
from datetime import datetime
import logging import logging
from collections import OrderedDict
class FileWatcher(object): class FileWatcher(object):
...@@ -134,92 +139,155 @@ class Filer(object): ...@@ -134,92 +139,155 @@ class Filer(object):
class IdeaGen(object): class IdeaGen(object):
idea_categories = {'Malware.Worm': re.compile("^Exploits: .*?Worm"),
'Attempt.Login': re.compile("SipVicious Brute Force"), tp_to_idea = {
'Attempt.Exploit': re.compile("^Exploits: .*?Attempt"), 1: {
'Other': re.compile("P2P"), 1: ["Attempt.Exploit"],
'Recon.Scanning': re.compile("^Reconnaissance"), 2: ["Attempt.Exploit"],
'Vulnerable.Open': re.compile("(^Vulnerabilities: [0-9]{5}|^Network Equipment: [0-9]{4} SNMP)"), 3: ["Attempt.Exploit"],
'Vulnerable.Config': re.compile("^Vulnerabilities: [0-9]{4} ICMP")} 4: ["Attempt.Exploit"],
anomaly_re = re.compile("(^Network Equipment: [0-9]{4} IP|^Traffic Normalization: [0-9]{4} (?!Tunneling))") 5: ["Attempt.Exploit"],
availability_ddos_re = re.compile("^Traffic Normalization: ") 6: ["Attempt.Exploit"],
255: ["Attempt.Exploit"]
def __init__(self, name, test=False): },
2: {
1: ["Malware.Worm"],
2: ["Malware.Virus"],
3: ["Malware.Trojan"],
4: ["Intrusion.Botnet"],
5: ["Fraud.Phishing"],
255: ["Malware"]
},
3: {
1: ["Availability.DDoS"],
2: ["Availability.DDoS"],
3: ["Availability.DDoS"],
255: ["Availability.DDoS"]
},
4: {
1: ["Other"],
2: ["Other"],
3: ["Other"],
4: ["Other"],
5: ["Other"],
6: ["Attempt.Login"],
7: ["Malware.Spyware"],
255: ["Other"]
},
5: {
1: ["Recon.Scanning"],
2: ["Attempt.Exploit"],
3: ["Attempt.Exploit"],
4: ["Recon.Scanning", "Attempt.Exploit"],
255: ["Attempt.Exploit"]
},
6: {
1: ["Anomaly.Protocol"],
2: ["Anomaly.Traffic"],
3: ["Anomaly.Application"],
255: ["Anomaly"]
},
7: {
1: ["Anomaly.Traffic"],
2: ["Anomaly.Application"],
255: ["Anomaly.Traffic"]
},
8: {
1: ["Other"],
2: ["Other"],
255: ["Other"]
},
}
def __init__(self, name, test=False, other=False):
self.name = name self.name = name
self.test = test self.test = test
self.other = other
def convert_category(self, category, incident, examples_of_incident): def convert_category(self, category, id_taxonomy):
''' '''
converts category from record to IDEA category converts category from record to IDEA category
:param category: TippingPoint category description :param category: TippingPoint category description
:param incident: TippingPoint incident description :param id_taxonomy: TippingPoint taxonomy id
:param examples_of_incident: some TippingPoing incident descriptions has examples
:return: if category or incident is empty or is not important for saving it return None, otherwise return :return: if category or incident is empty or is not important for saving it return None, otherwise return
converted category converted category
''' '''
if not (category and incident): if not (category and id_taxonomy):
return None return None
tp_category = category + ": " + incident tp_cat_maj = id_taxonomy >> 24
if IdeaGen.anomaly_re.search(tp_category) and not examples_of_incident: tp_cat_min = id_taxonomy >> 16 & 0b11111111
return "Anomaly.Traffic" tp_proto = id_taxonomy >> 8 & 0b11111111
if IdeaGen.availability_ddos_re.search(tp_category) and examples_of_incident: tp_platf = id_taxonomy & 0b11111111
return "Availability.DoS" try:
for category, pattern in IdeaGen.idea_categories.items(): category = IdeaGen.tp_to_idea[tp_cat_maj][tp_cat_min]
if pattern.search(tp_category): except KeyError:
return category category = ["Other"]
return None
return category
def gen_event_idea(self, timestamp, category, id_taxonomy, cve, examples_of_incident, proto, src_ip, src_port,
dest_ip, dest_port, conn_count, url, orig_data, incident_desription): def gen_event_idea(self, timestamp, category, id_taxonomy, cve, filter_name, proto, src_ip, src_port,
dest_ip, dest_port, conn_count, url, severity, orig_data):
''' '''
put every piece of record together into IDEA message put every piece of record together into IDEA message
:return: new IDEA message :return: new IDEA message
''' '''
event = {
'Format': "IDEA0", if (category == ["Other"]) and not self.other:
'ID': str(uuid4()), return None
'DetectTime': time.strftime("%y-%m-%dT%H:%M:%S", time.localtime(timestamp)),
'Category': [category] + (["Test"] if self.test else []), event = OrderedDict([
'Note': incident_desription, ("Format","IDEA0"),
'Ref': [] ("ID", str(uuid4())),
} ("DetectTime", datetime.fromtimestamp(timestamp / 1000).isoformat() + 'Z'),
("Category", category + (["Test"] if self.test else [])),
])
if cve: if cve:
event['Ref'].append("cve:"+cve) event['Ref'] = ['urn:cve:'.format(i) for i in cve]
if id_taxonomy: if conn_count and int(conn_count):
event['Ref'].append("tipping_point_taxonomy:%d" % int(id_taxonomy)) event['ConnCount'] = int(conn_count)
if conn_count: source = OrderedDict()
event['ConnCount'] = conn_count target = OrderedDict()
source = {}
target = {}
if src_ip: if src_ip:
# TippingPoint vSMS bugfix: Remove excessive spaces occasionally included inside the IPv6 address
src_ip = src_ip.replace(" ", "")
af = "IP4" if not ':' in src_ip else "IP6" af = "IP4" if not ':' in src_ip else "IP6"
source[af] = [src_ip] source[af] = [src_ip]
if src_port: if src_port and int(src_port):
source['Port'] = [src_port] source['Port'] = [int(src_port)]
if proto: if proto:
source['Proto'] = [proto] source['Proto'] = [proto]
if url: if dest_ip and (dest_ip != "0.0.0.0"):
source['url'] = url # TippingPoint vSMS bugfix: Remove excessive spaces occasionally included inside the IPv6 address
if dest_ip: dest_ip = dest_ip.replace(" ", "")
af = "IP4" if not ':' in dest_ip else "IP6" af = "IP4" if not ':' in dest_ip else "IP6"
target[af] = [dest_ip] target[af] = [dest_ip]
if dest_port: if dest_port and int(dest_port):
target['Port'] = [dest_port] target['Port'] = [int(dest_port)]
if proto:
target['Proto'] = [proto]
if url:
target['URL'] = url
if source: if source:
event['Source'] = [source] event['Source'] = [source]
if target: if target:
event['Target'] = [target] event['Target'] = [target]
if examples_of_incident:
event['Note'] += ", examples of event:" + examples_of_incident[6:]
if orig_data: if orig_data:
event['Attach'] = {'Handle': "att1", event['Attach'] = [OrderedDict([
'Note': "original data", ('Type', ["OrigData"]),
'Content': orig_data} ('Content', orig_data.strip())
event['Node'] = [{ ])]
'Name': self.name, event['Node'] = [OrderedDict([
'Type': ["Connection", "Honeypot", "Recon"], ('Name', self.name),
'SW': ["HP Tipping Point"], ('Type', ["Datagram", "Content", "Protocol", "Signature", "Policy", "Heuristic"]),
}] ('SW', ["TippingPoint_NX_NGIPS"])
])]
return event return event
...@@ -284,7 +352,7 @@ def daemonize( ...@@ -284,7 +352,7 @@ def daemonize(
def get_args(): def get_args():
optp = optparse.OptionParser( optp = optparse.OptionParser(
usage="usage: %prog [options] logfile ...", usage="usage: %prog [options] logfile ...",
description="Watch HP-Tipping_Point logfiles and generate Idea events into directory") description="Watch TippingPoint logfiles and generate Idea events into directory")
optp.add_option( optp.add_option(
"-n", "--name", "-n", "--name",
default=None, default=None,
...@@ -297,7 +365,13 @@ def get_args(): ...@@ -297,7 +365,13 @@ def get_args():
default=False, default=False,
dest="test", dest="test",
action="store_true", action="store_true",
help="Add Test category") help="Add \"Test\" category")
optp.add_option(
"--other",
default=False,
dest="other",
action="store_true",
help="Send events having \"Other\" category (usually nonmalicious)")
optp.add_option( optp.add_option(
"-o", "--oneshot", "-o", "--oneshot",
default=False, default=False,
...@@ -367,23 +441,19 @@ def process_data(line, filer, origdata, idea_gen): ...@@ -367,23 +441,19 @@ def process_data(line, filer, origdata, idea_gen):
:param idea_file: where output goes :param idea_file: where output goes
:param origdata: if true, write original record to IDEA message :param origdata: if true, write original record to IDEA message
''' '''
row = line.split(",") row = line.split("|")
while re.search("^CVE-.*$", row[4]): category = idea_gen.convert_category(category=row[1], id_taxonomy=int(row[2]))
row[3] += ", " + row[4] timestamp = row[0].split(" ")[-1]
del row[4] cve = [i for i in row[3].split(",") if i not in ("null", "")]
examples_of_incident = [] odata = "|".join([timestamp] + row[1:])
while not re.search("(UDP|IP|ICMP|DNS|IP6)", row[5]):
examples_of_incident.append(row[5])
del row[5]
examples_of_incident = " ".join(examples_of_incident)
category = idea_gen.convert_category(category=row[1], incident=row[4], examples_of_incident=examples_of_incident)
if category and not_empty(row[0][-14:-3]): if category and not_empty(row[0][-14:-3]):
idea_event = idea_gen.gen_event_idea(timestamp=int(row[0][-14:-3]), category=category, id_taxonomy=not_empty(row[2]), cve=not_empty(row[3]), idea_event = idea_gen.gen_event_idea(timestamp=int(timestamp), category=category, id_taxonomy=int(row[2]),
examples_of_incident=not_empty(examples_of_incident), proto=not_empty(row[5]), cve=cve, filter_name=not_empty(row[4]), proto=not_empty(row[5]),
src_ip=not_empty(row[6]), src_port=not_empty(row[7]), dest_ip=not_empty(row[8]), dest_port=not_empty(row[9]), src_ip=not_empty(row[6]), src_port=not_empty(row[7]), dest_ip=not_empty(row[8]), dest_port=not_empty(row[9]),
conn_count=not_empty(row[10]), url=not_empty(row[12]), conn_count=not_empty(row[10]), severity=not_empty(row[11]), url=not_empty(row[12]),
orig_data=str(line) if origdata else False, incident_desription=row[4]) orig_data=odata if origdata else False)
save_events(idea_event, filer) if idea_event:
save_events(idea_event, filer)
running_flag = True running_flag = True
...@@ -425,7 +495,7 @@ def main(): ...@@ -425,7 +495,7 @@ def main():
}) })
files = [FileWatcher(arg) for arg in args] files = [FileWatcher(arg) for arg in args]
filer = Filer(opts.dir) filer = Filer(opts.dir)
idea_gen = IdeaGen(opts.name, opts.test) idea_gen = IdeaGen(opts.name, opts.test, opts.other)
while running_flag: while running_flag:
for log_file in files: for log_file in files:
while True: while True:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment