一. Snort 简介
Snort 是世界上最重要的开源入侵防御系统 (IPS)。 Snort IPS 使用一系列规则来帮助定义恶意网络活动,并使用这些规则来查找与其匹配的数据包并为用户生成警报。Snort 也可以内联部署来阻止这些数据包。 Snort 有三个主要用途:作为数据包嗅探器(如 tcpdump)、作为数据包记录器 — 这对于网络流量调试很有用,或者可以用作成熟的网络入侵防御系统。 Snort 可以下载并配置用于个人和商业用途。
Snort - Network Intrusion Detection & Prevention System
二. 安装必要依赖
如果你已经构建了Snort,那么你可能有你需要的一切,如果没有,请获取最新:
- cmake to build from source
- daq from https://github.com/snort3/libdaq for packet IO
- dnet from https://github.com/dugsong/libdnet.git for network utility functions
- flex >= 2.6.0 from https://github.com/westes/flex for JavaScript syntax parser
- g++ >= 5 or other C++14 compiler
- hwloc from Portable Hardware Locality (hwloc) for CPU affinity management
- LuaJIT from The LuaJIT Project for configuration and scripting
- OpenSSL from [ Downloads ] - /source/index.html for SHA and MD5 file signatures, the protected_content rule option, and SSL service detection
- pcap from Home | TCPDUMP & LIBPCAP for tcpdump style logging
- pcre from PCRE - Perl Compatible Regular Expressions for regular expression pattern matching
- pkgconfig from pkg-config to locate build dependencies
- zlib from zlib Home Site for decompression
2.1 依赖安装过程
软件名称 | 信息记录 |
cmake | |
daq | libdaq是一款标准的自动工具项目,构建以及安装命令如下: (我在centos 和 ubuntu 上分别测试安装)
./bootstrap 执行前请安装 centos: yum install autoconf automake libtool ubuntu: apt install autoconf automake libtool ./configure make make install
执行 ./bootstrap 命令: 报错2.1: ./bootstrap: line 4: autoreconf: command not found 解决: yum install autoconf 报错2.2: autoreconf: failed to run aclocal: No such file or directory 解决: yum install automake 报错2.3:api/Makefile.am:4: error: Libtool library used but 'LIBTOOL' is undefined 解决: yum install libtool 补充: ubuntu在安装过程中遇到下面问题: error: possibly undefined macro: AC_CHECK_HEADERS 解决: apt install pkg-config 执行命令: ./configure centos: 执行结果如下 ubuntu 执行报错: error: Something went wrong bootstrapping makefile fragments for automatic dependency tracking 解决: apt install make 安装后再次执行./configure 结果如下: Q1: 注意: 在安装过程中感觉daq安装较为重要. 在所有依赖安装完毕时,不妨再编译安装一遍daq. 下图和上图显著的不同,就是 build XXX DAO module 构建 yes 的模块多了, 执行命令 make ubuntu: 报错: ../libtool: line 1762: g++: command not found 解决: apt install g++ 报错:ar: gwlb/libdaq_static_gwlb_la-daq_gwlb.o: No such file or directory 重新执行 make clean --> ./bootstrap --> ./configure ---> make ----> make install 执行 make install |
dnet | apt install libdnet 源码编译安装:(推荐) ./configure 执行报错: 解决: 安装check https://github.com/libcheck/check/releases 执行 autoreconf --install 执行 ./configure 执行 make 执行 make install libdnet再次编译:./configure make make install |
flex | apt install libdnet |
g++ | g++ --version |
hwloc | apt install hwloc 编译安装: Portable Hardware Locality (hwloc): Version 2.9 ./configure make make install |
LuaJIT | apt install build-essential make make install |
openssl | 查看版本: openssl version 升级OpenSSL: ./Configure --prefix=/usr/local/ssl --openssldir=/usr/local/ssl make make install 安装完毕,引用新安装的openssl cd /usr/local/ssl/bin ./openssl version 执行此命令查看新安装的openssl 版本,报错如下: ldd ./openssl 打印共享对象的依赖 发现依赖存在问题 (尝试解决 :参考文档: 执行“openssl version“报openssl: /usr/lib/libcrypto.so.3: version `OPENSSL_3.1.0‘ not found (required by_openssl: /lib/x86_64-linux-gnu/libcrypto.so.3: ver-CSDN博客) 再次验证: 同样的操作: 另外执行openssl version 还是显示老版本, 操作如下: mv /usr/bin/openssl /usr/bin/openssl.bak_20230124 ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl 安装完毕 |
pcap | apt install tcpdump 建议编译安装: 编译过程类似 3.3.3.1~2 安装libpacp,tcpdump Home | TCPDUMP & LIBPCAP |
pcre | apt install libpcre3 libpcre3-dev pcre-config --version |
pkgconfig | ./configure 报错: error: Either a previously installed pkg-config or "glib-2.0 >= 2.16" could not be found. Please set GLIB_CFLAGS and GLIB_LIBS to the correct values or pass --with-internal-glib to configure to use the bundled copy. 解决: ./configure --with-internal-glib make make check make install |
zlib | apt-get install zlib1g-dev 查看版本 |
三. 构建Snort
软件包: https://github.com/snort3/snort3/releases
文档: https://github.com/snort3/snort3#documentation
Installing Snort - Snort 3 Rule Writing Guide
3.1 解压snort3-xxx.tar.gz
3.2 ./configure_cmake.sh
3.2.1 执行时,报错: 缺少CMake
解决: apt install cmake
3.2.2 执行时,报错:dnet header not found
解决: 编译安装 libchek、 libdnet
3.2.3 执行时,报错:-- No package 'hwloc' found
解决: 编译安装 hwlow
3.2.4 执行时,报错: Could NOT find OpenSSL
疑惑: OpenSSL 已经安装了
解决: 升级 OpenSSL
还是同样的错误。
按照错误提示,执行 ./configure_cmake.sh --with-openssl=/usr/local/ssl 白色阴影部分显示
根据编译时提示 Could NOT find OpenSSL 的解决方法 - 简书 的提示: 试安装 :apt-get install libssl-dev
3.2.5 执行时,报错:ERROR! Libpcap library/headers
解决: apt install libpcap*
3.2.6 执行时,报错: LIBLZMA_LIBRARY
解决: apt install liblzma-dev 参考文档: ubuntu - cmake error: could NOT find LibLZMA (missing: LIBLZMA_INCLUDE_DIR - Unix & Linux Stack Exchange
3.2.7 执行成功
./configure_cmake.sh --with-openssl=/usr/local/ssl
这个是下面3.3.3报错误后,多个操作后,重新执行 ./configure_cmake.sh --with-openssl=/usr/local/ssl 发现红色模块的变化:出现了pcap等
3.3 安装
3.3.1 进入新创建的构建目录:
cd build
3.3.2 编译安装
make -j $(nproc)
知识补充: nproc nproc(1) - Linux manual page 解释: Print the number of processing units available to the current process, which may be less than the number of online processors. 打印当前进程可用的处理单元数量,该数量可能小于在线处理器的数量
make install
3.3.3 验证安装是否成功
snort -v
执行时,报错: ERROR: Could not find requested DAQ module: pcap
为解决此问题:尝试了下面的安装。期间还出现了sshd 启动失败,重启后无法连接的问题
3.3.3.1尝试编译安装 libpacp
执行 ./configure
报错: error: Neither bison, byacc, nor yacc was found
解决: apt install -y byacc
执行 make
执行 make install
3.3.3.2 编译安装 tapdump (虽然已经用apt 安装了tcpdump)
3.3.3.3 注意事项
注意:当我尝试安装依赖组件时,发现下面的关系,但不知道内部是怎样调用的。
就像下图展示的那样,如果再次安装snort3时,要注意libdap组件的编译时的状态。
3.3.4 再次验证:
执行 snort -v 验证安装是否成功
执行 snort --dap-list 验证您的安装是否具有可用的适当 DAQ
四. 使用说明:
4.1 命令行基础:
查看帮助文档: Command Line Basics - Snort 3 Rule Writing Guide
4.2 获取流量
- libDAQ 是数据采集库,从高层来看,它是“模块”用来与硬件和软件网络数据源进行通信的数据层。
- 用户可以运行 snort --daq-list 来查看那些DAQ模块可供使用
4.3 配置
4.3.1 配置文件:
Snort3 配置 现在全部在Lua中完成,这些配置项会以3中不同的方式被提供给Snort: 通过命令行 、用一个单独的Lua配置文件 或者 用多个Lua配置文件。snort中有很多的不同的配置项可以被调整,但幸运的是,开源Snort附带了一系列标准的配置文件,它可以帮助 snort 用户去快速启动和运行。这些默认文件位于/lua目录下,目前其中 snort.lua 和 snort_defaults.lua文件构成了基础配置。 这个配置是一个去用于构建的优秀模板,它可以被直接插入到snort中以便立即使用。
4.3.2 模块配置:
一个配置的很大部分是开启和调整Snort 模块,在一些高层次上 去控制snort如何处理网络流量,snort包含的那些模块可以去破译原始数据包、执行流量标准化,决定是否应该对一个特别的数据包采取一个指定的操作以及也可以控制如何去记录事件。 Snort具有8中类型不同的模块:
Basic Modules -> handle configuration for basic traffic and rule processing | 应对基础流量和规则处理的配置 |
Codec Modules -> decode protocols and perform anomaly detection | 解码协议并执行异常检测 |
Inspector Modules -> analyze and process protocols | 分析和处理协议 |
IPS Action Modules -> enable custom actions that can be performed when an event occurs | 启用当事件发生时,可以执行自定义操作 |
IPS Option Modules -> options set in Snort rules to set the detection parameters | 设置在Snort规则中的选项,用来配置检测参数 |
Search Engine -> perform pattern matching against packet data to determine which rules to evaluate | 对包数据进行匹配模式,以决定那些规则去评估 |
SO Rule Modules -> perform detection not attainable with the existing IPS options | 只有在现有的IPS选项无法实现时,才进行检测 |
Logger Modules -> control the output of events and packet data | 控制事件和数据包的输出 |
用 “ --help-modules ”命令去显示一个关于所有snort3模块的简短描述和列表
snort --help-modules
如果一个模块被初始化为一张空表,意味着该模块正使用着它的默认设置,我们可以借助 “--help-config”参数去观察这些默认配置项
snort --help-config moudle_name
这个默认的配置文件 snort.lua可以开启以及配置由snort依赖的许多核心模块,鼓励用户去仔细检查那个文件并使用”--help-module“和”--help-config“的snort 命令器了解那些模块
4.3.3 传递配置文件到snort:
默认情况下,snort不会去查找一个特别的配置文件,但是可以使用 “-c” 参数,将指定的文件传递给snort;
snort -c $my_path/lua/snort.lua
这个命令会简单的校验被提供的配置文件,如果一切都正常的话,命令的输出将会包含 一条“Snort已经成功验证配置 ”的消息。
4.3.4 通过命令行调整Lua配置:
有时候,规则编写者想要用一个指定的配置做实验以观察它如何影响检测结果。 幸运的是,Snort 3提供了这样的功能,可以从命令行直接地运行一次性的自定义lua配置,通过使用 “--lua”标记,后面跟着一串由引号‘’ 包含的字符串,该字符串包含要去设置的指定lua配置。
例如: 下面的 “--lua” 命令 把 来自于“ips”模块的 enable_builtin_rules 布尔值 设置为true:
snort -c $my_path/lua/snort.lua -R local.rules --lua 'ips.enable_builtin_rules = true'
注意,上面的“--lua” 的参数使用 ’ . ‘ 符号去引用任何现存的 “ips” 配置。该配置位于snort的配置文件中。然而,通过使用 “{ }” 花括号代替 “.” 符号,用户可以覆盖一个已给模块的配置。
例如,下面的参数将用指定的参数覆盖任何现有的ips配置:
$ snort -c $my_path/lua/snort.lua -R local.rules \
--lua 'ips = { enable_builtin_rules = true }'
上面的例子把“ips”设置回它的默认配置,但然后也会把 “enable_builtin_rules” 设置为 “true”.
4.3.5 Snort2Lua
Configuration - Snort 3 Rule Writing Guide
转换配置文件
对于那些从Snort 2迁移过来并且有一个可用的2.x配置文件的用户,构建Snort 3还会生成一个名为snort2lua的二进制文件。这个二进制文件可以读取用户旧的Snort 2配置,并输出一个可以被插入到Snort 3中的配置。
通过 -c 选项指向 snort2 配置文件,去调用那个二进制文件:
snort2lua -c snort.conf
如果在转换过程中出现任何错误,他们将会被放置在当前目录下的 snort.rej的文件中,一旦所有的错误都被处理了,snort2lua将会输出一个snort.lua文件,然后该文件会直接传递给snort3
4.4 Snort 规则
snort 的核心是入侵检测系统(IDS)和入侵防御系统(IPS),这意味着它有能力检测网络入侵,也能防御。配置会告诉snort如何去处理网络流量。规则决定了snort是否对特别的数据包采取行动。
通过ips模块,snort 规则可以直接被放置在某个Lua配置文件里。但对大部分规则而言,它们将存在于不同的以“.rules”结尾的文件中,这些文件被包含“included”。举例:我们有一个 “malware.rules” 文件,该文件和我们的Lua配置文件在同一目录下,我们可以 像下面那样,“include” 引用那些规则文件。
ips = { include = 'malware.rules' }
如果,用户想要包含多个以".rules"结尾的文件,那么他们可以这样做
ips =
{
rules = [[
include /path/to/rulesfile1.rules
include /path/to/rulesfile2.rules
…
]]
}
或者,在命令行中,把单个规则文件或指向规则目录的路径可以直接被传递给snort。 这是通过对单个规则文件使用 “-R”选项或者通过 “--rule-path”选项传递整个规则目录来完成的,当你需要针对pacp去验证一个或多个规则或者去排除其故障。
举例: 下面的命令将针对bad.pacp中的流量去运行malware.rules中的所有规则。
snort -c $my_path/lua/snort.lua -R malware.rules -r bad.pcap
4.4.1 生成警报
默认情况下,上面的命令将会输出关于指定运行的各种各样统计数据。那些包含 任何已经识别的应用、任何检测事件、被检测服务的类型以及更多的细节。
在以提供的流量上,这个检测事件将会展示有多少个被触发的警报,但是有时候我们想知道更多的信息,
snort 提供了一些不同的 “alert mode” 警报模式选项,这些选项可以在命令行中被设置去调整显示警报的方式。 这些模式涉及 cmg. 此“cmg”会在警报数据包的十六进制内容旁边展示那些告警信息。以及如下所示的几种不同的 “alert_*”模式:
$ snort --help-modules | grep alert
把想要的告警模式附在 “-A” 选项的后面去设置这些模式,以及我们可以通过引用“-q” (quit)选项来只关注警报内容。比如说“cmg”模块将会看起来像这样:
$ snort -q -c $my_path/lua/snort.lua -q -r get.pcap -R local.rules -A cmg
10/14-14:59:14.186063 [**] [1:0:0] "GET request" [**] [Classification: Web Application Attack] [Priority: 1] {TCP} 10.1.2.3:50284 -> 10.9.8.7:80
http_inspect.http_method[3]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
47 45 54 GET
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
http_inspect.http_version[8]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
48 54 54 50 2F 31 2E 31 HTTP/1.1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
http_inspect.http_uri[6]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2F 68 65 6C 6C 6F /hello
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
http_inspect.http_header[78]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
48 6F 73 74 3A 20 61 62 63 69 70 2D 68 6F 73 74 Host: ab cip-host
2E 6C 6F 63 61 6C 0D 0A 55 73 65 72 2D 41 67 65 .local.. User-Age
6E 74 3A 20 61 62 63 69 70 0D 0A 41 63 63 65 70 nt: abci p..Accep
74 2D 4C 61 6E 67 75 61 67 65 3A 20 65 6E 2D 75 t-Langua ge: en-u
73 0D 0A 41 63 63 65 70 74 3A 20 2A 2F 2A s..Accep t: */*
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
alert_talos 是另一个有用的模式,这个模式以一种简单而易于理解的格式去展示警报。
$ snort -q -c $my_path/lua/snort.lua -q -r get.pcap -R local.rules -A alert_talos
##### get.pcap #####
[1:0:0] GET request (alerts: 1)
#####
最后。 一些 关于“alert_*” 的模式是可以自定义的,比如: alert_csv 允许输出不同字段的自定义顺序, 下面的例子使用了“--lua”命令行标记,示范了一个自定义的cvs告警配置。
$ snort -q -c $my_path/lua/snort/lua -r cmd_injection.pcap -R local.rules --lua 'alert_csv = { fields = "action pkt_num gid sid rev msg service src_addr src_port dst_addr dst_port", separator = "," }'
would_block,5,1,1000000,0,"Command injection detected",http,10.1.2.3,50284,10.9.8.7,80
would_block,6,1,1000000,0,"Command injection detected",http,10.1.2.3,50284,10.9.8.7,80
4.4.2 内联测试规则
为了保护网络,确保我们的规则合适地阻止袭击,这很重要,dump DAQ 可以使我们做到这一点,指定 “-Q” 选项去开启内联模式, 以及设置“--daq”为“dump” 会 “dump”转储流量,这些流量 would‘'ve been passed through, 模仿一个真正的内联操作。默认情况下, 这个流量结果将会被转储到一个名为“inline-out.pacp”的文件中。
$ snort3 -Q --daq dump -q -r get.pcap -R local.rules
在上面的例子中, 如果“local.rules” 文件中包含一个 “block” 阻止规则,该规则会被“get.pacp”文件上的一些流量触发。然后inline-out.paco结果文件将只会包含未被阻止的流量。 我们可以使用此功能去测试规则是否正在阻止实际的攻击数据包通过。
4.4.3 将 Snort 2 规则转换为 Snort 3
略.
4.5 Snort Wizard 和 Binder
snort3 有两个重要组件: wizard 和 Binder 。这两个组件会帮助去确定在已给定的流量中最可能的服务,然后引导那些流量到正确的“server inspector”服务检测器" 。下面会进一步解释它们。
4.5.1 Wizard
wizard 会使用被叫做 hexes, spells,以及 curse 的工具去帮助确定存在于已给流中的服务,那三个工具观察流量的不同方面,以便于去帮助识别正在被使用的服务。然而,wizard只会帮助识别服务,它的工作是作出最终决定的应用识别检测器。因此,wizard的主要目标是快速的识别最可能的服务,以便把它交给合适的检测器去完成剩余的工作。
4.5.1.1 Hexes
Hexes 是基于二进制的模式,该模式被用于检测二进制协议 binary protocols,例如:ssl 和 dnp3。 在lua中,hexes 被配置为一系列表,每个表包含一些定义hexes如何操作的键。
这些键包括下面的内容:
service -> 被分配服务的名称
proto -> 扫描的协议 例如:tcp
client_first -> 布尔值,表明这个客户端是否是数据传输的发起者
to_server -> 发送到客户端数据中用于搜索的文件模式列表
to_client -> list of text patterns to search in the data sent to the server
4.5.1.2 Spells
hexes是基于二进制模式的,但是 spells 是基于文本模式的。这意味着它最好被用于文本主导的协议text-dominant protocols,例如:http、 smtp、 sip等等。spell 和 hexs有一样的配置方式,而且它们有一样的键或选项.
4.5.1.3 Curses
Curse 是被C++ state machines构建的,而不是被定义在snort配置中,curse存在于那种不需要少量的字符串又或是十六进制模式的服务中。像 hexes和spells一样,curses 也可以在snort配置中被开启。在snort_defaults.lua中的下行展示内容开启了6种默认的curses算法,这些算法存在于curses.cc中
curses = {'dce_udp', 'dce_tcp', 'dce_smb', 'mms', 's7commplus', 'sslv2'}
通过下面的命令查看可用的curses
snort --help-config wizard | grep curses
4.5.2 Binder
snort3的binder有这样一个特点, 它把网络流量导向一个特别的服务检测器,该检测器是基于 一些流量的检测服务、涉及的端口和网络协议以及使用的网络协议的组合。 用户可以创建这些选项的配置去告知snort那个服务检测器去用到一个已给的网络流上。
这些配置被写成lua表的数组以及被放置在某些snort配置文件中。 那些binder entries 通常包含两个嵌套表,when 和 use。 when表 控制调用操作的条件,那些操作被指定在 user 表中。这有一些不同的binder entries的例子:
使用下面的snort命令可以看见所有可用的binder表参数:
snort --help-module binder
4.6 Snort Twraks 和 Scripts
Tweaks
snort 也提供对配置使用“--weaks”选项去新增额外配置的功能。 举个例子,它可以采用能调整snort检测引擎的策略文件去获得更好的性能或者安全性。
snort3默认带有4个策略调整文件: max_detect、 security、 balanced、connectivity 。 max_detect策略提供最大程度的安全,然而 connectivity 在牺牲一定的安全性上优先考虑了性能和正常运行时间。
或多或少这些调整算是配置扩展, snort.lua 和 snort_defaluts.lua 文件提供了基础策略。tweaks允许进行一组特定的有针对性的更改
为使用一种调整,将要使用的调整策略文件的名称附在命令行选项“--tweaks”的后面。
举例: 为了使用“max_detect”策略,像下面那样运行snort:
snort -c $my_path/lua/snort.lua -R local.rules --tweaks max_detect
还存一个“talos”调整选项,该选项配置snort为一种Tolas分析师最初测试他们自己规则的方式。
snort -c $my_path/lua/snort.lua -R local.rules --tweaks talos
你可以在/lua目录下检查每种调整策略,以便于观察到那种类型的变更
Scripts
Snort3是可扩展的,以便于它为用户提供这种能力去创建自定义LuaJIT脚本去扩展它的功能,在命令行中,使用“--script-path <scripts_path> ”参数 将脚本传递给snort3,然后在snort规则中通过脚本”名称“ (声明在.lua文件中)作为一个规则选项被调用。
4.7 跟踪模块 Trace Module
snort3 也包含“trace” 追踪模块,该模块 在一个非常低的级别下开启记录snort引擎输出。以便去显示信息,比如: rule evaluation tracing 追踪规则评估, buffer dumping 缓冲区转储, Application ID (wizard) tracing 跟踪应用程序id, and much more.
在lua中配置snort跟踪选项。他们还可以被放置在一个tweak调整文件中,该文件被包含在正在使用的配置中,或者直接在在命令行中使用。
通过在命令行中使用“--help-module”参数。我们可以看见各种不同的跟踪模块选项以及可以利用的配置:
snort --help-module trace
五. 规则 Rules
5.1 基础
snort 规则结构
snort的入侵检测防御系统依赖snort规则去保护网络。 这些规则主要有两大部分组成:
- rule header 规则头部
规则头部定义操作,比如:呈现任何匹配的流量,还有协议、网络地址、端口号以及规则应该适用于的流量方向。
- rule body 规则体
规则体部分定义了 与规则相关联的信息以及最重要的是规则匹配需要满足的负载和非负载标准。尽管规则选项不是必要的,但是对于以正确的流量为目标的已给规则是至关重要的。
下面是一个完整的snort3规则,该规则带有正确的规则头部和规则选项定义;
第一个括号之前的文本:属于规则头部, 两个括号之间的内容属于: 规则体;
定义在已给的snort规则的头部中的操作不会被执行,除非规则中所有的单独选项计算结果为TRUE。
snort 注释
规则制定者也可以给他们的规则增加注释,以便于提供额外的内容或者关于规则或规则选项的信息,# 或者 /*...*/