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)進行匹配。