OSSIM-agent源代码分析(十)

2021SC@SDUSC

SessionParser.py
OSSIM-agent源代码分析(十)

简述

OSSIM Agent的主要职责是收集网络上存在的各种设备发送的所有数据,然后按照一种标准方式(standardized way)有序的发送给OSSIM Server,Agent收集到数据后在发送给Server之前要对这些数据进行标准化处理,这样Server就可以依一种统一的方式来处理这些信息,并且也简化了Server的处理过程。

Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在Session对象中。

作为使用cs模型的OSSIM,session的处理和控制就至关重要了

相关代码

初始导包

import re
from sets import Set
import sgmllib
import socket

SessionParser类

class SessionParser(sgmllib.SGMLParser):

解析给定字符串函数

def parse(self, s):
       
        self.feed(s)
        self.close()

初始化函数,将ip、端口、端口组等变量初始化

 def __init__(self, verbose=0):

        sgmllib.SGMLParser.__init__(self, verbose)
        self.starting_description = 0
        self.inside_table_element = 0
        self.inside_table_row = 0
        self.in_session = 0
        self.td_count = 0
        self.seen  = 0

        self.sessions = []
        self.session_num = 0

        self.queried_ip = ""

        self.dst_port_group = {}
        self.src_port_group = {}

        self.source_ip = ""
        self.source_port = ""
        self.dest_ip = ""
        self.dest_port = ""
        self.data_sent = 0
        self.data_rcvd = 0
        self.active_since = ""
        self.last_seen = ""
        self.duration = 0
        self.inactive = 0

时间处理函数,通过正则表达式,将只有秒,时分秒,日期时分秒分开处理

    def tosecs(self, data):

        
        if data.endswith('sec'):
            data = data.split(' ', 1)[0]

   
        elif data.__contains__('day'):
            result = re.findall('(\d+) days? (\S+)', data)
            (days, time) = result[0]
            seconds = int(days) * 86400

            dt = time.split(':')
            seconds += int(dt.pop())

            try:
                seconds += seconds + int(dt.pop()) * 60
                seconds += seconds + int(dt.pop()) * 3600

            except IndexError:
                pass
            data = str(seconds)

 
        else:
            dt = data.split(':')
            seconds = int(dt.pop())

            try:
                seconds += int(dt.pop()) * 60
                seconds += int(dt.pop()) * 3600

            except IndexError:
                pass
            data = str(seconds)

        return data

设置td开始函数

def start_td(self, attributes):
        self.td_count += 1
        self.inside_table_element = 1

设置td结束函数

    def end_td(self):
        self.inside_table_element = 0
        self.seen = 0

设置tr开始函数

    def start_tr(self, attributes):
        self.inside_table_row = 1

设置tr结束函数,同时如果session和ip都存在,则将将ip、端口等数据记录在tmp中,保存于日志中

    def end_tr(self):
        self.inside_table_row = 0
        self.td_count = 0

        if self.in_session and self.source_ip:
            self.session_num += 1
            tmp = "%s:%s --> %s:%s (%f %f) duration: %s" % (self.source_ip,self.source_port,self.dest_ip,self.dest_port, self.data_sent, self.data_rcvd, self.duration)
            self.sessions.append(tmp)

设置a开始函数,如果name为href且session存在则设置match

    def start_a(self, attributes):
        self.inside_table_row = 1
        for name, value in attributes:
            if name == "href" and self.in_session:
                matches = re.findall("\d+\.\d+\.\d+\.\d+",value)

                if len(matches) > 0:
                    if self.td_count is 1:
                        self.source_ip = matches[0]

                    elif self.td_count is 2:
                        self.dest_ip = matches[0]

数据设置函数,如果ip未设置,则通过matches,来补充ip设置

def handle_data(self, data):
        if self.queried_ip is "":
            matches = re.findall("(\d+\.\d+\.\d+\.\d+)",data)

            if len(matches) > 0:
                self.queried_ip = matches[0]

根据data的类型,设置对应的session标志

        if data.__contains__("Active TCP/UDP Sessions"):
            self.in_session = 1

        if data.__contains__("The color of the host"):
            self.sessions.append("NumSessions:%d" % int(self.session_num))
            self.in_session = 0
            source_sessions = 0
            dest_sessions = 0

通过sess,清洗session中的各个数据

 for sess in self.sessions:
                src_str = "^%s:.*" % self.queried_ip
                dst_str = "^\d+\.\d+\.\d+\.\d+:\S+\s+-->\s+%s:.*" % self.queried_ip
                src_sess = "^%s:\S+\s+-->\s+(\d+\.\d+\.\d+\.\d+):(\S+)" % self.queried_ip
                dst_sess = "^(\d+\.\d+\.\d+\.\d+):\S+\s+-->\s+%s:(\S+)" % self.queried_ip

根据session重新设置matches

  if re.findall(src_str, sess):
                    source_sessions += 1

                if re.findall(dst_str, sess):
                    dest_sessions += 1
                matches = re.findall(src_sess, sess)

再次根据matches,设置端口及端口组

 if len(matches) > 0:
                    if matches[0][1] in self.src_port_group:
                        self.src_port_group[matches[0][1]].add(matches[0][0])

                    else:
                        self.src_port_group[matches[0][1]] = Set()
                        self.src_port_group[matches[0][1]].add(matches[0][0])
                matches = re.findall(dst_sess, sess)

                if len(matches) > 0:
                    if matches[0][1] in self.dst_port_group:
                        self.dst_port_group[matches[0][1]].add(matches[0][0])

                    else:
                        self.dst_port_group[matches[0][1]] = Set()
                        self.dst_port_group[matches[0][1]].add(matches[0][0])

            self.sessions.append("SessionsAsSource:%s" % source_sessions)
            self.sessions.append("SessionsAsDest:%s" % dest_sessions)

根据端口,添加session的数据

      for port in self.src_port_group:
                self.sessions.append("UniqPort%sAsSourceSessions:%d" % (port, len(self.src_port_group[port])))

            for port in self.dst_port_group:
                self.sessions.append("UniqPort%sAsDestSessions:%d" % (port, len(self.dst_port_group[port])))

处理相关的端口和端口组的流量,并记录其对应的时间

        if self.inside_table_element and self.in_session:
            if self.td_count <= 2:
                matches = re.findall(":(\w+)",data)

                if len(matches) > 0:
                    try:
                        port = socket.getservbyname(matches[0])

                    except:
                        port = matches[0]

                    if self.td_count is 1:
                        self.source_port = port

                    elif self.td_count is 2:
                        self.dest_port = port

            elif self.td_count is 3:
                if self.seen == 0:
                    self.data_sent = float(data)
                    self.seen = 1

                else:
                    if data.__contains__("KB"):
                        self.data_sent *= 1024

                    elif data.__contains__("MB"):
                        self.data_sent *= 1024 * 1024

                    elif data.__contains__("GB"):
                        self.data_sent *= 1024 * 1024 * 1024

                    self.seen = 0

            elif self.td_count is 4:
                if self.seen == 0:
                    self.data_rcvd = float(data)
                    self.seen = 1

                else:
                    if data.__contains__("KB"):
                        self.data_rcvd *= 1024

                    elif data.__contains__("MB"):
                        self.data_rcvd *= 1024 * 1024

                    elif data.__contains__("GB"):
                        self.data_rcvd *= 1024 * 1024 * 1024

                    self.seen = 0

            elif self.td_count is 5:
                self.active_since = data

            elif self.td_count is 6:
                self.last_seen = data

            elif self.td_count is 7:
                self.duration = self.tosecs(data)

            elif self.td_count is 8:
                self.inactive = self.tosecs(data)

获取session函数

    def get_sessions(self):
        return self.sessions
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值