Snort源碼分析

       Snort由幾大軟件模塊組成,這些軟件模塊採用插件方式與Snort結合,擴展起來非常方便,例如有預處理器和檢測插件,報警輸出插件等,開發人員也可以加入自己編寫的模塊來擴展Snort功能。所有這些子模塊都建立在數據包截獲庫函數接口Libpcap的基礎上,Libpcap爲他們提供了一個可移植的數據包截獲和過濾機制。

snort源代碼主要由以下幾個主要部分構成:

snort.c   snort主代碼

decode.c   包解碼器

rules.c  規則引擎

detect.c  檢測引擎

log.c  記錄引擎

以 spp_開頭     預處理器插件

以 sp_開頭       處理插件

以sop_開頭       輸出插件

(1)主程序流程

處理流程圖如下:

                                                                                       

        在 snort.c中 , SnorMain函數纔是程序真正的入口和出口 ,它被 main函數調用 。 在 SnorMain中首先初始化設定一些缺省值 , 然後調用 ParseCmdLine函數解析命令行參數 , 根據命令行參數 , 填充結構變量 pv;pv數據結構用於存儲程序所用到的各種變量以及命令行參數的解析結果 。 根據 pv的值 (也就是解析命令行的結果 )確定工作方式 , 需要注意 :如果是運行在 D aemon 方式 , 通過 GoDaemon函數 , 創建守護進程 , 重定向標準輸入輸出 , 實現 Daemon 狀態 , 並結束父進程 。隨後調用 OpenPcap函數打開 L ibpcap包捕獲接口 。Snort可以實時採集網絡數據 , 也可以從文件讀取數據進行分析 。 如果是讀取文件進行分析 (並非直
接從網卡 實時採集來 的 ), 以該文件名 作爲 libpcap 的 函數OpenPcap的參數 , 打開採集過程 ;如果是從網卡實時採集 , 就把
網卡接口作爲 O penPcap的參數 , 利用 libpcap的函數打開該網卡接口 。

        接着 , 指定數據包的解析處理函數。不同的數據鏈路網絡 ,解析的函數也不同 。利用函數 SetProcessor, 根據全局變量
data link的值 , 來設定不同的解析函數 , 並將其保存在全局定義的函數指針 grinder中 。 例如 , 以太網 , 解析函數爲 DecodeE thPkt;令牌環網 , 解析函數爲 D ecodeTRPkt, 等等 。 這些 Decode*函數 , 在 decode. c中實現 。
        然後初始化各種預處理器插件 ( InitP reprocessor函數 ), 初始化各種處理插件 (InitPlugins函數 ), 初始化各種輸出插件
(InitOutputPlugins函數 ), 並解析規則文件 , 轉化成規則鏈表 。再根據報警模式 , 設定報警函數 ;根據日誌模式 , 設定日誌函數 ;
如果指定了能夠進行響應 , 就打開 raw socket, 準備用於響應 。最後 , 調用 InterfaceThread 函 數循環抓包檢測 , 在Interfa
ceThread函數中調用了 libpcap 的庫函數 pcap_ loop, 它實質上循環調用了pcap_ read函數 , 直至所需數目的數據包全部處理完
畢 。pcap_ loop 對每個採集來的數據包都用 ProcessPacke t函數進行處理 , ProcessPacke t函數的功能是啓動對每一個數據包的處理過程 , 如果出現錯誤或者到達指定的處理包數 (pv. pkt_ cnt定義 ), 就退出該函數 。
(2)數據包處理流程

數據包處理流程圖如下:

                                                           

        數據包處理流程被主程序在 InterfaceThread函數中循環調用 。對數據包進行處理時 , 首先調用各種網絡協議解析程序 , 對當前數據包進行分層協議格式字段的分析 ,並將分析結果存入到重要的數據結構packet中。ProcessPacket函數調用DecodeEthPkt函數 (在 decode. c中 ), 該函數對以太幀進行解碼 , 另外還有 DecodeIP對 IP協議進行解碼 ,DecodeTCP對 TCP協議進行解碼 , 等等 。然後 , 系統依次調用預處理程序 Preprocess函數 (在 detect.c中 )和檢測主引擎 Detect函數 , 該函數對當前數據包按照一定的順序 , 分別應用規則列表 , 根據給定的各種規則和當時所截獲的數據包分析結果 , 作出是否發生入侵行爲的判斷 。如果當前數據包符合某條檢測規則所指定的情況 , 則系統可以根據這條規則所定義的響應方式以及輸出模塊的初始化定義情況 , 選擇進行各種方式的日誌記錄和報警操作 。
(3)Snort規則建立及檢測引擎

         在啓動時 , Snort讀取所有的規則文件 , 並且建立一個三維的鏈表 , Snort使用規則匹配包和檢測 , 輸入和讀取規則文件都
在 parser. c中的ParseRulesFile()函數中實現 。鏈表的建立在snor.t c中進行初始化 , 當 Snort以 IDS模式運行時 , 在對網絡數
據包進行檢測前 , Snort首先讀取 Snort.conf配置文件 , 在Snort.conf文件的 “ Step4— Custom ize you r ru le set”中鏈接特定的規則文件 , 包含在每個規則文件中的規則被解析並且鏈表建立 。建立鏈表時 , 首先按規則類型 (Log、 Pass、Alert、 Dynamic、Activation)分類 , 分成了五個單獨的規則鏈 ;然後針對這五個規則鏈的每一個按協議類型 (TCP、UDP、 ICMP、 IP)分成相應的節點鏈表 ;最後又按照源 IP、目的 IP、源端口號及目的端口號分爲多個規則樹節點 (RTN);每個規則樹節點下又有規則選項 , 稱
爲選項樹節點 (OTN);這樣每個OTN節點就對應了一條規則 。
                                 

        當數據包到達檢測引擎時 , Snort將首先匹配規則鏈 , 然後根據數據包協議匹配相應 的節點鏈表 , 於是從左至右遍 歷RTN, 參看源 、目的 IP及端口號是否匹配 , 找到一個匹配後 , 算法向下進行 , 在每個 OTN 中尋找匹配 ;當找到一個匹配後 , 退出樹結構返回相應規則鏈的頭部 , 通過指定格式輸出 。
 

附錄:插件分析

Snort系統中插件模塊共分爲三種類型:預處理器插件模塊、輸出插件模塊和處理插件模塊。

        預處理器插件模塊———在數據包進入檢測引擎之前, 它們首先被送入預處理器 , 主要是在數據包送入 Snort主檢測引擎前提供一個報警、丟棄數據包、修改數據包的地方。預處理器完成的功能主要有:①包重組, 完成將多個包中的數據進行合併的工作, 如 TCP流重組插件 (stream4)、 IP 碎片重組插件 (frag2);②協議解碼和規範化, Snort中有三個協議解碼及規範化插件, 分別對 Telne t、HTTP和 RPC 協議進行處理;③異常檢測, 對無法用一般的規則發現的攻擊進行檢測, 或者進行協議異常檢測, 如端口掃描插件、Back Orifice檢測插件等;在 Snort.conf文件中加入preprocessor <name> <options>就可以啓動所需的預處理器。
         處理插件模塊———處理插件在規則匹配階段的 ParseRleOptions函數(在 rule. c中)中被調用, 輔助完成基於規則的匹配過程。 每個規則處理函數通常對應規則選項中的一個關鍵字, 實現對這個關鍵字的解釋, 主要功能爲:①檢查協議各字段,如TCPF lag、 ICMPType、 IPId 等;②輔助功能, 如會話記錄、攻擊響應、關閉連接等。
         輸出插件模塊———輸出插件允許把報警和日誌以更加靈活的格式和表現形式呈現給管理員, 這些輸出插件在預處理器和抓包引擎執行完後調用 Snort報警和日誌子系統時執行。他們在配置文件中定義, 在觸發規則時被調用, 如將數據寫入數據庫或者以TCPDump 格式輸出日誌文件, 或者向NMS發送SNMPtrap等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章