据统计,在所有黑客攻击事件中, SYN 攻击是最常见又最容易被利用的一种攻击手法。相信很多人还记得
2000 年 YAHOO 网站遭受的攻击事例,当时黑客利用的就是简单而有效的 SYN 攻击,有些网络蠕虫病毒配合 SYN
攻击造成更大的破坏。本文介绍 SYN 攻击的基本原理、工具及检测方法,并全面探讨 SYN 攻击防范技术。
一、 TCP
握手协议
在 TCP/IP 协议中, TCP 协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送 syn 包 (syn=j) 到服务器,并进入 SYN_SEND
状态,等待服务器确认;
第二次握手:服务器收到 syn 包,必须确认客户的 SYN ( ack=j+1
),同时自己也发送一个 SYN 包( syn=k ),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态;
第三次握手:客户端收到服务器的 SYN + ACK 包,向服务器发送确认包 ACK(ack=k+1)
,此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据,在上述过程中,还有一些重要的概念:
未连接队列:在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的 SYN 包(
syn=j )开设一个条目,该条目表明服务器已收到 SYN
包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于 Syn_RECV
状态,当服务器收到客户的确认包时,删除该条目,服务器进入 ESTABLISHED 状态。
Backlog
参数:表示未连接队列的最大容纳数目。
SYN-ACK 重传次数 服务器发送完 SYN - ACK
包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同。
半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到 SYN
包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为 Timeout 时间、
SYN_RECV 存活时间。
二、 SYN 攻击原理
SYN 攻击属于 DOS 攻击的一种,它利用 TCP 协议缺陷,通过发送大量的半连接请求,耗费 CPU
和内存资源。 SYN 攻击除了能影响主机外,还可以危害路由器、防火墙等网络系统,事实上 SYN
攻击并不管目标是什么系统,只要这些系统打开 TCP 服务就可以实施。从上图可看到,服务器接收到连接请求( syn=j
),将此信息加入未连接队列,并发送请求包给客户( syn=k,ack=j+1 ),此时进入 SYN_RECV
状态。当服务器未收到客户端的确认包时,重发请求包,一直到超时,才将此条目从未连接队列删除。配合 IP 欺骗, SYN
攻击能达到很好的效果,通常,客户端在短时间内伪造大量不存在的 IP 地址,向服务器不断地发送 syn
包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的 SYN
包将长时间占用未连接队列,正常的 SYN 请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。
三、 SYN 攻击工具
SYN 攻击实现起来非常的简单,互联网上有大量现成的 SYN 攻击工具。
1 、 windows 系统下的 SYN 工具
以 synkill.exe 为例,运行工具,选择随机的源地址和源端囗,并填写目标机器地址和 TCP
端囗,激活运行,很快就会发现目标系统运行缓慢。如果攻击效果不明显,可能是目标机器并未开启所填写的 TCP
端囗或者防火墙拒绝访问该端囗,此时可选择允许访问的 TCP 端囗,通常, windows 系统开放 tcp139 端囗, UNIX
系统开放 tcp7 、 21 、 23 等端囗。
四、检测 SYN 攻击
检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源 IP
地址是随机的,基本上可以断定这是一次 SYN 攻击。我们使用系统自带的 netstat 工具来检测 SYN 攻击:
# netstat -n -p TCP
tcp 0 0 10.11.11 .11:23
124.173.152.8:25882 SYN_RECV -
tcp 0 0 10.11.11.11:23
236.15.133.204:2577 SYN_RECV -
tcp 0 0 10.11.11.11:23
127.160.6.129:51748 SYN_RECV -
tcp 0 0 10.11.11.11:23
222.220.13.25:47393 SYN_RECV -
tcp 0 0 10.11.11.11:23
212.200.204.182:60427 SYN_RECV -
tcp 0 0 10.11.11.11:23
232.115.18.38:278 SYN_RECV -
tcp 0 0 10.11.11.11:23
239.116.95.96:5122 SYN_RECV -
tcp 0 0 10.11.11.11:23
236.219.139.207:49162 SYN_RECV -
...
上面是在 LINUX 系统中看到的,很多连接处于 SYN_RECV 状态(在 WINDOWS
系统中是 SYN_RECEIVED 状态),源 IP 地址都是随机的,表明这是一种带有 IP 欺骗的 SYN 攻击。
我们也可以通过下面的命令直接查看在 LINUX 环境下某个端囗的未连接队列的条目数:
# netstat -n -p TCP | grep SYN_RECV | grep :22 |
wc -l
324
显示 TCP 端囗 22 的未连接数有 324 个,虽然还远达不到系统极限,但应该引起管理员的注意。
五、 SYN 攻击防范技术
关于 SYN
攻击防范技术,人们研究得比较早。归纳起来,主要有两大类,一类是通过防火墙、路由器等过滤网关防护,另一类是通过加固 TCP/IP
协议栈防范 . 但必须清楚的是, SYN 攻击不能完全被阻止,我们所做的是尽可能的减轻 SYN 攻击的危害,除非将 TCP
协议重新设计。
1 、过滤网关防护
这里,过滤网关主要指明防火墙,当然路由器也能成为过滤网关。防火墙部署在不同网络之间,防范外来非法攻击和防止保密信息外泄,它处于客户端和服务器之间,利用它来防护
SYN 攻击能起到很好的效果。过滤网关防护主要包括超时设置, SYN 网关和 SYN 代理三种。
■ 网关超时设置:防火墙设置 SYN
转发超时参数(状态检测的防火墙可在状态表里面设置),该参数远小于服务器的 timeout 时间。当客户端发送完 SYN
包,服务端发送确认包后( SYN + ACK ),防火墙如果在计数器到期时还未收到客户端的确认包( ACK ),则往服务器发送
RST
包,以使服务器从队列中删去该半连接。值得注意的是,网关超时参数设置不宜过小也不宜过大,超时参数设置过小会影响正常的通讯,设置太大,又会影响防范
SYN 攻击的效果,必须根据所处的网络应用环境来设置此参数。
■ SYN 网关: SYN 网关收到客户端的 SYN 包时,直接转发给服务器; SYN 网关收到服务器的
SYN/ACK 包后,将该包转发给客户端,同时以客户端的名义给服务器发 ACK
确认包。此时服务器由半连接状态进入连接状态。当客户端确认包到达时,如果有数据则转发,否则丢弃。事实上,服务器除了维持半连接队列外,还要有一个连接队列,如果发生
SYN 攻击时,将使连接队列数目增加,但一般服务器所能承受的连接数量比半连接数量大得多,所以这种方法能有效地减轻对服务器的攻击。
■ SYN 代理:当客户端 SYN 包到达过滤网关时, SYN 代理并不转发 SYN
包,而是以服务器的名义主动回复 SYN/ACK 包给客户,如果收到客户的 ACK 包,表明这是正常的访问,此时防火墙向服务器发送
ACK 包并完成三次握手。 SYN 代理事实上代替了服务器去处理 SYN 攻击,此时要求过滤网关自身具有很强的防范 SYN
攻击能力。
2 、加固 tcp/ip 协议栈
防范 SYN 攻击的另一项主要技术是调整 tcp/ip 协议栈,修改 tcp 协议实现。主要方法有
SynAttackProtect 保护机制、 SYN cookies 技术、增加最大半连接和缩短超时时间等。 tcp/ip
协议栈的调整可能会引起某些功能的受限,管理员应该在进行充分了解和测试的前提下进行此项工作。
■ SynAttackProtect 机制
为防范 SYN 攻击, win2000 系统的 tcp/ip 协议栈内嵌了
SynAttackProtect 机制, Win2003 系统也采用此机制。 SynAttackProtect 机制是通过关闭某些
socket 选项,增加额外的连接指示和减少超时时间,使系统能处理更多的 SYN 连接,以达到防范 SYN 攻击的目的。默认情况下,
Win2000 操作系统并不支持 SynAttackProtect 保护机制,需要在注册表以下位置增加
SynAttackProtect 键值:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
当 SynAttackProtect 值(如无特别说明,本文提到的注册表键值都为十六进制)为 0
或不设置时,系统不受 SynAttackProtect 保护。
当 SynAttackProtect 值为 1 时,系统通过减少重传次数和延迟未连接时路由缓冲项(
route cache entry )防范 SYN 攻击。
当 SynAttackProtect 值为 2 时( Microsoft
推荐使用此值),系统不仅使用 backlog 队列,还使用附加的半连接指示,以此来处理更多的 SYN 连接,使用此键值时,
tcp/ip 的 TCPInitialRTT 、 window size 和可滑动窗囗将被禁止。
我们应该知道,平时,系统是不启用 SynAttackProtect 机制的,仅在检测到 SYN
攻击时,才启用,并调整 tcp/ip 协议栈。那么系统是如何检测 SYN 攻击发生的呢?事实上,系统根据
TcpMaxHalfOpen,TcpMaxHalfOpenRetried 和 TcpMaxPortsExhausted
三个参数判断是否遭受 SYN 攻击。
TcpMaxHalfOpen 表示能同时处理的最大半连接数,如果超过此值,系统认为正处于 SYN
攻击中。 Win2000 server 默认值为 100 , Win2000 Advanced server 为 500 。
TcpMaxHalfOpenRetried 定义了保存在 backlog
队列且重传过的半连接数,如果超过此值,系统自动启动 SynAttackProtect 机制。 Win2000 server 默认值为
80 , Win2000 Advanced server 为 400 。
TcpMaxPortsExhausted 是指系统拒绝的 SYN 请求包的数量,默认是 5 。
如果想调整以上参数的默认值,可以在注册表里修改(位置与 SynAttackProtect 相同)
■ SYN cookies 技术
我们知道, TCP 协议开辟了一个比较大的内存空间 backlog 队列来存储半连接条目,当 SYN
请求不断增加,并这个空间,致使系统丢弃 SYN 连接。为使半连接队列被塞满的情况下,服务器仍能处理新到的 SYN 请求, SYN
cookies 技术被设计出来。
SYN cookies 应用于 linux 、 FreeBSD 等操作系统,当半连接队列满时, SYN
cookies 并不丢弃 SYN 请求,而是通过加密技术来标识半连接状态。
在 TCP 实现中,当收到客户端的 SYN 请求时,服务器需要回复 SYN + ACK
包给客户端,客户端也要发送确认包给服务器。通常,服务器的初始序列号由服务器按照一定的规律计算得到或采用随机数,但在 SYN
cookies 中,服务器的初始序列号是通过对客户端 IP 地址、客户端端囗、服务器 IP
地址和服务器端囗以及其他一些安全数值等要素进行 hash 运算,加密得到的,称之为 cookie 。当服务器遭受 SYN 攻击使得
backlog 队列满时,服务器并不拒绝新的 SYN 请求,而是回复 cookie (回复包的 SYN 序列号)给客户端,
如果收到客户端的 ACK 包,服务器将客户端的 ACK 序列号减去 1 得到 cookie 比较值,并将上述要素进行一次 hash
运算,看看是否等于此 cookie 。如果相等,直接完成三次握手(注意:此时并不用查看此连接是否属于 backlog 队列)。
在 RedHat linux 中,启用 SYN cookies
是通过在启动环境中设置以下命令来完成:
# echo 1 > /proc/sys/net/ipv4/tcp_syncookies
■ 增加最大半连接数
大量的 SYN 请求导致未连接队列被塞满,使正常的 TCP
连接无法顺利完成三次握手,通过增大未连接队列空间可以缓解这种压力。当然 backlog
队列需要占用大量的内存资源,不能被无限的扩大。
WIN2000 :除了上面介绍的 TcpMaxHalfOpen,
TcpMaxHalfOpenRetried 参数外, WIN2000 操作系统可以通过设置动态 backlog(dynamic
backlog) 来增大系统所能容纳的最大半连接数,配置动态 backlog 由 AFD.SYS 驱动完成, AFD.SYS
是一种内核级的驱动,用于支持基于 window socket 的应用程序,比如 ftp 、 telnet 等。 AFD.SYS
在注册表的位置:
HKLM\System\CurrentControlSet\Services\AFD\ParametersEnableDynamicBacklog
值为 1 时,表示启用动态 backlog ,可以修改最大半连接数。
MinimumDynamicBacklog 表示半连接队列为单个 TCP 端囗分配的最小空闲连接数,当该
TCP 端囗在 backlog 队列的空闲连接小于此临界值时,系统为此端囗自动启用扩展的空闲连接(
DynamicBacklogGrowthDelta ), Microsoft 推荐该值为 20 。
MaximumDynamicBacklog
是当前活动的半连接和空闲连接的和,当此和超过某个临界值时,系统拒绝 SYN 包, Microsoft 推荐
MaximumDynamicBacklog 值不得超过 2000 。
DynamicBacklogGrowthDelta 值是指扩展的空闲连接数,此连接数并不计算在
MaximumDynamicBacklog 内,当半连接队列为某个 TCP 端囗分配的空闲连接小于
MinimumDynamicBacklog 时,系统自动分配 DynamicBacklogGrowthDelta
所定义的空闲连接空间,以使该 TCP 端囗能处理更多的半连接。 Microsoft 推荐该值为 10 。
LINUX : Linux 用变量 tcp_max_syn_backlog 定义 backlog
队列容纳的最大半连接数。在 Redhat 7.3 中,该变量的值默认为 256 ,这个值是远远不够的,一次强度不大的 SYN
攻击就能使半连接队列占满。我们可以通过以下命令修改此变量的值:
# sysctl -w net.ipv4.tcp_max_syn_backlog="2048"
Sun Solaris Sun Solaris 用变量 tcp_conn_req_max_q0
来定义最大半连接数,在 Sun Solaris 8 中,该值默认为 1024 ,可以通过 add 命令改变这个值:
# ndd -set /dev/tcp tcp_conn_req_max_q0 2048
HP-UX : HP-UX 用变量 tcp_syn_rcvd_max 来定义最大半连接数,在 HP-UX
11.00 中,该值默认为 500 ,可以通过 ndd 命令改变默认值:
# ndd -set /dev/tcp tcp_syn_rcvd_max 2048
■ 缩短超时时间
上文提到,通过增大 backlog 队列能防范 SYN 攻击;另外减少超时时间也使系统能处理更多的
SYN 请求。我们知道, timeout
超时时间,也即半连接存活时间,是系统所有重传次数等待的超时时间总和,这个值越大,半连接数占用 backlog
队列的时间就越长,系统能处理的 SYN
请求就越少。为缩短超时时间,可以通过缩短重传超时时间(一般是第一次重传超时时间)和减少重传次数来实现。
Win2000 第一次重传之前等待时间默认为 3 秒,为改变此默认值,可以通过修改网络接囗在注册表里的
TcpInitialRtt 注册值来完成。重传次数由 TcpMaxConnectResponseRetransmissions
来定义,注册表的位置是:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters registry
key 。
当然我们也可以把重传次数设置为 0 次,这样服务器如果在 3 秒内还未收到 ack 确认包就自动从
backlog 队列中删除该连接条目。
LINUX : Redhat 使用变量 tcp_synack_retries 定义重传次数,其默认值是
5 次,总超时时间需要 3 分钟。
Sun Solaris Solaris 默认的重传次数是 3 次,总超时时间为 3 分钟,可以通过
ndd 命令修改这些默认值。
【本站声明】本站刊载的部分内容全部来源互联网,对于此类文章本站仅提供交流平台,不为其版权负责。如涉及侵犯您的知识产权的文章,请联系我们,我们将尽快做出更正。并向您表示感谢!同时特别感谢对本站所有支持的网友。