Snort分析

Snort拥有三大基本功能:嗅探器、数据包记录器和入侵检测。嗅探器模式仅从网络上读取数据包并作为连续不断的流显示在终端上,数据包记录器模式是把数据包记录到硬盘上,网络入侵检测模式是最复杂的,而且是可配置的。我们可以让Snort分析网络数据流以匹配用户定义的一些规则,并根据检测结果采取一定的动作。

从本质上说,Snort与tcpdump和snoop一样,都是网络数据包嗅探器。因此,嗅探器模式是Snort工作的基本模式。只要运行Snort时不加载规则,它就可以从网络上读取数据包并连续不断地显示在屏幕上,直到用户按下Ctrl+C键终止。这时,Snort将显示统计信息。Snort使用Libpcap网络驱动库。在这种模式下,Snort将网卡设置为混在模式,读取并解析共享信道中的网络数据包。在嗅探模式下,Snort也可以将这些信息记录到日志文件中。这些文件随后可以用Snort或者tcpdump查看。入侵模式需要载入规则库才能工作。在入侵模式下,Snort并不记录所有捕获的包,而是将包与规则对比,仅当包与某个规则匹配的时候,才会记录日志或产生报警。如果包并不与任何一个规则匹配,那么它将会被悄悄丢弃,并不做任何记录。运行Snort的入侵检测模式的时候,通常会在命令行指定一个配置文件。

  • 工作流程

  • 包括包捕获模块、包解码模块、预处理模块、检测模块(模式匹配)、输出模块等

分析过程

由snort.c 文件中的OpenPcap函数实现捕包过程(实现的功能实现到libpcap库流程的循环抓包前为止)

  • 在ProcessPacket()中会对所选模式进行判断,并进行相应操作:

  • 若选择【嗅探模式】,则会调用下面的函数,然后进行输出,不会进行以下的步骤
if(pv.verbose_flag)
{
/*根据协议,调用相应输出函数,共支持4种协议*/
 if(p.iph!=NULL)/*IP协议*/
    PrintIPPkt(stdout,p.iph->ip_proto,&p);
   else if(p.ah!=NULL)/*Eapol协议*/
           PrintArpHeader(stdout,&p);
        else if(p.elph!=NULL)/*ARP协议*/
                PrintEapolPkt(stdout,&p);
               else if(p.wifih&&pv.showwifimgmt_flag)/*WiFi协议*/
                PrintWiFiPkt(stdout,&p);
}

  • 若选择【日志记录模式】,则会调用相应插件,进行日志记录,CallLogPlugins函数的主要功能是遍历LogList的所有注册函数,实现日志输出。
void CallLogPlugins(Packet *p,char *message,void *args,Event *event)
{
 OutputFuncNode *idx;
 idx=LogList;/*指向日志输出插线链表首节点*/
 if(p!=NULL)
  {
    if(pv.obfuscation_flag)
      ObfuscatePacket(p);
   }
 pc.log_pkts++;
/*遍历链表中注册的所有功能函数*/
 while(idx!=NULL)
  {
    idx->func(p,message,idx->arg,event);
    idx=idx->next;
  }
  return;
}

  • 若选择【入侵检测模式】,调用函数Preprocess,进行数据检测和处理。对当前数据包按照一定的顺序,分别应用规则列表,根据给定的各种规则和当时所截获的数据包分析结果,作出是否发生入侵行为的判断。如果当前数据包符合某条检测规则所指定的情况,则系统可以根据这条规则所定义的响应方式以及输出模块的初始化定义情况,选择进行各种方式的日志记录和报警操作。
int Preprocess(Packet *p)
{
 PreprocessFunNode *idx;
 int retval=0;
 if(p->csum_flags)
    return 0;
	
 /*是否打开引擎*/
 do_detect=1;
 /*指向预处理插件的顶层链表
 idx=PreprocessList;
 
 /*重置适当的应用层协议字段*/
 p->uri_count=0;
 UriBufs[0].decode_flags=0;
 
 /*打开所有预处理器*/
 p->preprocessors=PP_ALL;
 
 /*遍历预处理插件,对数据包进行处理*/
 
 while(idx!=NULL)
 {
  assert(idx->func!=NULL);
  idx->func(p);
  idx=idx->next; 
 }
 
 if(do_detect)
   Detect(p);
   
 retval=SnortEventqLog(p);
 SnortEventqReset();
   
 otn_tmp=NULL;
 
 if(retval&&p->ssnptr)
   AlertFlushStream(p);
   
 CheckFlowShutdown(p);
 return retval;  
}
  • 在Preprocess函数中,调用Detect函数进入实际的数据包检测,Detect函数会调用fpEvalPacket函数进入多模式匹配引擎‘判断待检测的数据包时TCP、UDP、ICMP还是IP包,然后调用相应的fpEvalHeaderXXX检测函数。

此处以TCP包为例,讲调用fpEvalHeaderTCP函数,将该数据包与规则子集合和进行匹配:
1.首先调用prmFindRuleGroupTcp函数获取适合当前规则的子集合;
2.然后掉哦那个InitMatchInfo函数进行优化
3.此后调用fpEvalHeaderSW进入多模式搜索匹配引擎,对数据包中的三类节点(包含content,包含uricontent,不包含content)进行匹配。

 posted on 2020-03-29 10:23  捞起月亮的渔民  阅读(1744)  评论(0编辑  收藏  举报