Snort規則被分成兩個邏輯部分:規則頭和規則選項。規則頭包含規則的動作,協議,源和目標ip地址與網絡掩碼,以及源和目標端口信息;規則選項部分包含報警消息內容和要檢查的包的具體部分。
1. 規則頭:
規則動作:
在snort中有五種動作:alert、log、pass、activate和dynamic.
1、Alert-使用選擇的報警方法生成一個警報,然后記錄(log)這個包。
2、Log-記錄這個包。
3、Pass-丟棄(忽略)這個包。
4、activate-報警并且激活另一條dynamic規則。
5、dynamic-保持空閑直到被一條activate規則激活,被激活后就作為一條log規則執行。
協議類型:
Snort當前分析可疑包的ip協議有四種:tcp 、udp、icmp和ip。將來可能會更多,例如ARP、IGRP、GRE、OSPF、RIP、IPX等。
地址:
關鍵字"any"可以被用來定義任何地址。地址就是由直接的數字型ip地址和一個cidr塊組成的。cidr塊指示作用在規則地址和需要檢查的進入的任何包的網絡掩碼。/24表示c類網絡, /16表示b類網絡,/32表示一個特定的機器的地址。
否定操作符用"!"表示。
你也可以指定ip地址列表,一個ip地址列表由逗號分割的ip地址和CIDR塊組成,并且要放在方括號內“[”,“]”。此時,ip列表可以不包含空格在ip地址之間。
例如:
alert tcp ![192.168.1.0/24,10.1.1.0/24] any -> [192.168.1.0/24,10.1.1.0/24] 111 (content: "|00 01 86 a5|"; msg: "external mountd access";)
變量定義:
var MY_NET 192.168.1.0/24
alert tcp any any -> $MY_NET any (flags: S; msg: "SYN packet";)
注:"$" 操作符之后定義變量;
"?" 和 "-"可用于變量修改操作符;
$var - 定義變量。
$(var) - 用變量"var"的值替換。
$(var:-default) - 用變量"var"的值替換,如果"var"沒有定義用"default"替換。
$(var:?message) - 用變量"var"的值替換或打印出錯誤消息"message"然后退出。
例如:
var MY_NET $(MY_NET:-192.168.1.0/24)
log tcp any any -> $(MY_NET:?MY_NET is undefined!) 23
端口號:
端口號可以用幾種方法表示,包括"any"端口、靜態端口定義、范圍、以及通過否定操作符。
靜態端口定義表示一個單個端口號,例如111表示portmapper,23表示telnet,80表示http等等。端口范圍用范圍操作符":"表示。范圍操作符可以有數種使用方法,如下所示:
log udp any any -> 192.168.1.0/24 1:1024
記錄來自任何端口的,目標端口范圍在1到1024的udp流
log tcp any any -> 192.168.1.0/24 :6000
記錄來自任何端口,目標端口小于等于6000的tcp流
log tcp any :1024 -> 192.168.1.0/24 500:
記錄來自任何小于等于1024的特權端口,目標端口大于等于500的tcp流
方向操作符:
方向操作符"->"表示規則所施加的流的方向。方向操作符左邊的ip地址和端口號被認為是流來自的源主機,方向操作符右邊的ip地址和端口信息是目標主機,還有一個雙向操作符"<>"。
2. 規則選項:
規則選項組成了snort入侵檢測引擎的核心,既易用又強大還靈活。所有的snort規則選項用分號";"隔開。規則選項關鍵字和它們的參數用冒號":"分開。例如:
- msg - 在報警和包日志中打印一個消息。
- flags -檢查tcp flags的值。
- content - 在包的凈荷中搜索指定的樣式。
Content關鍵字的選項數據比較復雜;它可以包含混合的文本和二進制數據。二進制數據一般包含在管道符號中("|"),表示為字節碼(bytecode)。字節碼把二進制數據表示為16進制數字,是描述復雜二進制數據的好方法。例如:content: "|90C8 C0FF FFFF|/bin/sh";
字符: ; \ "
在content選項內容中出現時必須被轉義(有兩個方法:1.用前導“\”字符 2. 使用字節的二進制表示方式,比如用“|3A|”表示“:”):
內容匹配項的默認是區分大小寫的; - offset - content選項的修飾符,設定開始搜索的位置 。
- depth - content選項的修飾符,設定搜索的最大深度。
- nocase - 指定對content字符串大小寫不敏感。
- distance - content選項的修飾符,設定模式匹配間的最小間距;
distance關鍵字是content關鍵字的一個修飾詞,確信在使用content時模式匹配間至少有N個字節存在。它被設計成在規則選項中和其他選項聯合使用。
格式:distance: ;
例子:
alert tcp any any -> any any (content: "2 Patterns"; content: "ABCDE"; content: "EFGH"; distance: 1;)
- within - content選項的修飾符,設定模式匹配間的最大間距;
within關鍵字是content關鍵字的一個修飾詞,確保在使用content時模式匹配間至多有N個字節存在。它被設計成在規則選項中和distance選項聯合使用。
格式:within: ;
例子:
alert tcp any any -> any any (content: "2 Patterns"; content: "ABCDE"; content: "EFGH"; within: 10;)
- byte_test - 數字模式匹配。
把數據包凈載中特定位置的字串轉換為數值類型與指定的值進行比較。
格式:byte_test: , , , [[relative],[big],[little],[string],[hex],[dec],[oct]] - bytes_to_convert 從數據包取得的字節數。
- operator 對檢測執行的操作 (<,>,=,!)。
- value 和轉換后的值相測試的值。
- offset 開始處理的字節在負載中的偏移量。
- relative 使用一個相對于上次模式匹配的相對的偏移量。
- big 以網絡字節順序處理數據(缺省)。
- little 以主機字節順序處理數據。
- string 數據包中的數據以字符串形式存儲。
- hex 把字符串數據轉換成十六進制數形式。
- dec 把字符串數據轉換成十進制數形式。
- oct 把字符串數據轉換成八進制數形式。
例子:
alert udp $EXTERNAL_NET any -> $HOME_NET any (msg:"AMD procedure 7 plog overflow "; content: "|00 04 93 F3|"; content: "|00 00 00 07|"; distance: 4; within: 4; byte_test: 4,>, 1000, 20, relative;)
- uricontent - 用于匹配正規化處理后URI字段。
這個關鍵字允許只在一個請求的URI(URL)部分進行搜索匹配。它允許一條規則只搜索請求部分的攻擊,這樣將避免服務數據流的錯誤報警。關于這個關鍵字的參數的描述可以參考content關鍵字部分。這個選項將和HTTP解析器一起工作。(只能搜索第一個“/”后面的內容)。
例如:uricontent:".emf"; - Flow
這個選項要和TCP流重建聯合使用。它允許規則只應用到流量流的某個方向上。這將允許規則只應用到客戶端或者服務器端。這將能把內網客戶端流覽web頁面的數據包和內網服務器所發送的數據包區分開來。這個確定的關鍵字能夠代替標志:A+ 這個標志在顯示已建立的TCP連接時都將被使用。
選項:
to_client 觸發上服務器從A到B的響應。
to_server 觸發客戶端上從A到B的請求。
from_client 觸發客戶端上從A到B的請求。
from_server 觸發服務器上從A到B的響應。
established 只觸發已經建立的TCP連接。
stateless 不管流處理器的狀態都觸發(這對處理那些能引起機器崩潰的數據包很有用。
no_stream 不在重建的流數據包上觸發。
only_stream 只在重建的流數據包上觸發。
格式:flow:[to_client|to_server|from_client|from_server|established|stateless|no_stream|only_stream]
reference - 外部攻擊參考ids。
這個關鍵字允許規則包含一個外面的攻擊識別系統。這個插件目前支持幾種特定的系統,它和支持唯一的URL一樣好。這些插件被輸出插件用來提供一個關于產生報警的額外信息的連接。 - sid - snort規則id。
這個關鍵字被用來識別snort規則的唯一性。這個信息允許輸出插件很容易的識別規則的ID號。
sid 的范圍是如下分配的:
<100 保留做將來使用
100-1000,000 包含在snort發布包中
1000,000 作為本地規則使用
- rev - 規則版本號。
這個關鍵字是被用來識別規則修改的。修改,隨同snort規則ID,允許簽名和描述被較新的信息替換。 - classtype - 規則類別標識。
這個關鍵字把報警分成不同的攻擊類。通過使用這個關鍵字和使用優先級,用戶可以指定規則類中每個類型所具有的優先級。 - pcre:
pcre選項允許用戶使用與PERL語言相兼容的正則表達式。相關正則表達式的具體細節參看PCRE的Web站點:http://www.pcre.org
pcre:[!]"(/<regex>/|m<delim><regex><delim>)[ismxAEGRUB]";
在表達式后的修飾符設置編譯正則表達式的一些標志。
Perl兼容的修飾符:
|i| 對大小不敏感
|s| 在點轉義符號中包含換行符, 一般情況下被匹配的緩沖區是作為一個大字符串
|m| 的,和$分別匹配串頭和串尾。當設置了m修飾符,和$匹配跟緊跟換行符和緊先導于換行符的情況
|x| 要匹配的模式中的空格符被忽略,除非是被轉義過的或在一個字符集中。
PCRE兼容的修飾符:
|A| 模式必須在緩沖區的開頭匹配到(同^) 設置指定的$必須匹配到緩沖區末尾。如果不用E |
|E| 修飾符,$則可能只匹配到串尾之前換行符。
|G| 在默認情況下不使用“貪婪”模式,只有在模式后面跟了“?”字符的情況下貪婪。
Snort特定的修飾符:
|R| 此匹配相對于前一個匹配成功串尾開始(類似于distance:0)
|U| 匹配解碼后的URI緩沖區(類似于uricontent
|B| 不使用解碼后的緩沖區(類似于rawbytes)
修飾符R和B不能同時使用。
例如:alert ip any any -> any any (pcre:"/BLAH/i";)
例子:
alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"WEB-CLIENT PNG large colour depth download attempt"; flow:from_server,established; content:"|89|PNG|0D 0A 1A 0A|"; content:"IHDR"; within:8; byte_test:1,>,16,8,relative;classtype:attempted-user; sid:3134; rev:3;reference:url,www.microsoft.com/technet/security/bulletin/MS05-009.mspx; )
alert tcp $EXTERNAL_NET any -> $HOME_NET 139 (msg:"NETBIOS SMB Trans Max Param/Count DOS attempt"; flow:established,to_server; content:"|00|"; depth:1; content:"|FF|SMB%"; within:5; distance:3; byte_test:1,!&,128,6,relative; pcre:"/^.{27}/sR"; content:"|00 00 00 00|"; within:4; distance:5;reference:url,www.corest.com/common/showdoc.php?idx=262;classtype:protocol-command-decode; sid:2101; rev:15;)
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"SPYWARE-PUT Hijacker shop at home select installation in progress"; flow:to_server,established; uricontent:"GRInstallCL.asp"; nocase; uricontent:"E="; nocase; uricontent:"MID="; nocase; uricontent:"Refer="; nocase; uricontent:"WGR="; nocase; uricontent:"Prev="; nocase; uricontent:"sGUID="; nocase; classtype:misc-activity; sid:5810; rev:1;)
正則表達式元字符的解釋:
\: 轉移字符,將后一個字符標記為一個特殊字符
^:匹配輸入字串的開始位置
$:匹配輸入字串的結束位置
*:匹配前面的子表達式0次或多次
+:匹配前面的子表達式1次或多次
?:匹配前面的子表達式0次或1次
{n,m}:匹配至少n次,至多m次
.:匹配到除"\n"之外的所有單個字符
[]:表示一個字符集,可以單個列出,如[amk$];也可以加一個"-"表示一個字符范圍,如[a-z];匹配任意一個字符即可;也可以用補集來匹配不在區間范圍內的字符。其做法是把""作為類別的首個字符;其它地方的""只會簡單匹配 ""字符本身,例如[5] 將匹配除 "5" 之外的任意字符。
例如:
pcre:"/X-Mailer\x3A[\r\n]*mPOP\s+Web-Mail/smi";
pcre:"/Host\x3A[\r\n]*e2give.com/smi";
pcre:"/User-Agent\x3A[\r\n]*NSISDL/smi";
pcre:"/Host\x3A[\r\n]*push\x2Ecom/smi";
...
注:\x 后為十六進制轉義值
\r 匹配一個回車符
\n 匹配一個換行符
\s 匹配任何空白字符
\d 匹配任何十進制數;它相當于類 [0-9]。
\D 匹配任何非數字字符;它相當于類 [^0-9]。
\s 匹配任何空白字符;它相當于類 [ \t\n\r\f\v]。
\S 匹配任何非空白字符;它相當于類 [^ \t\n\r\f\v]。
\w 匹配任何字母數字字符;它相當于類 [a-zA-Z0-9_]。
\W 匹配任何非字母數字字符;它相當于類 [^a-zA-Z0-9_]。
摘自百度文庫