OSSIM开源安全信息管理系统(十二)

本文详述了OSSIM系统中Framework模块的Listener.py文件,该文件主要处理来自传感器的请求,执行如日志分析、控制管理、资产管理和备份操作等功能。通过对不同命令的判断和处理,实现系统的安全运营。同时,讨论了日志记录的重要性和应包含的关键信息,强调了身份认证、系统变更、网络威胁、性能监控和业务连续性管理等方面的内容。
摘要由CSDN通过智能技术生成

2021SC@SDUSC




本周主要分析的内容为 Framework 模块中,Listener.py 文件。然后衔接上周内容,继续对 OSSIM 系统的日志分析部分进行简单分析。

1、Listener.py

在这个文件中,主要定义了两个类 FrameworkBaseRequestHandler 和 FrameworkBaseServer,分别实现的主要功能是对请求的数据包进行一些处理

同样先导入一些包

import re
import socket
import SocketServer
import sys
import threading
import json
from time import sleep

然后导入自己在其他文件中定义的

import Action
from DoControl import ControlManager
from DoASEC import ASECHandler
from DoWS import WSHandler
from DoNagios import NagiosManager
from BackupManager import BackupRestoreManager
from Logger import Logger
from OssimConf import OssimConf
from OssimDB import OssimDB
from DBConstantNames import *

接下来定义全局变量

logger = Logger.logger
controlmanager = None
asechandler = None
bkmanager = None

接下来就是具体的类代码部分

首先分析 FrameworkBaseRequestHandler

先是获取了请求的 IP 、端口、请求 ID 等基本信息

class FrameworkBaseRequestHandler(SocketServer.StreamRequestHandler):
    __nagiosmanager = None
    __conf = None
    __sensorID = ""

    def getRequestorIP(self):
        return self.client_address[0]

    def getRequestorPort(self):
        return self.client_address[1]

    def getRequestorID(self):
        return self.__id

def handle(self):

主要功能是对 sensor 发送的请求进行处理

def handle(self):
        global controlmanager
        global bkmanager
        global asechandler
        self.__id = None

        logger.debug("Request from: %s:%i" % (self.client_address))

接下来是一个 while 循环,其中有很多 if else 分支语句,主要就是对不同的请求进行不同的处理相应

通过调用函数 self.__check_sensor_ip() 实现对 ip 地址的检测,如果是当前主机 ip ,即 127.0.0.1,直接通过检测。函数 self.__check_sensor_ip() 的实现在下面的分析过程中讲解

        while 1:
            try:
                line = self.rfile.readline().rstrip('\n')
                if len(line) > 0 and not line.isspace():
                    command = line.split()[0]

                    #设置正常的默认响应
                    response = ""

                    #命令可用。请注意,只有“ping”对任何人开放。
                    #调用函数self.__check_sensor_ip()实现对ip地址的检测,如果是当前主机ip,即127.0.0.1,直接通过检测
                    if self.__check_sensor_ip(self.client_address[0]) or self.client_address[0] == '127.0.0.1':
                        if command == "ping":
                            response = "pong\n"

                        elif command == "control":
                            # spawn our control timer
                            #生成我们的控制计时器,如果为none,新生成一个
                            if controlmanager is None:
                                controlmanager = ControlManager(OssimConf())

                            response = controlmanager.process(self, command, line)

下面的就是一些仅有当前主机才可以请求的命令

#下面的仅有本主机可以
elif self.client_address[0] == '127.0.0.1':
	# Only control messages coming from localhost.
    #仅来自本地主机的控制消息。

    if command == "nagios":
    	if self.__nagiosmanager is None:
        	self.__nagiosmanager = NagiosManager(OssimConf())

        response = self.__nagiosmanager.process(line)

        elif command == "add_asset" or command == "remove_asset" or command == "refresh_asset_list":
            linebk = ""
            if controlmanager is None:
            	controlmanager = ControlManager(OssimConf())
            linebk = "action=\"refresh_asset_list\"\n"
            response = controlmanager.process(self, command, linebk)

        elif command == "backup":
            if bkmanager is None:
            	bkmanager = BackupRestoreManager(OssimConf())
            response = bkmanager.process(line)

        elif command == "asec":
            if asechandler is None:
            	asechandler = ASECHandler(OssimConf())
            response = asechandler.process_web(self, line)

        elif command == "asec_m":  # struct.unpack('!H',line[0:2])[0] == 0x1F1F:
            # it's a tlv
            if asechandler is None:
                asechandler = ASECHandler(OssimConf())
            response = asechandler.process(self, line)

        elif command == "ws":
            try:
                 [ws_data] = re.findall('ws_data=(.*)$', line)
                 ws_json = json.loads(ws_data)
                 logger.info("Received new WS: %s" % str(ws_json))
            except Exception, msg:
                 logger.warning("WS json is invalid: '%s'" % line)
        else:
            if ws_json['ws_id'] != '':
                 for ws_id in ws_json['ws_id'].split(','):
                      try:
                          ws_handler = WSHandler(OssimConf(), ws_id)
                      except Exception, msg:
                          logger.warning(msg)
            		  else:
                 		  response = ws_handler.process_json('insert', ws_json)
			else:
         		logger.warning("WS command does not contain a ws_id field: '%s'" % line)
        elif command == 'event':
            a = Action.Action(line)
            a.start()

	else:
        logger.info("Unrecognized command from source '%s': %s" % (self.client_address[0], command))
		return

接下来的 else 分值是不被允许的主机

else:
    logger.info("Dropped data from a disallowed source '%s': %s" % (self.client_address[0], command))
    return

#根据需要返回响应
if len(response) > 0:
    self.wfile.write(response)
line = ""

最后一部分是异常处理

except socket.error, e:
    logger.warning("Client disconnected...%s" % e)

except IndexError:
    logger.error("IndexError")
except Exception, e:
    logger.error("Unexpected exception in listener: %s" % str(e))
    import sys, traceback
    traceback.print_exc(file=sys.stdout)
    return

两个类属性设置的函数

def set_id(self, id):
    self.__id = id

def set_sensorID(self, uuid):
    self.__sensorID = uuid

两个获得类属性值的函数

def get_sensorID(self):
	return self.__sensorID
def get_id(self):
	return self.__id

__check_sensor_ip(addr)

刚才在上面的分析过程中,已经在 handle 函数中调用了这个方法

这个方法主要实现的功能就是检查请求是否来自准许的传感器

接收参数为 adrr,为具有 ip 地址和请求端口的元组

返回值为 true 或者 false,如果是来自于传感器,返回 true,否则返回 false

    @staticmethod
    def __check_sensor_ip(addr):        
        #连接数据库
        try:
            conf = OssimConf()
            myDB = OssimDB(conf[VAR_DB_HOST],
                           conf[VAR_DB_SCHEMA],
                           conf[VAR_DB_USER],
                           conf[VAR_DB_PASSWORD])
            myDB_connected = myDB.connect()
        except Exception, msg:
            # Cannot connect to database, return false.
            logger.warning("Cannot find registered sensors: %s" % str(msg))
            return False
        
        #从数据库中查询出id对应的ip
        query = 'select inet6_ntoa(sensor.ip) as ip from sensor, system where sensor.id=system.sensor_id;'
        result = myDB.exec_query(query)
        for r in result:
            if r['ip'] == addr:
                return True
        else:
            return False

后面还有一个 FrameworkBaseServer 类,继承自 SocketServer.ThreadingTCPServer ,实现的也比较简单,仅有两个函数,一个是构造函数,进行参数的简单初始化。另一个函数主要是调用 handle_request() 来进行一些处理。

由于比较简单,代码也很短,这里就不再详细阐述了。

最后一个类是 Listener 类,继承自 threading.Thread ,主要功能就是监听相应主机

class Listener(threading.Thread):
    def __init__(self):
        self.__conf = OssimConf()
        self.__server = None
        threading.Thread.__init__(self)

    def run(self):
        try:
            # Uncomment for SSL
            #            certfile='/var/ossim/ssl/local/cert_local.pem'
            #            keyfile='/var/ossim/ssl/local/key_local.pem'
            serverAddress = ("0.0.0.0", int(self.__conf[VAR_FRAMEWORK_PORT]))
            logger.info("Listen on: %s:%s" % serverAddress)
            sleep(3)

            # Uncomment for Non SSL
            self.__server = FrameworkBaseServer(serverAddress, FrameworkBaseRequestHandler)
            # Uncomment for SSL
            #            self.__server = FrameworkBaseServer(serverAddress, FrameworkBaseRequestHandler, certfile=certfile, keyfile=keyfile, conf=OssimConf())

            self.__server.serve_forever()
        except socket.error, e:
            logger.critical("Something wrong happend while binding the socket. %s" % str(e))
            sys.exit(-1)
        except Exception, e:
            logger.error("ERROR: %s" % str(e))
            sys.exit(-1)


2、日志记录内容

不同设备记录日志格式不同,那么什么样的日志才是有利于审计和有利于安全信息平台使用呢?目前国际上还没有统一的标准去衡量,但是通常来讲完整的日志应该包含如下信息:

  • Who:谁登录了。

  • What:他们在做什么,又发生了什么。

  • Where:发生在何处,在哪台主机,哪个文件系统上,或者哪个网络接口等等.

  • When:何时发生,应该包含开始时间和结束时间。

    为了得到更详细的内容,有时候还希望得到:为什么会发生( Why),如何发生(How),以及发生发展的趋势是什么,简单说就是5W1H。在网上找了一个图来大概描述一下,如下图所示。

在这里插入图片描述

有关安全运营的日志记录主要包含以下几个方面:

  1. 身份认证和授权。
  2. 系统变更管理(记录系统变更或组件变更等)。
  3. 网络威胁管理(由防火墙,IPS 设备产生)。
  4. 性能和容量管理(包括系统各种阈值,如CPU利用率、内存、网络带宽占用等)
  5. 业务的可持续性管理(系统开关机和冗余备份相关功能)。

本篇文章部分内容参考或转载自下列文章及书籍。侵权即删。

参考书籍:

  • 《开源安全运维平台OSSIM疑难解析(入门篇)》——李晨光著
  • 《开源安全运维平台OSSIM疑难解析(提高篇)》——李晨光著
  • 《开源安全运维平台:OSSIM最佳实践》——李晨光著

参考文章:

  • https://blog.51cto.com/chenguang/2426473
  • https://blog.csdn.net/lcgweb/article/details/101284949
  • https://blog.51cto.com/chenguang/1665012
  • https://www.cnblogs.com/lsdb/p/10000061.html
  • https://blog.51cto.com/chenguang/1691090
  • https://blog.51cto.com/chenguang/category10.html
  • https://blog.51cto.com/topic/ossim.html
  • https://blog.csdn.net/isinstance/article/details/53694361
  • https://blog.51cto.com/chenguang/1332329
  • https://www.cnblogs.com/airoot/p/8072727.html
  • https://blog.51cto.com/chenguang/1738731
  • https://blog.csdn.net/security_yj/article/details/120153992


上一篇:OSSIM开源安全信息管理系统(十一)
下一篇:

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌兮_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值