Skip to content
Snippets Groups Projects
Commit 5639d697 authored by Daniel Studený's avatar Daniel Studený
Browse files

Remake of TP taxonomy to IDEA category conversion, added new source/target...

Remake of TP taxonomy to IDEA category conversion, added new source/target protocol TP to IDEA (IANA) conversion and some other IDEA generation fixes.
parent 4273857c
No related branches found
No related tags found
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,6 +16,7 @@ import resource ...@@ -13,6 +16,7 @@ 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
...@@ -134,91 +138,251 @@ class Filer(object): ...@@ -134,91 +138,251 @@ 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_tax_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"]
},
}
tp_prot_to_idea = {
1: "appletalk",
2: "auth",
3: "bgp",
4: "cdp",
5: "clns",
6: "dhcp",
7: "domain",
8: "finger",
9: "ftp",
10: "hsrp",
11: "http",
12: "icmp",
13: "igmp",
14: "eigrp",
15: "ipv6",
16: "ipx",
17: "irc",
18: "isis",
19: "isakmp",
20: "ldap",
21: "mpls",
22: "ms-rpc",
23: "ms-sql",
24: "nat",
25: "netbios",
26: "nntp",
27: "ntp",
28: "oracle",
29: "ospf",
30: "pop-imap",
31: "sunrpc",
32: "qos",
33: "rip",
34: "sunrpc",
35: "smb",
36: "smtp",
37: "snmp",
38: "sql",
39: "ssh",
40: "ssl-tls",
41: "tacacs",
42: "tcp",
43: "telnet",
45: "udp",
46: "uucp",
48: "x11",
49: "tftp",
50: "ip",
51: "nfs",
52: "wins",
80: "h323",
81: "megaco",
82: "mgcp",
83: "sip",
84: "rtp",
99: "voip",
100: "aim",
101: "msn",
102: "yahoo",
103: "icq",
119: "im",
120: "musicmatch",
121: "winamp",
122: "shoutcast",
123: "windows",
124: "quicktime",
125: "rtsp",
149: "streaming",
150: "bittorrent",
151: "manolito",
152: "directconnect",
153: "earthstation5",
154: "p2p",
155: "fasttrack",
156: "gnutella",
157: "twister",
158: "winmx",
180: "p2p",
190: "scada-dnp3",
191: "scada-iccp",
192: "scada-iec",
193: "scada-modbus",
194: "scada-opc",
199: "scada",
254: "multi-protocol",
}
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_and_protocol(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_prot = 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_tax_to_idea[tp_cat_maj][tp_cat_min]
if pattern.search(tp_category): except KeyError:
return category category = ["Other"]
return None
try:
def gen_event_idea(self, timestamp, category, id_taxonomy, cve, examples_of_incident, proto, src_ip, src_port, protocol = IdeaGen.tp_prot_to_idea[tp_prot]
dest_ip, dest_port, conn_count, url, orig_data, incident_desription): except KeyError:
protocol = None
return { 'category': category, 'protocol': protocol }
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
''' '''
if (category == ["Other"]) and not self.other:
return None
event = { event = {
'Format': "IDEA0", 'Format': "IDEA0",
'ID': str(uuid4()), 'ID': str(uuid4()),
'DetectTime': time.strftime("%y-%m-%dT%H:%M:%S", time.localtime(timestamp)), 'DetectTime': datetime.utcfromtimestamp(timestamp / 1000).isoformat() + 'Z',
'Category': [category] + (["Test"] if self.test else []), 'Category': category + (["Test"] if self.test else [])
'Note': incident_desription,
'Ref': []
} }
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:
event['ConnCount'] = conn_count
source = {} source = {}
target = {} 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] if category and category == "Reputation":
if examples_of_incident: event['Source'].append(target)
event['Note'] += ", examples of event:" + examples_of_incident[6:] else:
event['Target'] = [target]
if orig_data: if orig_data:
event['Attach'] = {'Handle': "att1", event['Attach'] = [{
'Note': "original data", 'Type': ["OrigData"],
'Content': orig_data} 'Content': orig_data.strip()
}]
event['Node'] = [{ event['Node'] = [{
'Name': self.name, 'Name': self.name,
'Type': ["Connection", "Honeypot", "Recon"], 'Type': ["Datagram", "Content", "Protocol", "Signature", "Policy", "Heuristic"],
'SW': ["HP Tipping Point"], 'SW': ["TippingPoint_NX_NGIPS"]
}] }]
return event return event
...@@ -284,7 +448,7 @@ def daemonize( ...@@ -284,7 +448,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 +461,13 @@ def get_args(): ...@@ -297,7 +461,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 +537,43 @@ def process_data(line, filer, origdata, idea_gen): ...@@ -367,23 +537,43 @@ 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(",")
while re.search("^CVE-.*$", row[4]): ll_prot_str = [" ip:", " ipv6:", " udp:", " tcp:", "(ip)", "(ipv6)", "(udp)", "(tcp)", " ip ", " ipv6 ", " udp ", " tcp "]
row[3] += ", " + row[4]
del row[4] row = line.split("|")
examples_of_incident = []
while not re.search("(UDP|IP|ICMP|DNS|IP6)", row[5]): catprot = idea_gen.convert_category_and_protocol(category=row[1], id_taxonomy=int(row[2]))
examples_of_incident.append(row[5]) proto = []
del row[5] if not_empty(row[5]).lower() in ['ip', 'ip6', 'udp', 'tcp']:
examples_of_incident = " ".join(examples_of_incident) proto.append(row[5].lower())
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]): flt_proto = [pstr for pstr in ll_prot_str if(pstr in not_empty(row[4]).lower())]
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]), if flt_proto:
examples_of_incident=not_empty(examples_of_incident), proto=not_empty(row[5]), proto.append(flt_proto[0].translate(None, " ():v"))
if catprot['protocol']:
proto.append(catprot['protocol'])
if set(proto).intersection({"ip", "ip6"}):
try:
proto.remove("ip")
proto.remove("ip6")
except ValueError:
pass
if not "udp" in proto:
proto.append("tcp")
proto = list(set(proto))
timestamp = row[0].split(" ")[-1]
cve = [i for i in row[3].split(",") if i not in ("null", "")]
odata = "|".join([timestamp] + row[1:])
if catprot['category'] and not_empty(row[0][-14:-3]):
idea_event = idea_gen.gen_event_idea(timestamp=int(timestamp), category=catprot['category'], id_taxonomy=int(row[2]),
cve=cve, filter_name=not_empty(row[4]), proto=proto,
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 +615,7 @@ def main(): ...@@ -425,7 +615,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.
Finish editing this message first!
Please register or to comment