作者: bt0sea

0×00、前言

日志管理系统是信息安全发展过程中一直存在的业务系统,日志是安全的传感器,所以很有必要研究一下日志管理系统发展历史,以及以日志管理系统发展趋势。在文章的最后一段分享一下以前和一帮朋友做的日志管理系统。

0×01、商业日志管理系统发展历史

发展趋势

根据用户企业环境使用的产品以及各大厂商宣传的产品功能,大致可以推断出目前日志管理发展趋势。

日志分析管理软件解决方案(商业日志管理系统发展史)(1)

第一阶段:SIEM安全日志管理系统 (security information and event management)

1,针对第三方安全产品日志收集能力

日志管理系统做为安全的传感器,需要对任何第三方安全的产品的日志具备灵活的收集能力,某些厂商会开发定制化的收集器,并且公开定制工具。

第三阶段:安全大数据日志管理系统

1,提升APT发现能力,

通过大数据快速处理的能力,在短时间内通过关联分析发现企业内部威胁。

2,快速追溯威胁来源

成熟的商业产品

那么,市场上的玩家都有哪些?

Gartner发布了2015年度的SIEM市场分析报告

日志分析管理软件解决方案(商业日志管理系统发展史)(2)

1,IBM收购Q1 Lab

2, HP Arcsight

3,Splunk

4,RSA EnVersion

5,Symantec SSIM

6,Intel Security(MacAfee-Enterprise Log Manager)

Garnter发布了2014年度的全球MSS市场分析报告

日志分析管理软件解决方案(商业日志管理系统发展史)(3)

1,Dell – SecureWorks(IT综合服务提供商)

2,IBM-Fireeye Service/AT&T Service

3,Verizon(电信运营商)

4,Symantec(专业安全厂商)

大数据日志管理系统目前正处在崛起的阶段。目前各大互联网安全公司都在在这个领域下重金研发。

用户场景分析

在哪些场景会使用到日志管理系统呢?这要回归到基本安全管理问题:做为一家互联网公司的CSO,你怎么履行你的安全监控和管理职能?

1,简单使用一些开源工具,招聘一些有安全经验的运维人员做人工分析

Do Nothing –“Manual Analysis”

2,使用成熟的互联网安全商业软件 (传统厂商SEIM系统或者新兴互联网安全系统),少量的具备一般安全经验的运维人员熟练使用这些安全软件完成。SIEM

3,直接把安全外包给MSSP,由专业的公司分析安全威胁,只需要定期从MSSP厂商获得本公司 的安全报告。

国内大部分互联网公司,还是选择第二条路。

0×02、日志管理系统实践

产品架构设计

集中式部署

日志分析管理软件解决方案(商业日志管理系统发展史)(4)

如果被监管的设备不多而且相对集中,可以采用上图所示的集中式部署实现IT系统的安全信息监控。

分布式部署

日志分析管理软件解决方案(商业日志管理系统发展史)(5)

如果企业或组织内的IT架构比较复杂,而且监管的设备数目较多,可以采用上图所示的分布式部署方式。

支持的日志类型如下:

日志分析管理软件解决方案(商业日志管理系统发展史)(6)

GSGSoftInformation Security Management System

管理配置报表模块:ASP.net IIS MSSQL

日志收集系统:应用程序 MSSQL

日志分析管理软件解决方案(商业日志管理系统发展史)(7)

(1)GSGSoftManage 主要的功能 安全事件联动引擎

(2)GSGSoft Master Collection Agent 主动收集安全事件

(3)GSGSoft Slave Collection Agent 被动收集安全事件客户端(主要针对无法主动发送日志情况)

(4)Web Console 主要是安全事件的配置、告警和报表系统

(5)GSGSoft DataBase 安全事件存储数据库

GSGSoft Master Collection Agent功能设计

主动收集安全事件 对其标准化。针对Unix/Linux系统 建议用户打开系统syslog功能

通过syslog收集。

(1)Syslog Server 收集日志模块

(2)snmp trap 日志收集模块

(4)正则表达式查找匹配功能模块

(5)格式化原始事件为本系统识别事件模块

(6)本地存储结构模块

GSGSoft Slave Collection Agent 功能设计

被动收集安全事件客户端

(1)文件、文件夹日志收集模块

1.1 windows 日志收集模块system/security/applcation

1.2 IIS 日志收集模块

1.3 Apache 日志收集模块

(2)xml、csv文件收集模块

2.1 antivirus 扫描日志收集模块 (symantec 趋势 瑞星)

GSGSoft Web Console功能设计

主要是显示安全事件的平台,配置系统

(1)图形化报警功能

(2)灵活的SQL语句的构造系统,可产生多个自定义报表模块

(3)策略设置

GSGSoft Web Console详细设计

(1)图形化报警功能

在系统总览面板-图形化报警,功能设计:如果某个特定的区域发现符合报警条件的情况,则产生告警。并且相应的图形显示为红色扩散状的小球。

日志分析管理软件解决方案(商业日志管理系统发展史)(8)

系统默认用户为 admin ,密码为 123456 ,登录后建议管理员修改管理员密码。成功登录后,进入系统的主界面。如下图所示:

日志分析管理软件解决方案(商业日志管理系统发展史)(9)

当点击相应的红色小球,则显示具体的报警信息,如图:

日志分析管理软件解决方案(商业日志管理系统发展史)(10)

同时可以进入详细页面查看原始日志和标准化后的报警日志。

日志分析管理软件解决方案(商业日志管理系统发展史)(11)

查看完报警信息后小球的颜色恢复到原来的蓝色,证明报警信息被网管人员处理过。如图:

日志分析管理软件解决方案(商业日志管理系统发展史)(12)

图形化报警功能特别适合网管监控大屏幕显示,让安全事件发生源迅速形象的映入网管人员的视野。

报表功能

在安全报表中显示如图:

日志分析管理软件解决方案(商业日志管理系统发展史)(13)

设置安全报表查询条件,包括:开始结束时间、扫描条数、是否有图形显示、显示图形的X轴和Y轴。

日志分析管理软件解决方案(商业日志管理系统发展史)(14)

安全报表显示如图:

日志分析管理软件解决方案(商业日志管理系统发展史)(15)

策略设置功能

如何进行策略创建和分发

在“规则和策略”中左边的策略项中可点击正则表达式配置。

日志分析管理软件解决方案(商业日志管理系统发展史)(16)

点击其中的“对象”弹出如下:

日志分析管理软件解决方案(商业日志管理系统发展史)(17)

数据库设计

(1)系统登陆表GSGSoft_System

日志分析管理软件解决方案(商业日志管理系统发展史)(18)

(2)登陆日志GSGSoft_SiteLogin_log

日志分析管理软件解决方案(商业日志管理系统发展史)(19)

(3)Root 表Common Event Format

日志分析管理软件解决方案(商业日志管理系统发展史)(20)

日志分析管理软件解决方案(商业日志管理系统发展史)(21)

日志分析管理软件解决方案(商业日志管理系统发展史)(22)

GSGSoft服务器核心代码实现

编程工具:VC

平台:Windows

技术选型:IOCP架构 (Windows服务器要接收海量的日志一般技术架构是无法支持的)

IocpUdpInstance

IocpUdpInstance处理接收syslog UDP 54端口传输过来的日志数据。代码实现如下:

#include"stdafx.h"

#include"IocpUdpInstance.h"

//////////////////////////////////////////////////////////////////////

//Construction/Destruction

//////////////////////////////////////////////////////////////////////

CIocpUdpInstance::CIocpUdpInstance()

{

m_Port = 5353;

m_Inited = FALSE;

Lpbuf = m_buf;

m_BufLen = BUF_LEN;

m_FromLen = sizeof(SOCKADDR_IN);

}

CIocpUdpInstance::~CIocpUdpInstance()

{

Cleanup();

}

BOOLCIocpUdpInstance::Initialize()

{

if(LpParent == NULL) return FALSE;

if(m_Inited) return TRUE;

Lpbuf = m_buf;

m_BufLen= BUF_LEN;

SOCKET s = INVALID_SOCKET;

DWORD m_Result=0; int nRet=0;

//创建SOCKET并建立侦听

if(!m_Socket.CreateSocket(SOCK_DGRAM,IPPROTO_UDP,WSA_FLAG_OVERLAPPED))

goto EXIT;

if(!m_Socket.Bind(m_Port))

goto EXIT;

m_Inited = TRUE;

return TRUE;

EXIT:

Cleanup();

return FALSE;

}

BOOLCIocpUdpInstance::Doit()

{

if(LpParent == NULL ||!Initialize())

return FALSE;

//帮定到IO完成端口

SOCKET s = m_Socket;

if(!LpParent->Invoke(FN_IOCP_BIND,this,(HANDLE)s))

return FALSE;

RecvHandler(0);

return TRUE;

}

voidCIocpUdpInstance::Cleanup()

{

m_Inited = FALSE;

m_Socket.Cleanup();

}

voidCIocpUdpInstance::Release()

{

}

BOOLCIocpUdpInstance::SetValue(DWORD m_Code,...)

{

va_list vl,va_base;

va_start(vl,m_Code);

va_base = (va_list)&m_Code;

if(m_Code == BASE_VALIST)

{

vl = va_arg(vl,va_list);

va_base = vl;

m_Code =va_arg(vl,DWORD);

}

BOOL m_Resoult=TRUE;

switch(m_Code)

{

case IOCP_BUFFER:

{

Lpbuf = va_arg(vl,LPSTR);

m_BufLen=va_arg(vl,LONG);

break;

}

case SOCK_PORT:

{

m_Port=va_arg(vl,int);

break;

}

default:

{

m_Resoult=FALSE;

}

}

if(!m_Resoult)//子类没有处理则调用父类的

{

m_Resoult=CBase::SetValue(BASE_VALIST,va_base);

}

va_end(va_base);

va_end(vl);

return m_Resoult;

}

BOOLCIocpUdpInstance::GetValue(DWORD m_Code,...)

{

va_list vl,va_base;

va_start(vl,m_Code);

va_base = (va_list)&m_Code;

if(m_Code == BASE_VALIST)

{

vl = va_arg(vl,va_list);

va_base = vl;

m_Code =va_arg(vl,DWORD);

}

BOOL m_Resoult=TRUE;

switch(m_Code)

{

case IOCP_HANDLER:

{

LPWSAOVERLAPPEDLpolap = va_arg(vl,LPWSAOVERLAPPED);

CBase**LpBase = va_arg(vl,CBase**); *LpBase = NULL;

*LpBase =CONTAINING_RECORD(Lpolap, CIocpUdpInstance, m_olap);

break;

}

case BASE_OBJECT:

{

*(va_arg(vl,HANDLE*))=(HANDLE)(SOCKET)m_Socket;

break;

}

case SOCK_PORT:

{

*(va_arg(vl,int*))=m_Port;

break;

}

default:

{

m_Resoult=FALSE;

}

}

if(!m_Resoult)//子类没有处理则调用父类的

{

m_Resoult=CBase::GetValue(BASE_VALIST,va_base);

}

va_end(va_base); va_end(vl);

return m_Resoult;

}

DWORDCIocpUdpInstance::Invoke(DWORD m_Code,...)

{

va_list vl;

va_start(vl,m_Code);

DWORD m_Resoult = TRUE;

switch(m_Code)

{

case FN_IOCP_HANDLER:

{

DWORDm_szTrans = va_arg(vl,DWORD);

RecvHandler(m_szTrans);

break;

}

default:

{

m_Resoult=FALSE;

}

}

va_end(vl);

return m_Resoult;

}

BOOLCIocpUdpInstance::RecvHandler(DWORD m_szTrans)

{

if(m_szTrans > 0 &&LpContainer)

{

CBase *t_Tmp =LpContainer->Alloc();

if(t_Tmp)

{

t_Tmp->Initialize();

t_Tmp->SetValue(BASE_OBJECT,&m_Socket);

t_Tmp->SetValue(BASE_PARENT,(CBase*)this);

t_Tmp->SetValue(BASE_HANDLER,LpHandler);

if(!t_Tmp->Invoke(FN_INVOKE,Lpbuf, m_szTrans))

{

if(!t_Tmp->Recycle())t_Tmp->Release();

}

}

}

INITBUF(m_WBuf,Lpbuf,m_BufLen);

memset(&m_olap,0,sizeof(m_olap));m_FromLen=sizeof(SOCKADDR_IN);

int nRet =m_Socket.RecvEx(&m_WBuf,0,(sockaddr*)&m_SockAddr,&m_FromLen,&m_olap);

if(nRet==SOCKET_ERROR)

{

DWORD m_Result =WSAGetLastError();

if(m_Result !=ERROR_IO_PENDING)

{

returnFALSE;

}

}

return TRUE;

}

#include"StdAfx.h"

#include"IocpUdpHandler.h"

CIocpUdpHandler::CIocpUdpHandler(void)

{

hIocp = NULL;

m_Policy_p = NULL;

}

CIocpUdpHandler::~CIocpUdpHandler(void)

{

}

BOOLCIocpUdpHandler::Initialize()

{

if(LpParent == NULL)

return FALSE;

CBase *t_Base = NULL; hIocp = NULL;

LpParent->GetValue(BASE_PARENT,&t_Base);

if(t_Base) //CIocpBase

{

t_Base->GetValue(BASE_OBJECT,&hIocp);

// CAppInstance

if(t_Base->GetValue(BASE_PARENT,&t_Base) && t_Base)

{

t_Base->GetValue(BASE_OBJECT,OBJECT_POLICY, &m_Policy_p);

}

}

return (hIocp &&m_Policy_p);

}

voidCIocpUdpHandler::Cleanup()

{

m_Event.clear();

}

BOOLCIocpUdpHandler::GetValue(DWORD m_Code,...)

{

va_list vl,va_base;

va_start(vl,m_Code);

va_base = (va_list)&m_Code;

if(m_Code == BASE_VALIST)

{

vl = va_arg(vl,va_list);

va_base = vl;

m_Code =va_arg(vl,DWORD);

}

BOOL m_Resoult=TRUE;

switch(m_Code)

{

case BASE_CLASSTYPE:

{

*(va_arg(vl,DWORD*))=0x00000019;

break;

}

default:

{

m_Resoult=FALSE;

}

}

if(!m_Resoult)

{

m_Resoult=CBase::GetValue(BASE_VALIST,va_base);

}

va_end(va_base); va_end(vl);

return m_Resoult;

}

DWORDCIocpUdpHandler::Invoke(DWORD m_Code,...)

{

va_list vl;

va_start(vl, m_Code);

DWORD m_Resoult = TRUE;

switch(m_Code)

{

case FN_INVOKE:

{

m_Event = va_arg(vl, LPCSTR);

ULONG t_Size= va_arg(vl, ULONG);

m_Resoult =PostQueuedCompletionStatus(hIocp, t_Size, (ULONG_PTR)this, NULL);

break;

}

case FN_IOCP_HANDLER:

{

// returnFALSE 不能加 break;

if(m_Policy_p)

{

std::stringt_Event_o;

if(m_Policy_p->GetValue(BASE_AVAILABLE,&m_Event, &t_Event_o))

{

LpHandler->Invoke(ITEM_ADD,&t_Event_o);

}

}

}

default:

{

m_Resoult =FALSE;

}

}

va_end(vl);

return m_Resoult;

}

IocpUdpHandler

IocpUdpHandler处理接收过来的数据,实现代码如下:

#include"StdAfx.h"

#include"IocpUdpHandler.h"

CIocpUdpHandler::CIocpUdpHandler(void)

{

hIocp = NULL;

m_Policy_p = NULL;

}

CIocpUdpHandler::~CIocpUdpHandler(void)

{

}

BOOLCIocpUdpHandler::Initialize()

{

if(LpParent == NULL)

return FALSE;

CBase *t_Base = NULL; hIocp = NULL;

LpParent->GetValue(BASE_PARENT,&t_Base);

if(t_Base) //CIocpBase

{

t_Base->GetValue(BASE_OBJECT,&hIocp);

// CAppInstance

if(t_Base->GetValue(BASE_PARENT,&t_Base) && t_Base)

{

t_Base->GetValue(BASE_OBJECT,OBJECT_POLICY, &m_Policy_p);

}

}

return (hIocp &&m_Policy_p);

}

voidCIocpUdpHandler::Cleanup()

{

m_Event.clear();

}

BOOLCIocpUdpHandler::GetValue(DWORD m_Code,...)

{

va_list vl,va_base;

va_start(vl,m_Code);

va_base = (va_list)&m_Code;

if(m_Code == BASE_VALIST)

{

vl = va_arg(vl,va_list);

va_base = vl;

m_Code =va_arg(vl,DWORD);

}

BOOL m_Resoult=TRUE;

switch(m_Code)

{

case BASE_CLASSTYPE:

{

*(va_arg(vl,DWORD*))=0x00000019;

break;

}

default:

{

m_Resoult=FALSE;

}

}

if(!m_Resoult)

{

m_Resoult=CBase::GetValue(BASE_VALIST,va_base);

}

va_end(va_base); va_end(vl);

return m_Resoult;

}

DWORDCIocpUdpHandler::Invoke(DWORD m_Code,...)

{

va_list vl;

va_start(vl, m_Code);

DWORD m_Resoult = TRUE;

switch(m_Code)

{

case FN_INVOKE:

{

m_Event = va_arg(vl, LPCSTR);

ULONG t_Size= va_arg(vl, ULONG);

m_Resoult =PostQueuedCompletionStatus(hIocp, t_Size, (ULONG_PTR)this, NULL);

break;

}

case FN_IOCP_HANDLER:

{

// returnFALSE 不能加 break;

if(m_Policy_p)

{

std::stringt_Event_o;

if(m_Policy_p->GetValue(BASE_AVAILABLE,&m_Event, &t_Event_o))

{

LpHandler->Invoke(ITEM_ADD,&t_Event_o);

}

}

}

default:

{

m_Resoult =FALSE;

}

}

va_end(vl);

return m_Resoult;

}

Policys正则匹配

CPolicys::CPolicys(void)

{

m_EventHandler = NULL;

}

CPolicys::~CPolicys(void)

{

}

BOOLCPolicys::Initialize()

{

if(LpParent == NULL)

return FALSE;

std::string t_FileName, t_Tmp;

LpParent->GetValue(BASE_FILENAME,&t_FileName);

t_FileName = POLICY_NAME;

LpParent->GetValue(BASE_OBJECT,BASE_EVENT, &m_EventHandler);

HANDLE hFile =CreateFile(t_FileName.c_str(), GENERIC_READ,

FILE_SHARE_READ |FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if(hFile == INVALID_HANDLE_VALUE)

{

return FALSE;

}

ULONG t_Size = GetFileSize(hFile, NULL);

t_Tmp.resize(t_Size);

if(ReadFile(hFile,(LPSTR)t_Tmp.c_str(), t_Size, &t_Size, NULL))

{

m_Policys.clear();

CWorkSpace::XmlContextt_Context;

t_Context.m_Type = XML_WORK_GROUP;

t_Context.LpGroup = &m_Policys;

t_Context.LpMitem = NULL;

SplitXml(t_Tmp.c_str(),"

", "

", "

", XmlCallback, &t_Context);

}

CloseHandle(hFile);

return TRUE;

}

void WINAPICPolicys::XmlCallback(LPCSTR LpStr, size_t nLen, LPVOID m_Context)

{

if(LpStr == NULL || nLen == 0 ||m_Context == NULL)

return;

std::string t_Tmp;

CStringParse m_Parse;

m_Parse.SetBuffer(LpStr, nLen);

m_Parse.SetPartition(NULL,"\" ");

m_Parse.SetTrim('"');

m_Parse.Parse();

CPolicy t_Policy;

t_Tmp =m_Parse.GetValue("pid");

if(t_Tmp.empty())

return;

t_Policy.SetPolicyID(ATOUL(t_Tmp.c_str()));

t_Tmp =m_Parse.GetValue("eventid");

t_Policy.SetEventID(ATOUL(t_Tmp.c_str()));

t_Tmp =m_Parse.GetValue("name");

t_Policy.SetName(t_Tmp);

t_Tmp =m_Parse.GetValue("field");

t_Policy.SetFields(t_Tmp);

t_Tmp =m_Parse.GetValue("table");

t_Policy.SetTable(t_Tmp);

t_Tmp =m_Parse.GetValue("regexmatch");

t_Policy.SetRegexMatch(t_Tmp);

t_Tmp =m_Parse.GetValue("regexsplit");

t_Policy.SetRegexSplit(t_Tmp);

CWorkSpace::XmlContext *t_Ctx_p;

t_Ctx_p =(CWorkSpace::XmlContext*)m_Context;

POLICY *t_Policy_p =(POLICY*)t_Ctx_p->LpGroup;

if(t_Policy_p)

{

t_Policy_p->insert(POLICY_PAIR(t_Policy.GetPolicyID(),t_Policy));

}

}

BOOLCPolicys::GetValue(DWORD m_Code,...)

{

va_list vl,va_base;

va_start(vl,m_Code);

va_base = (va_list)&m_Code;

if(m_Code == BASE_VALIST)

{

vl = va_arg(vl,va_list);

va_base = vl;

m_Code =va_arg(vl,DWORD);

}

BOOL t_Resoult = TRUE;

switch(m_Code)

{

case BASE_AVAILABLE:

{

t_Resoult =FALSE;

std::string*t_Event_i, *t_Event_o;

t_Event_i =va_arg(vl,std::string*);

t_Event_o =va_arg(vl,std::string*);

if(t_Event_i== NULL || t_Event_o == NULL)

break;

t_Event_o->clear();

CLockSectiont_Lock(m_Section);

POLICY_ITERitra = m_Policys.begin();

for(; itra!= m_Policys.end(); itra )

{

std::stringt_Match, t_Split;

t_Match= itra->second.GetRegexMatch();

t_Split= itra->second.GetRegexSplit();

if(t_Match.empty()|| t_Split.empty())

{

continue;

}

//正则表达式是否匹配

boost::regexexpression(t_Match.c_str());

boost::cmatchwhat;

if(boost::regex_match(t_Event_i->c_str(),what, expression))

{

t_Lock.UnLock();t_Resoult = TRUE;

if(m_EventHandler&& g_App.GetViewEvent()) // 加入到显示队列

{

m_EventHandler->Invoke(ITEM_ADD,itra->second.GetEventID(), t_Event_i);

}

//用正则表达式进行解析

boost::regexe(t_Split.c_str());

FIELDl; FIELDITER itrb;

boost::regex_split(std::back_inserter(l),*t_Event_i, e);

for(itrb= l.begin(); itrb != l.end(); itrb )

{

if(!t_Event_o->empty())

{

*t_Event_o = ',';

}

*t_Event_o = '\"';

*t_Event_o = *itrb;

*t_Event_o = '\"';

}

break;

}

}

break;

}

default:

{

t_Resoult=FALSE;

}

}

if(!t_Resoult)//子类没有处理则调用父类的

{

t_Resoult =CBase::GetValue(BASE_VALIST,va_base);

}

va_end(va_base); va_end(vl);

return t_Resoult;

}

服务器端处理

(1)、首先通过解析DeviceIdentifier.xml,首先确定是否为支持的设备,支持的设备可以通过xml看出来。代码如下:

^\d\d\d\d-\d\d-\d\d\d\d\:\d\d\:\d\d \S \d \.\d \.\d \.\d \S \S \S \d \S \d \.\d \.\d \.\d \S \d \d \d $

2008-06-04 07:43:41W3SVC1846873709 10.1.3.3 GET /x.asp URL=http://www.google.cn 80 - 10.1.3.3Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)200 0 0

^<\d >.*?\:\%\w \-\d \-\w \: [\s|\S] $

<173>33:*Mar 1 04:53:37.494 UTC:%SYS-5-CONFIG_I: Configured from console by console (192.168.1.100)

^.*\S \sMSWinEventLog\s\d \s\w \s\d .*$

2009-08-15 17:12:47 Local7.Debug 127.0.0.1 vmMSWinEventLog 0 Security 5 Sat Aug 15 17:12:47 2009 592 Security AdministratorUser Success Audit VM 详细追踪 已经创建新的过程: 新的进程 ID: 1456 映像文件名:C:\WINDOWS\system32\cmd.exe 创建者进程 ID: 1280 用户名: Administrator 域: VM 登录 ID:(0x0,0x14FE2) 0

^<\d >.*SymantecServer \S :.*$

<54>三月 29 18:32:12 SymantecServer sepserver:DellXP708-33,检测到 [SID: 21590] P2P Edonkey PingMessage。 已允许来自此应用程序的通信: C:\ProgramFiles\Tencent\QQDownload2\QQDownload.exe,本地: 0.0.0.0,本地: 000000000000,远程: ,远程:129.47.150.11,远程: 000000000000,2,其他,Intrusion ID: 0,开始: 2009-03-29 17:35:17,结束: 2009-03-2917:35:17,出现次数: 1,应用程序: C:/Program Files/Tencent/QQDownload2/QQDownload.exe,位置: 默认值,用户: Administrator,域: WORKGROUP

^.*$

This is a testmessage

(2)第二步进入每个详细类型设备支持的正则。

Mapping/DeviceSupplier/DeviceProductName/DeviceVersion/FieldMapping.xml

日志分析管理软件解决方案(商业日志管理系统发展史)(23)

这里我就介绍一个最复杂的Symantec Endpoint Protection正则匹配,首先先解释一下xml文件。

<itempid="2" name="CISCO" p="" 设备类型<="" 数据库字段:devicegroup="">

subname="trans" // 数据库字段:DealDeviceGroup 日志类型 例如:流量日志

regexmatch="1\w*"// 正则校验式

regexsplit="^1(\d)(\d)(\d)(\w*)"// 正则表达式

table="event"// 存储事件表 不允许改

field="name,id,time"// 解析字段 需要编辑的内容:name,id,time

/>

详细可以解析的日志类型

^<\d >.*SymantecServer \S : 站点: .*?,服务器: .*,域: .*,管理员: .*,管理员登录成功.*$

^<\d >.*?SymantecServer \S : 站点: (.*?),服务器: (.*),域: (.*),管理员: (.*),(管理员登录成功).*$

CS1,DestinationName,DestinationDomainName,DestinationUserName,EventName

^<\d >.*?SymantecServer \S : 站点: .*?,服务器: .*,域: .*,管理员: .*,注销管理员.*$

^<\d >.*?SymantecServer \S : 站点: (.*?),服务器: (.*),域: (.*),管理员: (.*),(注销管理员).*$

CS1,DestinationName,DestinationDomainName,DestinationUserName,EventName

^<\d >.*?SymantecServer \S : 发现病毒,计算机名: .*,源: .*,风险名称: .*,出现次数: \d ,.*,.*,实际的操作: .*,请求的操作: .*,次要操作: .*,事件时间: .*,已插入: .*,结束: .*,域: .*,组: .*,服务器: .*,用户: .*,源计算机: .*,源 IP: .*$

^<\d >.*?SymantecServer \S : (发现病毒),计算机名: (.*),源: (.*),风险名称: (.*),出现次数: (\d ),(.*),.*,实际的操作: (.*),请求的操作: .*,次要操作: .*,事件时间: .*,已插入: .*,结束: .*,域: (.*),组: (.*),服务器: (.*),用户: (.*),源计算机: (.*),源 IP: (.*)$

EventName,Device_Name,CS6,CS2,CN1,FileName,DeviceAction,DestinationDomainName,CS4,CS1,SourceUserName,SourceName,SourceIP

^<\d >.*?SymantecServer \S : 发现安全风险,计算机名: .*,源: .*,风险名称: .*,出现次数: \d ,.*,.*,实际的操作: .*,请求的操作: .*,次要操作: .*,事件时间: .*,已插入: .*,结束: .*,域: .*,组: .*,服务器: .*,用户: .*,源计算机: .*,源 IP: .*$

^<\d >.*?SymantecServer\S : (发现安全风险),计算机名: (.*),源: (.*),风险名称: (.*),出现次数: (\d ),(.*),.*,实际的操作: (.*),请求的操作: .*,次要操作: .*,事件时间: .*,已插入: .*,结束: .*,域: (.*),组: (.*),服务器: (.*),用户: (.*),源计算机: (.*),源 IP: (.*)$

EventName,Device_Name,CS6,CS2,CN1,FileName,DeviceAction,DestinationDomainName,CS4,CS1,SourceUserName,SourceName,SourceIP

^<\d >.*?SymantecServer \S : 风险样例已提交至 Symantec,计算机名: .*,源: .*,风险名称: .*,出现次数: \d ,.*,.*,实际的操作: .*,请求的操作: .*,次要操作: .*,事件时间: .*,已插入: .*,结束: .*,域: .*,组: .*,服务器: .*,用户: .*,源计算机: .*,源 IP: .*$

^<\d >.*?SymantecServer \S : (风险样例已提交至 Symantec),计算机名: (.*),源: (.*),风险名称: (.*),出现次数: (\d ),(.*),.*,实际的操作: (.*),请求的操作: .*,次要操作: .*,事件时间: .*,已插入: .*,结束: .*,域: (.*),组: (.*),服务器: (.*),用户: (.*),源计算机: (.*),源 IP: (.*)$

EventName,Device_Name,CS6,CS2,CN1,FileName,DeviceAction,DestinationDomainName,CS4,CS1,SourceUserName,SourceName,SourceIP

^<\d >.*?SymantecServer \S : 站点: .*,服务器: .*,域: .*,客户端已成功下载策略,.*?,.*?,.*$

^<\d >.*?SymantecServer \S : 站点: (.*),服务器: (.*),域: (.*),(客户端已成功下载策略),(.*?),(.*?),(.*)$

CS1,DestinationName,DestinationDomainName,EventName,DeviceHostName,SourceUserName,SourceDomainName

^<\d >.*?SymantecServer \S : 站点: .*,服务器: .*,域: .*,客户端已成功下载内容软件包,.*?,.*?,.*$

^<\d >.*?SymantecServer \S : 站点: (.*),服务器: (.*),域: (.*),(客户端已成功下载内容软件包),(.*?),(.*?),(.*)$

CS1,DestinationName,DestinationDomainName,EventName,DeviceHostName,SourceUserName,SourceDomainName

^<\d >.*?SymantecServer\S : 站点: .*,服务器: .*,域: .*,客户端已重新与管理服务器连接,.*?,.*?,.*$

^<\d >.*?SymantecServer \S : 站点: (.*),服务器: (.*),域: (.*),(客户端已重新与管理服务器连接),(.*?),(.*?),(.*)$

CS1,DestinationName,DestinationDomainName,EventName,DeviceHostName,SourceUserName,SourceDomainName

^<\d >.*?SymantecServer \S : .*?,已通过主机完整性检查.*要求: .*,本地: .*,本地: .*,远程: .*,远程: .*,远程: .*开始: .*,结束: .*,出现次数: \d ,应用程序: .*,位置: .*,用户: .*,域: .*$

^<\d >.*?SymantecServer \S : (.*?),(已通过主机完整性检查).*要求: (.*),本地: (.*),本地: .*,远程: .*,远程: .*,远程: .*开始: .*,结束: .*,出现次数: (\d ),应用程序: (.*),位置: (.*),用户: (.*),域: (.*)$

DeviceName,EventName,message,SourceIP,CN1,FileName,CS2,SourceUserName,SourceDomainName

^<\d >.*?SymantecServer \S : .*?,检测到 .*\s 已禁止来自此应用程序的通信:.*,本地: .*,本地: .*,远程: .*,远程: .*,远程: .*,.*,.*,Intrusion ID: \d ,开始: .*,结束: .*,出现次数: .*,应用程序: .*,位置:.*,用户: .*,域: .*$

^<\d >.*?SymantecServer \S : (.*?),(检测到 .*)\s (已禁止来自此应用程序的通信): (.*),本地: (.*),本地: .*,远程: .*,远程: .*,远程: .*,.*,.*,Intrusion ID: (\d ),开始: .*,结束: .*,出现次数: .*,应用程序: .*,位置:(.*),用户: (.*),域: (.*)$

EventTime"field="DeviceName,message,EventName,fileName,SourceIP,CN2,CS2,SourceUserName,SourceDomainName

^<\d >.*?SymantecServer \S : .*?,检测到 .*\s 已允许来自此应用程序的通信:.*,本地: .*,本地: .*,远程: .*,远程: .*,远程: .*,.*,.*,Intrusion ID: \d ,开始: .*,结束: .*,出现次数: .*,应用程序: .*,位置:.*,用户: .*,域: .*$

^<\d >.*?SymantecServer \S : (.*?),(检测到 .*)\s (已允许来自此应用程序的通信): (.*),本地: (.*),本地: .*,远程: .*,远程: .*,远程: .*,.*,.*,Intrusion ID: (\d ),开始: .*,结束: .*,出现次数: .*,应用程序: .*,位置:(.*),用户: (.*),域: (.*)$

EventTime"field="DeviceName,message,EventName,fileName,SourceIP,CN2,CS2,SourceUserName,SourceDomainName

^<\d >.*?SymantecServer \S : 扫描 ID: .*,开始: .*,结束: .*,.*,时间长度 \(秒\): .*,用户 1: .*,用户 2: .*,.*,命令: .*,威胁: .*,受感染: .*,文件总数: .*,已省略: .*,计算机: .*,IP 地址: .*,域: .*,组: .*,服务器: .*$

^<\d >.*?SymantecServer \S : (扫描) ID: (.*),开始: .*,结束: .*,(.*),时间长度 \(秒\): (.*),用户 1: (.*),用户 2: .*,(.*),命令: (.*),威胁: (.*),受感染: (.*),文件总数: (.*),已省略: (.*),计算机: (.*),IP 地址: (.*),域: (.*),组: (.*),服务器: (.*)$

EventName,CN1,Device_EventType,CN2,SourceUserName,message,CS1,CN3,CN4,CN5,CN6,DeviceName,SourceIP,DestinationDomainName,CS4,DestinationName

^<\d >.*?SymantecServer\S : .*?,类别: .*,Smc,主机完整性检查已启用.*$

^<\d >.*?SymantecServer \S : (.*?),类别: (.*),(Smc),(主机完整性检查已启用).*$

DeviceName,DeviceEventID,CS1,EventName

^<\d >.*?SymantecServer \S : .*?,类别: .*,Symantec AntiVirus,已成功关闭 Symantec Endpoint Protection 服务.*$

^<\d >.*?SymantecServer \S : (.*?),类别: (.*),(Symantec AntiVirus),(已成功关闭 Symantec Endpoint Protection 服务).*$

DeviceName,DeviceEventID,Device_EventType,EventName

^<\d >.*?SymantecServer \S : .*?,类别: .*,Symantec AntiVirus,新的病毒定义文件已加载。版本: \S 。$

^<\d >.*?SymantecServer \S : (.*?),类别: (.*),(Symantec AntiVirus),(新的病毒定义文件已加载)。版本: (\S )。$

DeviceName,DeviceEventID,Device_EventType,EventName,CS6

^<\d >.*?SymantecServer \S : .*?,类别: .*,GUP,停止用作组更新提供程序.*$

^<\d >.*?SymantecServer \S : (.*?),类别: (.*),(GUP),(停止用作组更新提供程序.*)$

DeviceName,DeviceEventID,Device_EventType,EventName

^<\d >.*?SymantecServer \S : .*?,类别: .*,Smc,Symantec Management Client 已启动。.*$

^<\d >.*?SymantecServer \S : (.*?),类别: (.*),(Smc),(Symantec Management Client 已启动。).*$

DeviceName,DeviceEventID,Device_EventType,EventName

^<\d >.*?SymantecServer \S : .*?,类别: .*,Smc,位置 已更改为 默认值。.*$

^<\d >.*?SymantecServer \S : (.*?),类别: (.*),(Smc),(位置 已更改为 默认值。).*$

DeviceName,DeviceEventID,Device_EventType,EventName

^<\d >.*?SymantecServer \S : .*?,类别: .*,Smc,网络威胁防护 已激活.*$

^<\d >.*?SymantecServer \S : (.*?),类别: (.*),(Smc),(网络威胁防护 已激活).*$

DeviceName,DeviceEventID,Device_EventType,EventName

^<\d >.*?SymantecServer \S : .*?,类别: .*,Smc,网络威胁防护.*引擎版本: \S .*$

^<\d >.*?SymantecServer \S : (.*?),类别: (.*),(Smc),(网络威胁防护).*引擎版本: (\S ) (.*)$

DeviceName,DeviceEventID,Device_EventType,EventName,CS6,Message

^<\d >.*?SymantecServer \S : (.*?),(.*?),.*?,(.*?),开始: .*,结束: .*,规则: (.*),.*?,(.*?),\d ,(\S ),(.*?),用户: (.*),域: (.*)$

^<\d >.*?SymantecServer \S : (.*?),(.*?),.*?,(.*?),开始: .*,结束: .*,规则: (.*),.*?,(.*?),\d ,(\S ),(.*?),用户: (.*),域: (.*)$

DeviceHostName,DeviceAction,Device_EventType,EventName,FileName,CS2,CS3,SourceUserName,SourceDomainName

^.*$

^(.*)$

Message

name=`SEP Events`

0×03、结论

在产品化的路上,上面的产品Demo还远远没有达到第一阶段SIEM的要求,但是大致雏形已经具备。希望对大家有帮助。目前商业日志大数据方向的产品已经很多,如果大家有兴趣可以聊聊。

文章来源36大数据,www.36dsj.com ,微信号dashuju36 ,36大数据是一个专注大数据创业、大数据技术与分析、大数据商业与应用的网站。分享大数据的干货教程和大数据应用案例,提供大数据分析工具和资料下载,解决大数据产业链上的创业、技术、分析、商业、应用等问题,为大数据产业链上的公司和数据行业从业人员提供支持与服务。

End.

,