检测可疑流量
随着今年年初备受期待的 Linux 2.4.0 内核的发布,GNU/Linux 在迈向企业级操作系统领域方面获得了重大推动。自 2.2.x 系列以来,内核的多个领域都得到了改进,其中最重要的就是防火墙代码。2.4.x 内核系列中的 Netfilter 取代了 2.2.x 系列中旧的 ipchains 防火墙代码,并融入了企业级防火墙所需的许多功能,例如状态检测、DoS 防护/速率限制、网络地址转换 (NAT)、MAC 地址过滤,以及最重要的,基于 TCP 标志的任意组合的 TCP 数据包过滤和日志记录。相比之下,ipchains(除了不是状态检测等之外)有一个令人遗憾的限制,即只能区分两种类型的 TCP 数据包:设置了 SYN 标志的数据包和未设置 SYN 标志的数据包。Netfilter 区分任意 TCP 标志组合的能力使得可以检测到高级端口扫描,例如那些可以通过 nmap 轻松利用针对机器的扫描。首先,我们需要了解一些关于 nmap 的背景知识,以便说明高级端口扫描的工作原理以及如何检测它们。
nmap 是世界上最著名的端口扫描器,它结合了许多高级端口扫描技术,可用于检测目标机器和/或网络上的开放端口。此外,nmap 还结合了操作系统指纹识别和 TCP 序列号预测(以及其他功能),以提供比仅通过确定目标机器上的哪些端口是开放的所能收集到的更好的侦察信息。nmap 支持的三种特别有趣的 TCP 扫描模式是 FIN、NULL 和 XMAS 扫描。在正常的 TCP 流量中,FIN 数据包(或设置了 FIN 标志的数据包)可以由 TCP 连接的任一端发送,表明会话已结束,或者更准确地说,没有更多数据要发送。FIN 扫描的工作原理是,发送到开放 TCP 端口的孤立 FIN 数据包(即,尚未成为现有 TCP 会话一部分的数据包)不应被确认。但是,如果将此类数据包发送到关闭的端口,则正常的未过滤 TCP 堆栈应使用 RST 数据包进行响应。因此,为了使用 FIN 数据包扫描主机,nmap 只需向每个目标端口发送一个 FIN 数据包,并等待 RST 数据包涓涓细流般返回。不使用 RST 响应的端口是开放的(或被防火墙过滤)。NULL 和 XMAS 扫描的功能类似,但 XMAS 扫描不仅设置 FIN 标志,还设置 URG 和 PSH 标志,而 NULL 扫描使用没有任何标志设置的 TCP 数据包。
设置安全防火墙的基本原则是采用默认拒绝姿态,其中所有未被防火墙明确允许的流量都将被拒绝或拒绝。此外,应将防火墙配置为将任何未经授权的数据包记录到日志文件中,以供系统管理员或自动化日志文件监视器(如 psad)进行分析。
有关在您的系统上运行 iptables 的更多信息,我强烈推荐 Rusty Russell 的“Netfilter HOWTO”,可在 netfilter.samba.org 上获取。
# iptables -L Chain INPUT (policy ACCEPT) target prot source destination ACCEPT all anywhere anywhere state RELATED,ESTABLISHED ACCEPT TCP anywhere anywhere TCP dpt:ssh flags:FIN, SYN,RST,PSH,ACK,URG/SYN ACCEPT TCP anywhere anywhere TCP dpt:www flags:FIN, SYN,RST,PSH,ACK,URG/SYN LOG TCP anywhere anywhere LOG level warning prefix `DENY ' DROP TCP anywhere anywhere
这样的 iptables 策略是否会阻止端口扫描?首先,发送到 80 或 22 以外的目标端口的任何 TCP 数据包(无论 TCP 标志如何)都将由规则编号四记录,然后由规则编号五丢弃。这处理了针对 80 和 20 以外的任何 65535 个 TCP 端口的任何类型的嘈杂扫描。那么测试 80 和 22 是否开放的扫描呢?答案是这取决于扫描的类型。规则三和规则四接受设置了 SYN 标志且所有其他标志都已清除的数据包,因此任何仅使用 SYN 数据包的扫描都会成功。此外,任何使用正常的 TCP connect() 系统调用的扫描(如普通的 Web 浏览器或 SSH 客户端将使用的)都将成功,因为规则编号一允许完成三次 TCP 握手。
nmap 通过 -sS(半开放或 SYN 扫描)和 -sT(TCP connect() 扫描)命令行开关支持这两种扫描技术。任何其他不基于到这些端口的合法 TCP 流量的扫描技术都将被阻止和记录。此类扫描包括 nmap 部分中提到的 FIN、XMAS 和 NULL 扫描,以及 SYN/FIN 和 ACK 扫描。
现在我们有理由相信我们的 iptables 防火墙将阻止端口扫描,但我们不应因成功而自满。仅仅阻止扫描是不够的;我们还应尽最大努力检测它们,因为端口扫描可能是更高级攻击的先兆。
端口扫描攻击检测器 (psad) 是一个完全用 Perl 编写的程序,旨在与限制性的 ipchains/iptables 规则集一起工作,以检测 TCP 和 UDP 端口扫描。它具有一组高度可配置的危险阈值(提供合理的默认值)、电子邮件警报、通过动态重新配置 ipchains/iptables 防火墙规则集可选自动阻止攻击性 IP 地址以及详细的警报消息,其中包括源、目标、扫描的端口范围、开始和结束时间、dns 和 whois 查找。对于 iptables 防火墙,psad 利用扩展的日志记录功能来检测高度可疑的扫描,例如 FIN、XMAS 和 NULL,这些扫描很容易通过 nmap 利用针对目标机器。此外,psad 结合了 Snort 入侵检测系统中包含的许多 TCP 和 UDP 签名,以检测针对各种后门程序(例如,EvilFTP、GirlFriend、SubSeven)和 DDoS 工具(mstream、shaft)的扫描和/或流量。psad 是根据 GNU 通用公共许可证发布的自由软件,可从 www.cipherdyne.com 获取。
psad 的基本任务是利用 ipchains 或 iptables 生成的防火墙日志消息来检测可疑的网络流量。为了完成此任务,psad 需要一种有效的方法从防火墙写入 syslog 的日志消息中获取所需的数据。因此,在安装时,psad 在 /var/log/ 目录中创建一个名为 psadfifo 的命名管道,并重新配置 syslogd 以将所有 kern.info 消息写入管道。在 syslog 术语中,ipchains 和 iptables 日志消息都通过 kern 工具以 info 日志级别报告。psad 完成的大部分工作由两个单独的守护程序完成:kmsgsd 和 psad。
kmsgsd 守护程序相对简单,其唯一职责是打开 psadfifo 管道,读取任何指示 ipchains/iptables 已拒绝或拒绝数据包的 kern.info 消息,并将所有此类消息写入 psad 数据文件 /var/log/psad/fwdata。由于 kmsgsd 中包含的正则表达式仅查找已被拒绝或拒绝的数据包,因此 fwdata 文件为 psad 提供了精简的数据流,其中包含可能仅从安全角度来看具有重要意义的信息。但是,此信息的完整性和详细程度仅取决于防火墙的生成能力,因此需要尽可能严格的防火墙规则集。
iptables 不支持任何丢弃或拒绝数据包的规则的日志记录选项。不过,一个简单的解决方案是在任何丢弃规则之前加上一个使用 --log-prefix 选项的日志记录规则。请参阅 simplefirewall.sh 的规则编号四。列表 1 中的 kmsgsd 代码片段说明了如何从 psadfifo 命名管道读取防火墙消息,以及如何使用正则表达式来匹配 ipchains 或 iptables 生成的任何丢弃的数据包消息。
一旦 fwdata 文件填充了已被拒绝的数据包,psad 守护程序就有责任分析并判断数据包是否构成端口扫描或其他可疑网络流量。psad 通过定期检查 fwdata 中指示数据包最近被防火墙拒绝的新行来完成此操作。端口扫描根据在固定时间内被拒绝的数据包数量被分配从一到五的危险级别。但是,扫描也可能根据它是否与 psad_signatures 文件中包含的任何一组恶意签名匹配而被分配危险级别。此类签名的示例包括“NMAP 指纹尝试”(对于任何设置了 URG、PSH、SYN 和 FIN 标志的数据包)和“DDoS - mstream 客户端到处理程序”(对于目标端口为 15104 的 SYN 数据包)。
在端口扫描达到预定的危险阈值后,将发送一封电子邮件,其中包含以下几条信息:扫描的源 IP、目标 IP、上次扫描间隔内新扫描的端口范围(TCP 或 UDP)、自扫描开始以来扫描的完整端口范围(TCP 和 UDP)、开始和结束时间、psad 分配的危险级别、反向 dns 信息、扫描中使用的 TCP 标志(以及将生成此类扫描的相应 nmap 命令行选项)和 whois 信息。
psad 没有求助于任何 Linux 发行版上默认安装的 whois 客户端,而是使用了 Marco d'Itri 编写的出色的 whois 客户端。该客户端的优势在于可以准确地查询几乎任何扫描源 IP 地址的正确 whois 数据库。psad 还具有重新配置 ipchains/iptables 规则集以阻止任何已达到足够高危险阈值的 IP 地址的功能。此功能默认情况下处于禁用状态,因为许多管理员不希望网络上的志愿者管理员能够通过从网站的 IP 地址欺骗恶意数据包来强制防火墙阻止访问他们选择的任何网站。
但是,有些管理员喜欢设置端口扫描或其他恶意流量的高阈值,并让 psad 自动阻止它。请注意,psad 分析的任何流量都已被防火墙阻止。但是,如果扫描达到足够高的阈值,则自动阻止功能将阻止来自攻击源 IP 的所有流量,因为管理员可能不希望这样的 IP 向本地网络发送任何数据包,无论是否合法。
psad 还包括一个信号处理程序,这样,如果向 psad 进程发送 USR1 信号,psad 将调用 Data::Dumper 将 %Scan 哈希的内容转储到 /var/log/psad/scan_hash.$$ 文件中,其中 $$ 表示 psad 进程的 pid。%Scan 哈希是主要的 psad 数据结构,包含所有扫描信息,因此转储其内容既可以作为捕获扫描数据记录的方式,也可以作为扩展 psad 功能集的调试工具。psad 是一个正在进行中的工作,待办事项清单上有很多内容,但它正在积极开发中,并且版本发布周期也相对较短。
列表 2 中的 ipchains 消息是由 nmap 对 TCP 端口 79 到 81 进行 XMAS 扫描生成的。回想一下,XMAS 扫描设置了 FIN、URG 和 PSH 标志。首先列出 nmap 命令和输出,然后列出相应的 ipchains 输出。请注意,ipchains 没有提及设置了哪些 TCP 标志。
列表 3. 来自与 Web 服务器的 TCP 会话的 iptables 消息
现在我们执行相同的 nmap 扫描(nmap 命令行和输出与上面的 ipchains 示例相同,因此不再重复),并显示相应的 iptables 输出(请参阅列表 3)。这一次,我们可以清楚地看到扫描中使用的数据包中设置了 FIN、URG 和 PSH 标志。

Michael Rash 在马里兰州安纳波利斯的 ASP 公司担任高级安全工程师。他拥有马里兰大学应用数学硕士学位,自 1998 年以来一直在摆弄 Linux。可以通过 mbr@cipherdyne.com 与他联系。