SYN攻击(DDOS攻击的一种)

SYN攻击是黑客攻击的手段。SYN洪泛攻击的基础是依靠TCP创建链接时三次握手的设计。第三个数据包验证链接发起人在第一次请求中使用的源IP地址上具备接受数据包的能力,即其返回是可达的。

SYN攻击概述

编辑
据统计,在全部 黑客攻击事件中,SYN攻击是最多见又最容易被利用的一种攻击手法。相信不少人还记得2000年YAHOO网站遭受的攻击事例,当时黑客利用的就是简单而有效的SYN攻击,有些网络蠕虫病毒配合SYN攻击形成更大的破坏。本文介绍SYN攻击的基本原理、工具及检测方法,并全面探讨SYN攻击防范技术。

1、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存活时间。 [1]  

2、SYN攻击原理

SYN攻击属于DOS攻击的一种,它利用TCP协议缺陷,经过发送大量的半链接请求,耗费CPU和内存资源。SYN攻击除了能影响主机外,还能够危害路由器、防火墙等网络系统,事实上SYN攻击并无论目标是什么系统,只要这些系统打开TCP服务就能够实施。从上图可看到,服务器接收到链接请求(syn=j),将此信息加入未链接队列,并发送请求包给客户(syn=k,ack=j+1),此时进入SYN_RECV状态。当服务器未收到客户端的确认包时,重发请求包,一直到超时,才将此条目从未链接队列删除。配合IP欺骗,SYN攻击能达到很好的效果,一般,客户端在短期内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,因为源地址是不存在的,服务器须要不断的重发直至超时,这些伪造的SYN包将长时间占用未链接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引发网络堵塞甚至系统瘫痪。 3、SYN攻击工具
SYN攻击实现起来很是的简单,互联网上有大量现成的SYN攻击工具。 [1]  

3、windows系统下的SYN工具

以synkill.exe为例,运行工具,选择随机的源地址和源端囗,并填写目标机器地址和TCP端囗,激活运行,很快就会发现目标系统运行缓慢。若是攻击效果不明显,多是目标机器并未开启所填写的TCP端囗或者防火墙拒绝访问该端囗,此时可选择容许访问的TCP端囗,一般,windows系统开放tcp139端囗,UNIX系统开放tcp七、2一、23等端囗。 [1]  

4、检测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个,虽然还远达不到系统极限,但应该引发管理员的注意。

5、SYN攻击防范技术

关于SYN攻击防范技术,人们研究得比较早。概括起来,主要有两大类,一类是经过防火墙、路由器等过滤网关防御,另外一类是经过加固TCP/IP协议栈防范.但必须清楚的是,SYN攻击不能彻底被阻止,咱们所作的是尽量的减轻SYN攻击的危害,除非将TCP协议从新设计。
一、过滤网关防御
这里,过滤网关主要指明防火墙,固然路由器也能成为过滤网关。防火墙部署在不一样网络之间,防范外来非法攻击和防止保密信息外泄,它处于客户端和服务器之间,利用它来防御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攻击能力。 二、加固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命令修改这些默认值。