从海量安全事件中挖掘有用的威胁信息与情报是当今讨论的热门话题,同时这也是一个难点?怎么实现呢?这里用到一种技术叫做关联分析,他也是SIEMSecurity? Information Event Management安全信息和事件管理)系统中最常见的事件检测手段,这并不是什么新鲜事物,20年前就已经有人提出来了。通常基于时序来对相同数据源或来自不同数据源的安全事件,使用关联规则来进行综合的关联分析,下面介绍关联分析的具体功能。

??? 通常来说,一次恶意Gong JI会在多个安全设备或应用程序(如网络防火墙,交换机,Web 应用日志,SQL 日志,审核日志等)中留下痕迹. 然而,所有这些信息都是孤立隔绝的,被保存在不同的设备日志中,如果利用了关联分析技术就可以快速定位故障。

关联分析为什么有如此神通广大呢?其实后台有很多复杂的关联规则最为基础的,这些检测规则可以识别?A t t a c k?事件,实际上这些规则是人工在大量实践中总结出来生成对Gong JI事件的一种语言描述,并对其进行了精确分类,分类越细描述越准确,识别率就越高。

Tips:?下文中“Gong Ji”“**”代表铭感词汇,你懂得。

?

一、关联分析核心思想

关联分析技术的核心思想是通过对某一类事件进行训练建立行为基线,基线范围外的事件视为异常事件来进行分类. 该算法较适合于本文检测场景,通常 SIEM 系统中绝大多数的日志为正常事件,通过对正常事件训练建模,来检测异常或Gong JI事件,这就是理论上说的One-Class SVM(单类支持向量机)。OSSIM系统中需要更多维度特征向量,才能准确判断Gong JI源,避免检测精度低或过拟合情况. 算法输入是经过 OSSIM 归一化后具备相同数据结构的安全事件,输出则为带有标记的安全事件,标记分为两类:正常(Negative)Gong JI(Positive) OSSIM关联分析引擎的输出就是 One-Class SVM分类算法输出的带标记的正常与Gong JI事件。

通过深入分析 SIEM 系统的关联规则,其中最常见的配置字段如:event_idtimestampplugin_idplugin_sidsrc_ipsrc_portdes_ipdes_portprotocol 等。 为了使关联分析规则不依赖于传感器配置,本文从 OSSIM 的规则库中抽取了几个重要的字段 plugin_id_nameplu-gin_id_descriptionsid_name,并将所有字段拆分成关键词标签,然后针对每一条检测规则生成其关键词标签统计模型,利用规则统计模型来代替原始的规则来检测Gong JI

关联分析的核心通过一个或一组关联指令来完成,下面用SSH**破解的例子加以说明,如图1所示,SSH**破解(Brute Force)大约自UNIX诞生之后,就衍生出来的一种Gong JI行为,据统计发现大约有50%以上的用户名是root。一个低可靠性(low reliability)的SSH 服务器,在经过100登录尝试之后成功登录,而高可靠性(high reliability)的SSH服务器,则经过10000次登录才成功,那么关联引擎可通过在一定时间内,登录的次数,以及这些时间的不同源地址和相同目标IP地址,以及这些IP地址来自于那些国家,它们信誉度如何等信息来综合判定Gong JI以及作出响应。

10 数据源分类

Ossim的关联引擎运行之前,必须为所有已知的Gong JI场景建立对应的树形指令(在开源系统中提供了84条,在OSSIM 4.15的商业版本提供了1800余条,OSSIM USM 5.x提供2100+条),这也是它的核心价值的体现,在OSSIM启动时,系统会将所有预先定义好的指令读入内存,在接收到一个directive_event后,先将该事件与之前已经匹配,而还没有匹配完的指令中的规则匹配,然后再与其它指令的规则匹配。注意一个事件可以与很多指令中的规则匹配。


五、 完善规则


OSSIM系统中的关联规则生成主要通过安全专家人工编写,这种方式效率低下,且人工成本难以承受. 对于新出现的Gong JI和漏洞无法及时作出响应,检测规则的编写往往出现滞后的情况, 大家也许会考虑能否利用AI技术和数据融合技术进行智能化的数据挖掘呢,这些刚高级的黑科技在实际应用中往往生成的关联规则检测精度较低,检测结果不理想,实际应用效果有限。利用人工神经网络来自动生成关联规则,是关联分析研究领域今后发展的方向。

对于新手而言从一张白纸开始写规则有些难了,但是对照系统给出的默认规则,照葫芦画瓢还是可以实现的,不管这个模型是否完善,先用起来,然后逐步修改。在合适的时间,对自己进行***,然后监控SIEM的反应,观察它是否产生正确的警报,而警报是否提供足够的信息来协助相应这弄清楚发生了什么威胁,如果没有那就需要修改规则,然后你需要不断的优化阈值,你是否发现SIEM报警过于频繁,或者非常稀少,你需要调节阈值来解决,顺便说一句,面对动态的网络Gong JI,这个调节的过程没有终点如果读者在学习关联规则的过程中遇到各种问题也可以参考我的新书《开源安全运维平台OSSIM疑难解析:提高篇》。

?

?

?附件:

下面分享的是OSSIM关联分析的一部分源代码。

/*
**?*?该指令是否与根节点指令匹配,这里只检查根节点,并不检查指令的子节点**
?*/gboolean
sim_directive_match_by_event?(SimDirective??*directive,
??????????????????????????????????????????????????????SimEvent??????*event)
{
??SimRule?*rule;
??gboolean?match;

??g_return_val_if_fail?(directive,?FALSE);
??g_return_val_if_fail?(SIM_IS_DIRECTIVE?(directive),?FALSE);
??g_return_val_if_fail?(!directive->_priv->matched,?FALSE);
??g_return_val_if_fail?(directive->_priv->rule_root,?FALSE);
??g_return_val_if_fail?(directive->_priv->rule_root->data,?FALSE);
??g_return_val_if_fail?(SIM_IS_RULE?(directive->_priv->rule_root->data),?FALSE);
??g_return_val_if_fail?(event,?FALSE);
??g_return_val_if_fail?(SIM_IS_EVENT?(event),?FALSE);

??rule?=?SIM_RULE?(directive->_priv->rule_root->data);

??match?=?sim_rule_match_by_event?(rule,?event);?

??return?match;
}/*
**?*这将检查事件是否可以与backlog中的某些数据匹配。backlog实际上是一个包含事件数据的指令。每个backlog条目都是一个树,其中包含来自一个指令的所有规则(它相当于是一个指令克隆)。其中每个规则(simrule)还包含与规则匹配的事件的数据。**
?*?
?*/gboolean
sim_directive_backlog_match_by_event?(SimDirective??*directive,
??????????????????????????????????????????????????????????????????????SimEvent????*event)
{
??GNode??????*node?=?NULL;

??g_return_val_if_fail?(directive,?FALSE);
??g_return_val_if_fail?(SIM_IS_DIRECTIVE?(directive),?FALSE);
??g_return_val_if_fail?(!directive->_priv->matched,?FALSE);
??g_return_val_if_fail?(directive->_priv->rule_curr,?FALSE);
??g_return_val_if_fail?(directive->_priv->rule_curr->data,?FALSE);
??g_return_val_if_fail?(SIM_IS_RULE?(directive->_priv->rule_curr->data),?FALSE);
??g_return_val_if_fail?(event,?FALSE);
??g_return_val_if_fail?(SIM_IS_EVENT?(event),?FALSE);

??node?=?directive->_priv->rule_curr->children;??while?(node)??????//**我们必须对照backlog中的所有规则节点检查事件,除了根节点,因为它签入了sim_directive_match_by_event是从sim_organizer_correlation调用的.**
??{
????SimRule?*rule?=?(SimRule?*)?node->data;????if?(sim_rule_match_by_event?(rule,?event))
????????{
????????????g_log?(G_LOG_DOMAIN,?G_LOG_LEVEL_DEBUG,?"sim_directive_backlog_match_by_event;?sim_rule_match_by_event:?True");
??????????time_t?time_last?=?time?(NULL);
????????????directive->_priv->rule_curr?=?node;?????//?每次事件匹配时,该指令都下一级到匹配的节点。下次将根据此级别检查事件。

????????????????????????????????????????????????????????????????????????????????????????//FIXME:?父节点中可能存在内存泄漏.
??????????directive->_priv->time_last?=?time_last;
??????????directive->_priv->time_out?=?sim_directive_get_rule_curr_time_out_max?(directive);

????????????sim_rule_set_event_data?(rule,?event);??????//这里我们将事件中的各个字段分配到规则中,所以每次我们进入规则时,我们可以看到匹配的事件.

??????????sim_rule_set_time_last?(rule,?time_last);??????????if?(!G_NODE_IS_LEAF?(node))
????????{
??????????GNode?*children?=?node->children;??????????while?(children)
????????????????{
??????????????????SimRule?*rule_child?=?(SimRule?*)?children->data;

??????????????????sim_rule_set_time_last?(rule_child,?time_last);

??????????????????sim_directive_set_rule_vars?(directive,?children);
??????????????????children?=?children->next;
????????????????????g_log?(G_LOG_DOMAIN,?G_LOG_LEVEL_DEBUG,?"sim_directive_backlog_match_by_event:?There?are?childrens?in?%d?directive",?directive->_priv->id);
????????????????}
????????????}??????????else
??????????{
??????????????directive->_priv->matched?=?TRUE;
????????????????g_log?(G_LOG_DOMAIN,?G_LOG_LEVEL_DEBUG,?"sim_directive_backlog_match_by_event:?The?directive?%d?has?matched",?directive->_priv->id);
??????????}??????????return?TRUE;
????????}????????else
????????{
????????????g_log?(G_LOG_DOMAIN,?G_LOG_LEVEL_DEBUG,?"sim_directive_backlog_match_by_event:?sim_rule_match_by_event:?False");
????????}

??????node?=?node->next;
????}??return?FALSE;
}/*
?*?检查指令中的所有节点规则,以查看.......
?*/gboolean
sim_directive_backlog_match_by_not?(SimDirective??*directive)
{
??GNode??????*node?=?NULL;
??GNode??????*children?=?NULL;

??g_return_val_if_fail?(directive,?FALSE);
??g_return_val_if_fail?(SIM_IS_DIRECTIVE?(directive),?FALSE);
??g_return_val_if_fail?(!directive->_priv->matched,?FALSE);
??g_return_val_if_fail?(directive->_priv->rule_curr,?FALSE);
??g_return_val_if_fail?(directive->_priv->rule_curr->data,?FALSE);
??g_return_val_if_fail?(SIM_IS_RULE?(directive->_priv->rule_curr->data),?FALSE);

??node?=?directive->_priv->rule_curr->children;??while?(node)?
??{
????SimRule?*rule?=?(SimRule?*)?node->data;????????//如果规则已超时?&&???????
????if?((sim_rule_is_time_out?(rule))?&&?(sim_rule_get_not?(rule))?&&?(!sim_rule_is_not_invalid?(rule)))?
????????{
??????????time_t?time_last?=?time?(NULL);
????????directive->_priv->rule_curr?=?node;
??????????directive->_priv->time_last?=?time_last;
??????????directive->_priv->time_out?=?sim_directive_get_rule_curr_time_out_max?(directive);

????????sim_rule_set_not_data?(rule);??????????if?(!G_NODE_IS_LEAF?(node))?//这不是最后的节点,他还有一些子节点.
????????{
??????????children?=?node->children;??????????while?(children)
????????????????{
????????????????SimRule?*rule_child?=?(SimRule?*)?children->data;

??????????????????sim_rule_set_time_last?(rule_child,?time_last);

??????????????????sim_directive_set_rule_vars?(directive,?children);
??????????????????children?=?children->next;
????????????????}
????????}????????else?//last?node!
????????{
??????????directive->_priv->matched?=?TRUE;
????????}????????return?TRUE;
????????}
????node?=?node->next;
??}??return?FALSE;
}/*
?*?backlog&directives几乎是相同的:backlog是存储指令并填充事件数据的地方。
?*“node”是子节点函数。我们需要从引用其级别的节点向该节点添加src_ip、port等。如果“node”参数是根节点->子节点1->子节点2中的children2,并且我们在children2中有1:plugin-sid,那么我们必须将根节点中的plugin-sid添加到children2中。
?*/void
sim_directive_set_rule_vars?(SimDirective?????*directive,
?????????????????????????????????????????????????????GNode????????????*node)
{
??SimRule????*rule;
??SimRule????*rule_up;
??GNode??????*node_up;
??GList??????*vars;
??GInetAddr??*ia;
??GInetAddr??*sensor;
??gint????????port;
??gint????????sid;
??SimProtocolType??protocol;
????gchar???????????????*aux?=?NULL;

??g_return_if_fail?(directive);
??g_return_if_fail?(SIM_IS_DIRECTIVE?(directive));
??g_return_if_fail?(node);
??g_return_if_fail?(g_node_depth?(node)?>?1);

??rule?=?(SimRule?*)?node->data;
??vars?=?sim_rule_get_vars?(rule);

?

?2019 最 新 作 品

?

?

?

?

?

?