1. 规则或签名要素
协议,源IP,目的IP,源端口,目的端口,数据报方向,IP报文的TTL域, ,IP报文的TOS域, ,IP报文的分片ID域, ,IP报文的option域, ,IP报文的fragbits域(分片比特位),IP 负载的长度,TCP的flags域, ,TCP报文的SEQ域, TCP报文的ACK域,ICMP报文的itype类型域,ICMP报文的icode代码域, ICMP报文的icmp_id回应消息ID域,ICMP报文的icmp_seq回应消息序列号域,PALOAD负载
如果使用SNORT_INLINE版本,可以用的要素是resp,就是入侵响应,可选方式:rst_snd,rst_rcv,rst_all,icmp_net,icmp_host,icmp_port,icmp_all
检测签名和规则编写的时候还要主要协议特征和PAYLOAD的特征位置, 比如offset: 0; depth: 1;这个就是说从PAYLOAD的起始位置开始,长度是1的PAYLOAD作为特征.
数据报方向在NFR的NCODE里面可以这样写:
Filter sample1 tcp(dport:80,client) 相当与从你定义的要保护的子网出去的流量.
Filter sample1 tcp(dport:80,server) 相当与其他网络到达你定义的要保护的子网进来的流量.
在SNORT的规则里flow: to_server 到你要定义的server的流量, flow:from_client是从客户端来的流量, flow还可以指定检测连接的状态的,比如stateless, established等
在NCODE里有*.cfg文件定义的几个数据大家要认识一下:
backend_id=NID-792-002
num_columns=6
column_1_attr=IP_ADDR_SRC #源地址
column_1_type=p_src_ip
column_1_label=Source Address
column_2_attr=PORT_SRC #源端口
column_2_type=p_src_port
column_2_label=Source Port
column_3_attr=IP_ADDR_DST #目的地址
column_3_type=p_dst_ip
column_3_label=Destination Address
column_4_attr=PORT_DST #目的端口
column_4_type=p_dst_port
column_4_label=Destination Port
column_5_attr=REASON
column_5_type=p_string
column_5_label=Reason
column_6_attr=PAYLOAD #数据包的DATA部分
column_6_type=p_string
column_6_label=Additional Data
gui=list
title=PPLive ACITVE
origin=NFR
disposition=enable
version=7
如果你是检测UDP协议特征,你的签名要素要这样写:
"IP_ADDR_SRC", ip.src, #源地址
"PORT_SRC", udp.sport, #UDP协议的源端口
"IP_ADDR_DST", ip.dst, #目的地址
"PORT_DST", udp.dport #UDP协议的目的端口
"IP_PROTO_NUM", 17, #UDP协议号
如果你检测的是TCP协议特征,你的签名要素要这样写:
"IP_ADDR_SRC", tcp.connsrc, #TCP协议的源地址
"IP_ADDR_DST", tcp.conndst, #TCP协议的目的地址
"PORT_SRC", tcp.connsport, #TCP协议的源端口
"PORT_DST", tcp.conndport #TCP协议的目的端口
"IP_PROTO_NUM", 6,#TCP协议号
2. SNORT和NFR签名的一般写法
A) SNORT规则写法
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"BLEEDING-EDGE P2P Direct Connect Traffic (client-server)"; flow:from_client,established; content:"$MyINFO"; offset:0; depth:7; classtype:policy-violation; reference:url,en.wikipedia.org/wiki/Direct_connect_file-sharing_application; sid:2002814; rev:1;)
注释:检测TCP协议,从要保护的本地网络到外部网络的连接,是任意端口到任意端口,即any到any. 方向flow:from_client,匹配payload里的第0位开始,长度是7,是否存在"$MyINFO"
alert tcp any any -> any 4660:4799 (msg: "BLEEDING-EDGE P2P ed2k file request answer"; flow: to_server,established; content:"|e3|"; offset: 0; depth: 1; content:"|00000059|"; offset: 2; depth: 4; reference:url,www.giac.org/practical/GCIH/Ian_Gosling_GCIH.pdf; classtype: policy-violation; sid: 2000333; rev:5; )
注释: 检测TCP协议,从任何网络到任何网络的连接,从任意端口到4660:4799(端口在4660到4799之间),方向是flow: to_server,payload里第一次匹配第0个字节是0xe3,第2次匹配从第2个字节开始,长度是4个字节的"|00000059|"
B) NFR签名写法
检测QQ UDP登陆的签名:qq.nfr
qq_schema = library_schema:new(1, ["time","ip","int", "ip", "int",
"str", "str"], scope()); # schema里记录的参数要和qq.cfg的对应上
RCDR = recorder ("bin/list %c","qq_schema");
#下面是常量定义
QQ_REQUEST[22]=1;#0x16
QQ_REQUEST[23]=1;#0x17
QQ_REQUEST[1]=1;#0x01
QQ_REQUEST[5]=1;#0x05
QQ_REQUEST[6]=1;#0x06
QQ_REQUEST[48]=1;#0x30
QQ_REQUEST[10]=1;#0x0a
QQ_string[22]="qq send info";
QQ_string[23]="qq client recieve info";
QQ_string[1]="qq log out";
QQ_string[5]="qq search user ";
QQ_string[6]="qq get user info ";
QQ_string[48]="qq group operation instruction ";
QQ_string[10]="qq delete good friend ";
#这个是主要的检测函数,针对UDP协议的,目的端口QQ_PORTS是在qq.values里面有的
filter qq udp( dport: QQ_PORTS ) {
if ( substr(udp.blob,0,1) == "\x02"){ #这里跟SNORT的一样,这个用函数
#substr做PAYLOAD的匹配,这里写的是从第0个字节开始,长度为1的包,也就#是第一个字节是0x02
#detect qq login
if ( substr(udp.blob,4,1) == "\x22"){ #这里写的是从第4个字节开始,长度为
#1的包,也就是第一个字节是0x22
$temp1=ulong(udp.blob,7); #这里去出QQ号
alert( source_me, qq_login_alert, #这里是报警的内容,前两个参数在
#qq.acf文件里定义了
ip.src, ip.dst, #在UDP协议检测里必须写上的原和目的的IP
cat("QQ ",$temp1 ," :log in server"), #自定义参数,QQ号
"--AlertDetails", "ALERT_ID", "911-003-001", #报警的ID,最好不要
#和其他签名重复
"ALERT_SEVERITY", "low", #报警的严重层度
"ALERT_IMPACT", "information gathering", #漏洞类型
"ALERT_EVENT_TYPE","logging", #事件类型
"ALERT_ASSESSMENT", "unknown", #事件考评,基本都是unknown
"ALERT_CONFIDENCE", 90, #签名报警的可信度
"IP_ADDR_SRC", ip.src,
"PORT_SRC", udp.sport,
"IP_ADDR_DST", ip.dst,
"PORT_DST", udp.dport,
"$temp1",$temp1,
"$temp2",$temp2);
record packet.sec, ip.src, udp.sport, ip.dst, #做数据报记录的功能,
#如果attack里的inhitit.values开启了record这个签名的功能
#,这里就要录制数据报
udp.sport, "qq client connect to server" ,"N/A" to RCDR;
}
#detect qq request info
$temp1=byte(udp.blob,4);
if(QQ_REQUEST[$temp1]==1){
alert(source_me, qq_request_info,
ip.src, ip.dst,QQ_string[$temp1],
"--AlertDetails",
"ALERT_ID","911-003-002",
"IP_ADDR_SRC", ip.src,
"PORT_SRC", udp.sport,
"IP_ADDR_DST", ip.dst,
"PORT_DST", udp.dport);
record packet.sec, ip.src, udp.sport, ip.dst,
udp.sport, "qq_request_info" ,QQ_string[$temp1] to RCDR;
}
}
}
qq.cfg
backend_id=NID-911-003
num_columns=6
column_1_attr=IP_ADDR_SRC
column_1_type=p_src_ip
column_1_label=Source Address
column_2_attr=PORT_SRC
column_2_type=p_src_port
column_2_label=Source Port
column_3_attr=IP_ADDR_DST
column_3_type=p_dst_ip
column_3_label=Destination Address
column_4_attr=PORT_DST
column_4_type=p_dst_port
column_4_label=Destination Port
column_5_attr=REASON
column_5_type=p_string
column_5_label=Reason
column_6_attr=PAYLOAD
column_6_type=p_string
column_6_label=Additional Data
gui=list
title=QQ ACITVE
origin=NFR
disposition=enable
version=7