Snort入侵檢測系統

1 一條簡單的規則

alert tcp 202.110.8.1 any -> 122.111.90.8 80 (msg:”Web Access”; sid:1)
  • alert:表示如果此條規則被觸發則告警
  • tcp:協議類型
  • ip地址:源/目的IP地址
  • any/80:端口號
  • ->:方向操作符,還有雙向操作符 <>
  • msg:在告警和包日誌中的打印消息
  • sid:Snort 規則 id

這條規則看字面意思就很容易理解。Snort 就是利用規則來匹配數據包進行實時流量分析,網絡數據包記錄的網絡入侵檢測/防禦系統(Network Intrusion Detection/Prevention System),也就是 NIDS/NIPS。

2 Snort 目錄結構

建議將Snort的目錄結構配置成如下:

/etc/snort
 ├── barnyard2.conf      	#barnyard2日誌分析工具配置文件
 ├── snort.conf          	#snort配置文件(關鍵)
 ├── threshold.conf      	#事件過濾配置文件
 ├── classification.config 	#規則分類配置文件(classtype)
 ├── reference.config      	#外部參考配置文件(reference)
 ├── gen-msg.map      		#generate id 和 msg 對應關係 map
 ├── sid-msg.map      		#snort id 和 msg 對應關係 map
 ├── unicode.map      		#預處理器http_inspect編碼翻譯文件
 ├── preproc_rules       	#預處理器及解碼器規則集
 │ ├── decoder.rules  
 │ ├── preprocessor.rules
 │ └── sensitive-data.rules
 ├── rules               	#Snort規則集(關鍵)
 │  ├── web-iis.rules 
 │  ├── web-php.rules
 More…
 ├── so_rules            	#Share Object規則集
 │  ├── browser-ie.rules
 │  ├── browser-other.rules    
 More…

3 配置文件-snort.conf

此文件是配置Snort的核心文件,包括以下幾部分:

1) Set the network variables.  					#設置各類網絡地址,規則中易於使用
2) Configure the decoder      					#設置解碼器
3) Configure the base detection engine  		#設置基礎檢測引擎
4) Configure dynamic loaded libraries   		#設置動態鏈接庫
5) Configure preprocessors     					#設置預處理器
6) Configure output plugins    					#設置輸出插件
7) Customize your rule set     					#設置自定義規則
8) Customize preprocessor and decoder rule set	#設置預處理、解碼器規則
9) Customize shared object rule set 			#設置共享對象規則集

4 Snort 體系結構

數據包嗅探解碼模塊:
主要負責監聽網絡數據包,並根據TCP/IP協議解析數據包。

預處理模塊:
1.包重組預處理器,它的作用是爲了防止攻擊信息被拆分到多個包中而逃避了Snort的檢測;
2.協議編碼預處理器,它的功能是把數據包協議解碼成一個統一的格式,再傳送給檢測模塊;
3.協議異常檢測預處器。

檢測引擎模塊:
當預處理器把數據包送過來後,檢測引擎將這些數據包與三維鏈表形式的檢測規則進行匹配,一旦發現數據包中的內容和某條規則相匹配,就通知報警模塊。

報警/日誌模塊檢測引擎:
將數據包傳送給報警模塊後,報警模塊會根據規則定義(alert,log…)對其進行不同的處理(數據庫,日誌)。

5 解碼模塊與預處理模塊

5.1 模塊介紹

由於解碼模塊和預處理模塊功能類似,都是在規則檢測引擎之前對數據包的處理,所以兩個模塊一併介紹。

解碼模塊主要是將從監控網絡當中抓取的原始網絡數據包,按照各個網絡協議棧從下至上進行解碼,並將解碼數據保存到各個對應的數據結構當中,最後交由預處理模塊進行處理。

解碼後的數據包經過預處理之後才能被主探測引擎進行規則匹配。預處理器的主要用來應對一些IDS攻擊手段。其作用包括:

  1. 針對可疑行爲檢查包或修改包,以便探測引擎能對其正確解釋。
  2. 負責對流量標準化,以便探測引擎能精確匹配特徵。

目前已知的IDS逃避技術主要有:

  1. 多態URL編碼
  2. 多態shellcode
  3. 會話分割
  4. IP碎片

Snort主要包含以下三類預處理器(舉例說明):

  1. 包重組預處理器:
    frag3:IP分片重組和攻擊監測
    stream:維持TCP流狀態,進行會話重組

  2. 協議規範化預處理器:
    http_inspect:規範HTTP流
    rpcDecode:規範RPC調用

  3. 異常檢測預處理器:
    ARP spoof:檢測ARP欺騙
    sfPortscan:檢測端口掃描

5.2 模塊配置

配置分兩個步驟,都是在snort.conf中配置。

  1. snort.conf 配置解碼器或者預處理參數。
  2. snort.conf 啓用檢測規則。

5.2.1 解碼器配置舉例

  1. 配置解碼器

    config disable_decode_alerts   			#關閉decode告警。
    config enable_decode_oversized_alerts
    
    如果一個包(IP,UDP,TCP)長度長於length字段,則告警。
    # Stop generic decode events
    

    格式爲 config docoder [option],使用 # 作爲註釋

  2. 啓用解碼器檢測規則

    include $PREPROC_RULE_PATH/decoder.rules
    

    snort.conf 文件中使用 include 關鍵詞包含配置文件和規則文件。

  3. 在 decoder.rules 中我們找到了檢測IP長度異常的規則。

    alert ( msg:"DECODE_IPV4_DGRAM_GT_IPHDR"; sid:6; gid:116; rev:1; metadata:rule-type decode;classtype:protocol-command-decode; )
    

5.2.2 預處理器 http_insepect 配置舉例

  1. 下面是 http_inspect 默認的配置

    #unicode.map是http_inspect解碼unicode時的解碼文件。
    preprocessor http_inspect: global iis_unicode_map unicode.map 1252 compress_depth 65535 decompress_depth 65535
    
    preprocessor http_inspect_server: server default \
    http_methods { GET POST PUT SEARCH MKCOL ...} \
        ...  
        enable_cookie        	#將http請求或響應中的cookie提取到緩存,用於後面規則匹配。
        normalize javascript 	#對標籤中的js腳本解碼。
        ...
    
  2. 啓用預處理器規則

    #include $PREPROC_RULE_PATH/preprocessor.rules
    

    下面是一條解碼器規則:

    alert ( msg:"DECODE_TCP_INVALID_OFFSET"; sid:46; gid:116; rev:1; metadata:rule-type decode; reference:cve,2004-0816; classtype:bad-unknown; )
    

    發現這條規則和之前看到的不一樣,它沒有源/目的IP,端口等信息,說明這條規則是由解碼器自動觸發的,用戶不需要干預。 一般我們也不需要去修改解碼器或者預處理器的規則,只需要去 snort.conf 中添加、配置或者刪除插件即可。

6 檢測引擎模塊

規則結構:

alert tcp 202.110.8.1 any -> 122.111.90.8 80 (msg:”Web Access”; sid:1) 
|---||---||---||---||---||---||---||---||---||--規則頭---||---||---||---||---||---||---||---||--||---||---||---||-規則選項---||---||---||---||-|

6.1 規則頭

動作: 在 snort 中有五種動作:alert、log、pass、activate 和 dynamic.

  1. alert: 生成一個告警,然後記錄(log)這個包。
  2. log: 記錄這個包。
  3. pass: 丟棄這個包。
  4. activate: alert並且激活另一條 dynamic 規則。
  5. dynamic:保持空閒直到被一條 activate 規則激活,被激活後就作爲一條 log 規則執行。

協議:
Snort 當前可分析的協議有四種:TCP,UDP,ICMP和IP。將來可能會更多,例如:ARP、IGRP、GRE、OSPF、RIP、IPX等。

IP地址:

  1. 地址就是由直接的 ip 地址或一個 CIDR 塊組成的。也可以指定 ip 地址列表,一個 ip 地址列表由逗號分割的 ip 地址和 CIDR 塊組成,並且要放在方括號內 [,]

  2. 否定操作符用 ! 表示

  3. 關鍵字 “any” 可以被用來定義任何地址

    例如:

    alert tcp ![192.168.1.0/24,10.1.1.0/16] any -> 192.168.2.1 80(msg:”notice!;content|xxxx|;)
    

方向操作符:
方向操作符 -> 表示規則所施加的流的方向。方向操作符左邊的ip地址和端口號被認爲是流來自的源主機,方向操作符右邊的ip地址和端口信息是目標主機,還有一個雙向操作符<>。

端口號:

  1. 端口號可以用幾種方法表示,包括 any 端口、靜態端口定義、範圍、以及通過否定操作符。
  2. 靜態端口定義表示一個單個端口號,例如111表示 portmapper,23表示 telnet,80表示 http 等等。
  3. 端口範圍用範圍操作符 “:” 表示。比如,80: , :1024 ,80:1024

6.2 規則選項

規則選項分爲四大類:

  1. 通用規則選項(General rule option)
  2. 負載檢測規則選項(Payload detection rule option)
  3. 非負載檢測規則選項(Non-Payload detection rule option)
  4. 後檢測規則選項(Post detection rule option)

6.2.1 通用規則選項(General rule option)

  • sid
    snort id,這個關鍵字被用來識別 snort 規則的唯一性。sid 的範圍是如下分配的:

    <100 			#保留做將來使用
    
    100-1000,000 	#包含在snort發佈包中
    
    >1000,000 		#作爲本地規則使用
    
  • msg
    標示一個消息,但是規則中的 msg 不起作用,sid 和 msg 的對應關係查閱 sid-msg.map。

  • sid-msg.map
    格式:sid || msg

    例子:384 || PROTOCOL-ICMP PING

    在 /etc/snort/rules/protocol-icmp.ruls 中我們找到了這條規則:

    alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"PROTOCOL-ICMP PING"; icode:0; itype:8; metadata:ruleset community; classtype:misc-activity; sid:384; rev:8;)
    

    此文件作用是將 sid 與 msg 的一一對應,否則,在告警中會出現下圖中第一條的現象。

    此文件用於自定義規則中 sid 與 msg 的對應和在 snort 自有規則中自定義告警信息。 上圖中 Snort Alert[1:1000015:0] 其中內容對應爲 Snort alert[gid:sid:rev]。這說明一個規則需要這三個因素才能確定,之前說只有 sid 唯一標示一條規則是不嚴謹的。

  • gid
    generate id,作用是爲了說明這條規則是 snort 的哪部分觸發的。比如是由解碼器、預處理器還是 Snort 自有規則等。

    查看 /usr/local/share/doc/snort/generators 文件(此文件不是配置文件):

    rules_subsystem       1 		# Snort Rules Engine
    rpc_decode            106 		# RPC Preprocessor(預處理器)
    stream4               111 		# Stream4 preprocessor(預處理器)
    ftp                   125 		# FTP decoder(解碼器)
    ...               
    

    decoder 和 preprocessor 的 gid 就不一一列舉,可以看到 Snort Rule Engine 的 gid 爲1,自定義規則和 snort 自有規則(也就是 /etc/snort/rules 目錄下的規則)gid默認是1。但是這裏我們獲知 decoder 和 preprocessor 也是有 sid 的。 舉例說明:

    /etc/snort/rules/protocol-icmp.rules 中的一條規則:

    alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:“PROTOCOL-ICMP Traceroute”; icode:0; itype:30; metadata:ruleset community; classtype:misc-activity; sid:456; rev:8;)
    

    gid默認爲1

    /etc/snort/preproc_rules/decoder.rules 中的一條規則:

    alert ( msg:"DECODE_IP6_EXCESS_EXT_HDR"; sid:456; gid:116; rev:1; metadata:rule-type decode; classtype:misc-activity; )
    

    可以看到兩條規則的 sid 是相同的,所以還需要 gid 來區分。

  • gen-msg.map
    這個文件和 sid-msg.map 作用類似,在邏輯上應該是包含了sid-msg.map(sid-msg.map相當於默認gid爲1)

    格式:generatorid || alertid(sid) || MSG

    例子:

    1   || 1 || snort general alert
    129 || 2 || stream5: Data on SYN packet
    116 || 271 || snort_decoder: WARNING: IPv6 header claims to not be IPv6
    116 || 456 || snort_decoder: WARNING: too many IPV6 extension headers #例子
    ...
    

    拿 gid 中第二條規則舉例,如果此條規則被觸發,則會報 snort_decoder: WARNING: too many IPV6 extension headers告警,而不是DECODE_IP6_EXCESS_EXT_HDR。所以規則中的 msg 僅僅起到標示作用,告警 msg 需要在 sid-msg.map 和gen-msg.map 這兩個文件中對應查找。

  • rev
    這個關鍵字是被用來識別規則修改的版本,需要和 sid,gid 配合使用。 這樣就介紹完了 gid,sid,rev 三個確定規則唯一的元素。

  • reference
    外部攻擊參考,這個關鍵字允許規則包含一個外面的攻擊識別系統。這個插件目前支持幾種特定的系統,這些插件被輸出插件用來提供一個關於產生報警的額外信息的連接。

  • reference.config
    格式:config reference: system URL

    例子: config reference: cve http://cve.mitre.org/cgi-bin/cvename.cgi?name=
    定義了一些外部安全網站的網址。比如規則中定義 reference: cve,1001,那麼就像在上面的網址後面添加了1001,http://cve.mitre.org/cgi-bin/cvename.cgi?name=1001,最後點擊告警中的 [cve],就會跳轉到相應的網址。

    注:reference 也需要在 sid-msg.map 中與 sid 對應,否則不起作用,類比 msg。

  • classtype
    規則類別標識。這個關鍵字把報警分成不同的攻擊類。通過使用這個關鍵字和使用優先級,用戶可以指定規則類中每個類型所具有的優先級。

  • priority
    設置 classtype 的優先級。classtype 和 priority 是配合使用的,classification.config 文件將其聯繫起來。

  • classification.config
    格式: config classification:shortname,short description,priority

    例子: config classification: attempted-admin,Attempted Administrator Privilege Gain,1

    寫在此文件中的都是默認值,priority 關鍵詞可以在規則中重寫優先級。

    例子:

    alert tcp any any -> any 80 (msg:"EXPLOIT ntpdx overflow"; dsize:>128; classtype:attempted-admin; priority:10 );
    
  • metadata
    可以在規則中添加自定義的信息,一般以鍵值對的形式出現。通用規則選項只是對一條規則進行標示,分類等操作,並沒有進行實際的過濾檢測。

6.2.2 負載檢測規則選項(Payload Detection Rule Options)

  • content
    content 是 Snort 重要的關鍵詞之一。它規定在數據包的負載中搜索指定的樣式。它的選項數據可以包含混合的文本和二進制數據。二進制數據一般包含在管道符號中 “|”,表示爲字節碼(bytecode),也就是將二進制數據的十六進制形式。

    舉例如下:

    alert tcp any any -> any 139 (content:"|5c 00|P|00|I|00|P|00|E|00 5c|";)
    alert tcp any any -> any 80 (content:!“GET”;)
    

    content 還有很多修飾符:

    Nocase            content字符串大小寫不敏感
    rawbytes          直接匹配原始數據包
    Depth             匹配的深度
    Offset            開始匹配的偏移量
    Distance          兩次content匹配的間距
    Within            兩次content匹配之間至多的間距  
    http_cookie       匹配cookie
    http_raw_cookie   匹配未經normalize的cookie
    http_header       匹配header
    http_raw_header   匹配未經normalize的header
    http_method       匹配method
    http_url          匹配url
    http_raw_url      匹配日在未經normalize的url中
    http_stat_code    匹配狀態碼中匹配
    http_stat_msg     匹配狀態信息
    http_encode       匹配編碼格式
    

    http 開頭的修飾符需要配合前面介紹過的預處理器 http_inspect 一起使用。

  • pcre
    允許用戶使用與 PERL 語言相兼容的正則表達式。

    格式 pcre:[!]"(/<regex>/|m<delim><regex><delim>)[ismxAEGRUBPHMCOIDKY]

    例子:

    alert tcp any any -> any 80 (content:“/foo.php?id="; pcre:"/\/foo.php?id=[0-9]{1,10}/iU";) 
    

    正則的細節查閱snort_manual。

  • protected_content
    將 content 中的查詢內容使用 hash 算法加密,保護規則的私密性。

    格式:protected_content:[!]"<content hash>", length:orig_len[, hash:md5|sha256|sha512];

  • rawbytes
    忽略解碼器及預處理器的操作,直接匹配原始網絡包。

上面只列舉出了一些常用的 payload detection rule option,更多的關鍵詞查閱 snort_manual。

6.2.3 非負載檢測規則選項(Non-Payload Detection Rule Option)

Fragoffset                IP 偏移量
Ttl                       IP 生存時間
Tos                       IP 服務類型
Id                        IP 標識
Ipopts                    IP 可選項
Fragbits                  IP 標誌
Dsize                     數據包負載量
Flags                     TCP flags
Seq                       TCP seq
Ack                       TCP ack
Window                    TCP window
Icmp_id                   ICMP ID

此類規則選項都是對數據包幀結構中特殊字段的匹配。

6.2.4 後檢測規則選項(Post-Detection Rule Option)

Logto                     輸出日誌路徑
Session                   從 TCP 會話中獲取用戶數據
Resp                      通過發送響應結束惡意的請求
React                     不僅僅記錄觸發規則的特定數據包
Tag                       不僅僅記錄觸發規則的特定數據包
Activates                 activate 動作
Activates_by              dynamic 動作
Count                     dynamic 規則被觸發後可以匹配的包的數目
Replace                   替換 content 內容
Detection-filter          檢測過濾

6.3 檢測引擎模塊配置

  1. 在 /etc/rules 目錄下的 *.rules 文件中寫規則

  2. snort.conf 中 include 對應規則

    例子

    include $RULE_PATH/local.rules
    #include $RULE_PATH/app-detect.rules
    #include $RULE_PATH/attack-responses.rules
    #include $RULE_PATH/backdoor.rules
    #include $RULE_PATH/bad-traffic.rules
    #include $RULE_PATH/blacklist.rules
    

7 Snort 告警/日誌模塊

7.1 輸出模塊配置

輸出模塊配置在 snort.conf 的 Configure output plugins. 支持多種輸出格式。如下列中是將 Snort 的報警日誌輸出格式設置爲 unified2,並通過 barnyard2 解析 unified2 文件,將報警日誌存入數據庫。

設置日誌路徑:

config logdir:/var/log/snort 

設置輸出格式爲 unified2:

output unified2: filename snort.log, limit 128

barnyard2.conf

barnyard2 的作用是將 unified2 格式的數據存入數據庫。

設置與 snort 日誌關聯:

config waldo_file: /var/log/snort/barnyard.waldo

設置數據庫:

output database: log, mysql, user=snort password=123456 dbname=snort host=localhost

7.2 數據庫

  • schema

    vseq:數據庫模式ID
    ctime:數據庫創建時間
    

    信息表,和其他數據庫內容上沒有聯繫

  • sensor

    sid:傳感器代號
    hostname:傳感器所屬的用戶名稱
    Interface:傳感器對應的網絡接口
    filter:對應傳感器的過濾原則
    detail:表示傳感器監測模式,記錄模式詳細程度的級別        
    encoding:包含數據存在形式
    last_cid: 對應每個sid即傳感器捕獲告警的最後一個值
    
  • detail

    0-fast快速檢測
    1-full全面檢測
    

    傳感器sensor的檢測級別。

  • encoding

    0- Hex
    1- base64
    2- asci
    

    數據包中數據的存在形式。

  • event

    sid:sensor id,傳感器id。
    cid;event id   事件id。sid和cid共同作爲主碼,其中cid是在sid的基礎上進行排序的。每個sid對應自己的cid排序。
    signature:對應signature表格中的sig_id選項,表明這條告警事件所屬的規則形式的告警對應哪一類rules。
    timestamp:對應告警事件發生的系統時間。
    

    最核心的一張表,告警的每一條數據都會存儲在 event 表中,一條 event 數據就代表一個包。

  • signature

    sig_id: 總數代表發生告警種類的總數。是告警種類的主碼。唯一標識一條規則。
    sig_name:告警名稱。對應每條alert語句的Msg。
    sig_class_id:對應sig_class表格中的sig_class_id.代表告警種類的大類信息。
    sig_priority:告警的優先級
    sig_rev:版本號
    sig_sid:snort id   
    sig_gid:generate id 
    

    存儲 snort 規則的一張表,可以看到 sig_sid,sig_gid,sig_rev 分別對應規則中的 sid,gid,rev。注意規則中的 snort id 和數據庫中的 sensor id 注意區分。

  • sig_reference

    sig_id:對應的告警種類。
    ref_id:對應reference表格中的主碼
    ref_seq:參考序列號
    

    提供報警種類信息signature的參考信息。將signature與reference聯繫起來的表格。

  • reference

    Ref_id:主碼
    Ref_system_id:對應reference_system表格
    Ref_tag:規則中 cve,bugtraq 後面的參數
    
  • reference_system

    ref_system_id:主碼
    ref_system_name:reference system的名字,如cve,url等。
    
  • sig_class

    sig_class_id:分類編號
    sig_class_name:分類名稱
    

    signature 告警種類的分類信息。

  • iphdr

  • tcphdr

  • udphdr

  • icmphdr

  • data
    data_payload:數據包有效載荷

    規則中協議爲 tcp 時,data_payload 中是 tcp 後面的內容

    規則中協議爲 icmp 時,data_payload 中是 icmp 協議中的 data 字段值

  • opt
    IP 和 OPT 的 option

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