Snort
- Snort簡介
- Snort安裝與配置
- Snort總體結構分析
- Snort的使用
- Snort的規則
- 使用 Snort構建入侵檢測系統實例
Snort簡介
Snort是一個基於 Libpcap的輕量級網絡入侵檢測系統,它運行在一個“傳感器(Sensor)”主機上,監聽網絡數據。
Snort能夠把網絡數據和規則集進行模式匹配,從而檢測可能的入侵企圖;或者使用 SPADE(Statistical Packet Anomaly Detection Engine)插件,使用統計學方法對網絡數據進行異常檢測。
Snort使用一種易於擴展的模塊化體系結構,開發人員可以加入自己編寫的模塊來擴展Snort的功能,如HTTP解碼插件、TCP數據流重組插件、端口掃描檢測插件、FLEXRESP插件以及各種日誌輸入插件等。
Snort的特點
-
Snort是一個輕量級的入侵檢測系統。Snort雖然功能強大,但是其代碼極爲簡潔、短小,其源代碼壓縮包只有大約110KB。
-
Snort的跨平臺性能極佳,Snort具有跨平臺的特點,它支持的操作系統廣泛,包括 Linux、OpenBSD、FreeBSD、NetBSD、Solaris、HP-UX、AIX、IRIX、Win32(Windows9xNT2000)等。
-
Snort的功能非常強大:
- Snort具有實時流量分析和日誌IP網絡數據包的能力。
- Snort能夠進行協議分析,內容的搜索/匹配。
- Snort的日誌格式既可以是 Tcpdump式的二進制格式,也可以解碼成ASCII字符形式。
- Snort可以對TCP包進行重組。
- Snort能夠報告非正常的可疑包,從而對端口掃描進行有效的檢測。
- Snort還有很強的系統防護能力。
-
擴展性能較好,對於新的攻擊威脅反應迅速。作爲一個輕量級的網絡入侵檢測系統,Snort有足夠的擴展能力。Snort支持插件,可以使用具有特定功能的報告、檢測子系統插件對其功能進行擴展。Snort當前支持的插件包括數據庫日誌輸岀插件、碎數據包檢測插件、端口掃描檢測插件、HTTP URI normalization插件、XML插件等。
-
遵循公共通用許可證GPL
- Snort遵循GPL,所以任何企業、個人、組織都可以免費使用它作爲自己的NIDS。
Snort的組成
Snort由3個重要的子系統構成:數據包解碼器、檢測引擎、日誌與報警系統。
Snort的工作模式
Snort有以下3種工作模式。
- 嗅探器——嗅探器模式僅僅是從網絡上:讀取數據包並作爲連續不斷的流顯示在終端上。
- 數據包記錄器——數據包記錄器模式把數據包記錄到硬盤上。
- 網絡入侵檢測系統——網路入侵檢測模式是最複雜的而且是可配置的。用戶可以讓 Snort分析網絡數據流以匹配用戶定義的一些規則,並根據檢測結果採取一定的動作。
Snort安裝
略
Snort總體結構分析
插件機制優點
在 Snort中運用了插件機制。對於 Snort來說,插件機制具有以下一些明顯的優點。
- 通過增加插件,Snort能夠非常容易地増加功能,使程序具有很強的可擴展性。
- 插件機制簡化了Snort的編碼工作。
- 插件機制使代碼功能內聚,模塊行強,程序相對易讀。
- 插件模塊包括預處理插件、處理插件和輸出插件3種,它們通常對應規則中的一個或幾個關鍵字,規則匹配中遇到這些關鍵字時就會激活相應的插件,以完成相應的功能。
預處理插件
它們的源文件名都是以spp_開頭的,在規則匹配(誤用檢測)之前運行,完成的功能主要分爲以下幾類。
- 模擬 TCP/IP堆棧功能的插件:如I碎片重組、TCP流重組插件。
- 各種解碼插件:如HITP解碼插件、Unicode解碼插件、RPC解碼插件、Telnet協商插件等。
- 規則匹配無法進行攻擊檢測時所用的檢測插件:如端口掃描插件、Spade異常入侵檢測插件、Bo檢測插件、Arp欺騙檢測插件等。
處理插件
它們的源文件名都以sp_開頭,在規則匹配階段的ParseRuleOptions中被調用,輔助完成基於規則的匹配檢測過程。每個規則處理函數通常對應規則選項中的一個關鍵字,實現對這個關鍵字的解釋或輔助解釋。這些插件的主
要功能如下。
- 協議各字段的檢查,如 TCPFlag,IcmpType,IcmpCode,Ttl,IpId,TcpAck,TcpSeg,Dsize,IpOption,Rpc,Icmpld,IcmpSeq,IpTos,Frag Bits,TcpWin,IpProto和 IpSame等。
- 一些輔助功能,如 Respond,Priority,Pattern Match,Session,React,Reference等,這些插件分別完成響應(關閉連接)、嚴重級別、模式匹配(內容)、會話記錄、攻擊響應(高級的響應機制)、攻擊參考信息等功能。
輸出插件
它們的源文件名都以spo_開頭,這些插件分爲日誌和警告兩種類型放入兩個列表中,在規則匹配過程中和匹配結束之後調用,以便記錄日誌和警告。以一個HTTP解碼預處理器插件爲例來解釋插件的內部結構:
- 每個插件都有一個安裝函數,名稱爲 SetupXXX(),如Spp_http_decode.c: Setuphttpdecode()
- 在解釋規則文件時,如果檢測到相應的關鍵字,系統就會使用規則文件中這些關鍵字後的字符串作爲參數來調用相應的初始化函數。
- 在檢測過程中,一旦規則匹配成功,就會觸發處理函數的執行,預處理器就會在預處理過程中對數據報調用相應處理函數進行處理。
Snort使用
Libpcap的命令行
Snort和大多數基於 Libpcap的應用程序(如 Tcpdump)一樣可以使用標準BPF類型的過濾器。過濾器的正確設置將決定 Snort是否只看到所感興趣的數據包,如果沒有設置過濾器,Snort將看到所有網絡中的數據包。
整個過濾器的表達式由一個或多個元語組成,而一個元語則是由一個或多個關鍵字加上一個相關的值(字符串或數字)所組成。
關鍵字分爲以下幾類。
- 屬性類關鍵字:說明後面所跟值的意義,這樣的關鍵字有host、net、port。如果一個元語沒有屬性關鍵字,默認爲host。
- 方向類關鍵字:說明報文的流向,這樣的關鍵字有src,dst,src or dst,src and dst。對於空連接層(如:使用slip等的點到點協議),可以使用 inbound和 outbound來說明方向
- 協議類關鍵字:用來限制協議,這樣的關鍵字有 ether,fddi,ip,arp,rarp,decnet,lat,sca,moprc,mopdl,tcp,udp。如果一個元語沒有協議類關鍵字,那麼所有可能的協議都將符合。
過濾器的描述功能非常強大,可以用來描述任何想要得到的報文。例如
net 192.168.1 and not host 192.168.1.1
說明除了主機192.168.1.1外其他所有192.168.1網段的網絡數據報文。
tcp[13]&3!=0 and not src and dst net localnet
說明涉及外網的tcp會話中起始和終止報文(SYN和FIN報文)
Snort的命令行
Snort的命令行參數很多,可以使用 Snort-?命令列出這些參數及其簡單的解釋,詳細的解釋可以使用 man Snort命令查看幫助頁。
-
-A 設置報警模式:fast、full、none(只是使用報警文件)、undock(使用UNIX套接字記入日誌,出於測試階段)。
-
-a 顯示ARP(Address resolution protocol,地址解析協議)包。
-
-b 日誌文件使用tcpdump格式(更快)
-
-c 使用規則文件 rules
-
-C 只使用字符方式打印負載信息(不使用hex方式)
-
-d 複製應用層。
-
-D 在後臺運行 Snort(精靈狀態)。
-
-e 顯示第二層(數據鏈路層)包頭信息。
-
-F Read BPF filters from file
-
-g 初始化完成後,使 Snort的gid爲 gname
-
-h Home網絡爲hn
-
-i 在接口if監聽。
-
-I 把界面名加入到報警輸出界面。
-
-I 設置目錄ld爲日誌目錄。
-
-M把SMB消息發送到文件 wrkst列出的工作站中(Requires smbclient to be in PATH)
-
-n收到cnt個包後退出。
-
-N關閉日誌功能(警報功能仍然有效)。
-
-o把規則測試順序修改爲:Pass|Alert|Log
-
-O打亂被日誌的IP地址
-
-p關閉混雜嗅探模式。
-
-P設置複製的包的長度爲 snaplen(默認:1514)
-
-q安靜模式。不輸出 banner和狀態報告
-
-r讀取並處理 tcpdump文件tf(回放功能)。
-
-s把所有警告信息記入 syslog
-
-S設置規則文件中的n的值等於v的值。
-
-t初始化完成後 Chroot到dir目錄。
-
-u初始化完成後,把 Snort的uid設置爲 uname。
-
-v設置冗餘模式。
-
-V顯示版本號。
-
-X從鏈路層開始複製包的數據。
-
-?顯示幫助信息。
如果在一個高數據流量(例如大於100 Mbit/s)的網絡環境下運行 Snort,就需要考慮如何配置 Snort才能使它高效率地運行,這就要求使用更快的輸出功能,產生更少的警告,可以使用諸如-b,-A fast,-s等選項。例如:
./Snort -b -A fast -c Snort-Iib
使用這種配置選項,日誌信息將被以二進制的 tcpdump格式記錄到Snort.log文件中。然後,使用下面帶有-選項的命令讀取這個文件,做進一步的分析:
./Snort -d -c Snort-lib-I ./log-h 192 1681.0/24 -r Snort.log
Snort的規則
Snort規則分爲兩個部分:規則頭和規則選項。規則頭包含規則的動作、協議、源地址、目的地址、子網掩碼、源和目的端口信息。規則選項包含報警信息以及用於確定是否觸發規則響應動作而檢查的數據包區域位置信息。
規則頭
規則動作
規則的頭包含了定義一個包的Who,Where和What信息,以及當滿足規則定義的所有屬性的包出現時要採取的行動。規則的第一項是“規則動作”(Rule action),“規則動作”告訴Snort在發現匹配規則的包時要幹什麼。在 Snort中有5種動作:Alert,Log,Pass,Activate和 Dynamic。
協議
規則的下一部分是協議。Snort當前分析可疑包的協議有4種:TCP,UDP,ICMP和IP,將來可能會更多,如ARP,IGRP,GRE,OSPF,RIP,IPX等。
IP地址
規則頭的下一個部分處理一個給定規則的P地址和端口號信息。關鍵字 “any” 可以被用來定義任何地址。
有一個操作符可以應用在IP地址上,它是否定運算符。這個操作符告訴Snort匹配除了列出的IP地址以外的所有IP地址。否定操作符用“!”表示。下面這條規則對任何來自本地網絡以外的流都進行報警。
端口號
端口號可以用幾種方法表示,包括“any端口、靜態端口定義、範圍、以及通過否定操作符。“any”端口是一個通配符,表示任何端口。靜態端口定義表示一個單個端口號,例如,111表示Portmapper,23表示Telnet,80表示HTTP等。端口範圍用範圍操作符“:”表示。
方向操作符
方向操作符“->”表示規則所施加的流的方向。方向操作符左邊的IP地址和端口號被認爲是流來自的源主機,方向操作符右邊的I地址和端口信息是目標主機,還有一個雙向操作符“<>。它告訴 Snort把地址/端口號對既作爲源,又作爲目標來考慮。這對於記錄/分析雙向對話很方便,例如,Telnet或者POP3會話。
Activate和 Dynamic規則
注意:Activate和 Dynamic規則將被 Tagging所代替。在 Snort的將來版本,Activate和 Dynamic規則將完全被功能增強的Tagging所代替。
Activate和 Dynamic規則對給了 Snort更強大的能力。用戶現在可以用一條規則來激活另一條規則,當這條規則適用於些數據包時,在一些情況下這是非常有用的,例如用戶想設置一條規則:當一條規則結束後來完成記錄。Activate規則除了包含一個選擇域:Activates外就和一條 Alert規則一樣。
規則選項
規則選項組成了 Snort入侵檢測引擎的核心,既易用又強大還靈活。所有的 Snort規則選項用分號“;”隔開。規則選項關鍵字和它們的參數用冒號“:”分開。按照這種寫法,Snort中有以下42個規則選項關鍵字。
- msg——在報警和包日誌中打印一個消息
- logto——把包記錄到用戶指定的文件中而不是記錄到標準輸出。
- ttl——檢查IP頭的TTL的值。
- tos——檢査IP頭中TOS字段的值。
- id——檢查IP頭的分片ID值。
- ipoption——査看IP選項字段的特定編碼
- fragbits——檢查IP頭的分段位。
- dsize——檢查包的淨荷尺寸的值。
- flags——檢查 TCP Flags的值。
- seq——檢查TCP順序號的值。
- ack——檢查TCP應答(Acknowledgement)的值。
- window——測試TCP窗囗域的特殊值。
- itype——檢查 ICMP Type的值。
- icode——檢查 ICMP Code的值。
- icmp_id——檢查 ICMP ECHO ID的值。
- Icmp_seg——檢查 ICMP ECHO順序號的值。
- content——在包的淨荷中搜索指定的樣式。
- content-list——在數據包載荷中搜索一個模式集合。
- offset——Content選項的修飾符,設定開始搜索的位置。
- depth——Content選項的修飾符,設定搜索的最大深度。
- nocase——指定對 Content:字符串大小寫不敏感。
- session——記錄指定會話的應用層信息的內容。
- rpc——監視特定應用進程調用的RPC服務。
- resp——主動反應(切斷連接等)。
- react——響應動作(阻塞Web站點)。
- reference——外部攻擊參考IDS。
- sid——Snort規則ID。
- rev——規則版號
- classtype——規則類別標識。
- priority——規則優先級標識號。
- uricontent——在數據包的URI部分搜索一個內容。
- tag——規則的高級記錄行爲。
- ip_proto——IP頭的協議字段值
- sameip——判定源IP和目的IP是否相等。
- stateless——忽略流狀態的有效性。
- regex——通配符模式匹配。
- distance——強迫關係模式匹配所跳過的距離。
- within——強迫關係模式匹配所在的範圍。
- byte_test——數字模式匹配。
- byte_jump——數字模式測試和偏移量調整。
規則的語法
規則分類存放在規則文件中。規則文件是普通的文本文件,用戶可以使用普通的文本編輯器打開進行編輯。
規則文件可以包含註釋行,註釋行以“#”字符開頭,#號前不能有任何非空字符。
Snort允許定義變量,並在規則中使用這些變量。變量的定義格式如下所示:
var:
在規則中可以直接使用 $,而遇到變量名解釋器就會使用< value>替代 $。
預處理程序
預處理程序使得 Snort的功能可以很容易地擴展,用戶和程序員能夠將模塊化的插件方便地融入Snort之中。預處理程序代碼在探測引擎被調用之前運行,但在數據包譯碼之後。通過這個機制,數據包可以通過額外的方法被修改或分析。使用 preprocessor關鍵字加載和配置預處理程序。
在 Snort規則文件中的 preprocessor指令格式如下:
preprocessor :
例如:
preprocessor minfrag:128
輸出插件
輸出插件使得Snot在向用戶提供格式化輸出時更加靈活。輸出插件在 Snort的告警和記錄子系統被調用時運行,在預處理程序和探測引擎之後。規則文件中指令的格式非常類似於預處理程序。
格式:
output :
例子:
output alert_syslog:LOG_AUTH LOG_ALERT
規則例子
(1)記錄所有登錄到一個特定主機的數據包:
log tcp any any->192.168.1.1/32 23
(2)在第一條的基礎上記錄了雙向的流量:
log tcp any any<>192.168.1.1/32 23
(3)這一條規則記錄了所有到達你的本地主機的icmp數據包:
log icmp any any-> 192.168 1.0/24 any
(4)這條規則允許雙向的從你的機子到其他站點的http包:
pass tcp any 80<>192.168 1.0/24 any
(5)這條告警規則顯示了本地主機對其他主機的111端口的訪問,並在log中顯示端口影射調用(‘portmapper call’)信息:
alert tcp 192.168.1.0/24 any-> any 111(msg:“Portmapper call”;)
(6)記錄其他任意地址的小於1024端口訪問本地小於1024端口的流量:
log tcp any :1024->192.168.1.0/24 :1024
(7)這條規則將會發現 SYN FIN掃描:
alert tcp any any-> 192.168 1.0/24 any(msg:“SYN-FIN scan!”;flags: SF;)
(8)這條規則將會發現空TCP掃描:
alert tcp any any->192.168.1.0/24 any(msg:Null scan!"flags:0;)
(9)這條規則將會發現 Queso fingerprint掃描:
alert tcp any any-> 192.168 1.0/24 any(msg:“Queso fingerprint”;flags: S12;)
(10)這條規則將進行基於內容的查找以發現溢出攻擊:
alert tcp any any-192 168 1.0/24 143(msg:“IMAP Buffer overflow!”; content: “|90E8 COFF FFFF|/bin/sh”;)
(11)這條規則將會發現PHF攻擊:
alert tcp any any->192.168.1.0/24 80(msg:"PHF attempt "; content: “/cgi-bin/phf”; )
(12)這條規則將會發現 Traceroute包:
alert udp any any-192.168.1.0/24 any(msg:“Traceroute”;ttl:1;)
(13)這條規則將會發現其他主機對本地發出的icmp包:
alert udp any any->192.168 1.0/24 any(msg:“Traceroute”;ttl:1)
(14)這條規則發現nmap的TCP的ping掃描:
alert tcp any any->192.168.1.0/24 any(flags:A;ack:0;msg:NMAP TCP ping!"; )
(15)這條規則將會發現源路由的數據包(源路由攻擊):
alert tcp any any-> any any(ipopts:lsrr;msg:“Source Routed packet!”; )