1 /* attack.c
2  * Attacks management core
3  *
4  * Yersinia
5  * By David Barroso <tomac@yersinia.net> and Alfredo Andres <aandreswork@hotmail.com>
6  * Copyright 2005-2017 Alfredo Andres and David Barroso
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #ifndef _REENTRANT
28 #define _REENTRANT
29 #endif
30 
31 #include <stdio.h>
32 #include <errno.h>
33 
34 #ifdef HAVE_SYS_TYPES_H
35 #include <sys/types.h>
36 #endif
37 
38 #ifdef HAVE_INTTYPES_H
39 #include <inttypes.h>
40 #endif
41 
42 #ifdef HAVE_NETINET_IN_SYSTM_H
43 #include <netinet/in_systm.h>
44 #else
45 #ifdef HAVE_NETINET_IN_SYSTEM_H
46 #include <netinet/in_system.h>
47 #endif
48 #endif
49 
50 #include <netinet/in.h>
51 #include <arpa/inet.h>
52 #include <time.h>
53 
54 #ifdef TIME_WITH_SYS_TIME
55 #include <sys/time.h>
56 #endif
57 
58 #ifdef HAVE_UNISTD_H
59 #include <unistd.h>
60 #endif
61 
62 #ifdef HAVE_STRING_H
63 #include <string.h>
64 #endif
65 
66 #ifdef HAVE_STRINGS_H
67 #include <strings.h>
68 #endif
69 
70 #ifdef HAVE_BSTRING_H
71 #include <bstring.h>
72 #endif
73 
74 #ifdef STDC_HEADERS
75 #include <stdlib.h>
76 #endif
77 
78 #include "attack.h"
79 
80 
81 /* Launch choosed attack... */
attack_launch(struct term_node * node,u_int16_t proto,u_int16_t attack,struct attack_param * attack_params,u_int8_t nparams)82 int8_t attack_launch( struct term_node *node, u_int16_t proto, u_int16_t attack, struct attack_param *attack_params, u_int8_t nparams )
83 {
84     u_int16_t i = 0;
85     dlist_t *p;
86     void *value1, *value2;
87 
88     while (i < MAX_THREAD_ATTACK)
89     {
90         if (node->protocol[proto].attacks[i].up == 0)
91         {
92 
93             node->protocol[proto].attacks[i].up = 1;
94             node->protocol[proto].attacks[i].mac_spoofing = node->mac_spoofing;
95             node->protocol[proto].attacks[i].attack  = attack;
96             node->protocol[proto].attacks[i].params  = attack_params;
97             node->protocol[proto].attacks[i].nparams = nparams;
98             /* FIXME: temporal hasta ponerlo bien, pillamos para el ataque las interfaces del usuario */
99             node->protocol[proto].attacks[i].used_ints = (list_t *) calloc(1, sizeof(list_t));
100             for (p = node->used_ints->list; p; p = dlist_next(node->used_ints->list, p))
101             {
102 
103                 value1 = dlist_data(p);
104                 value2 = (void *) calloc(1, sizeof(struct interface_data));
105                 memcpy((void *)value2, (void *)value1, sizeof(struct interface_data));
106                 node->protocol[proto].attacks[i].used_ints->list = dlist_append(node->protocol[proto].attacks[i].used_ints->list, value2);
107             }
108             node->protocol[proto].attacks[i].used_ints->cmp = interfaces_compare;
109 
110             if ((node->protocol[proto].attacks[i].data = calloc(1, protocols[proto].size )) == NULL)
111             {
112                  thread_error("attack_launch calloc",errno);
113                  node->protocol[proto].attacks[i].params  = NULL;
114                  node->protocol[proto].attacks[i].nparams = 0;
115                  node->protocol[proto].attacks[i].up = 0;
116                  return -1;
117             }
118 
119             memcpy(node->protocol[proto].attacks[i].data, node->protocol[proto].tmp_data, protocols[proto].size );
120 
121             if ( thread_create( &node->protocol[proto].attacks[i].attack_th, //&node->protocol[proto].attacks[i].attack_th.id,
122                                 (*protocols[proto].attack_def_list[attack].attack_th_launch),
123                                 &node->protocol[proto].attacks[i]) < 0)
124             {
125                  free(node->protocol[proto].attacks[i].data);
126                  node->protocol[proto].attacks[i].params  = NULL;
127                  node->protocol[proto].attacks[i].nparams = 0;
128                  node->protocol[proto].attacks[i].up      = 0;
129                  return -1;
130             }
131             write_log(0, " attack_launch: %X Attack thread %X is born!!\n", (int)pthread_self(), (u_long) node->protocol[proto].attacks[i].attack_th.id);
132             return 0;
133         }
134         i++;
135     } /* while...*/
136 
137     return -1;
138 }
139 
140 
141 /*
142  * Kill attack thread pertaining to "node".
143  * If "pid" == 0 then kill *ALL* node attack threads.
144  * Return -1 on error. Return 0 if Ok.
145  */
attack_kill_th(struct term_node * node,pthread_t pid)146 int8_t attack_kill_th( struct term_node *node, pthread_t pid )
147 {
148     u_int16_t i, j;
149 
150     for( i=0; i < MAX_PROTOCOLS; i++ )
151     {
152         if ( protocols[i].visible )
153         {
154             for( j=0; j < MAX_THREAD_ATTACK; j++ )
155             {
156                 if ( node->protocol[i].attacks[j].up == 1 )
157                 {
158                     if ( !pid || ( node->protocol[i].attacks[j].attack_th.id == pid ) )
159                     {
160                        thread_destroy( &node->protocol[i].attacks[j].attack_th );
161                        pthread_mutex_destroy( &node->protocol[i].attacks[j].attack_th.finished );
162                        if ( pid )
163                            return 0;
164                     }
165                 }
166             }
167         }
168     }
169 
170     return 0;
171 }
172 
173 
174 /* Kill attack by index... */
attack_kill_index(struct term_node * node,uint8_t proto_arg,uint8_t attack_arg)175 int8_t attack_kill_index( struct term_node *node, uint8_t proto_arg, uint8_t attack_arg )
176 {
177     if ( ( proto_arg < MAX_PROTOCOLS ) && ( attack_arg < MAX_THREAD_ATTACK ) )
178     {
179         if ( node->protocol[ proto_arg ].attacks[ attack_arg ].up == 1 )
180         {
181             thread_destroy( &node->protocol[ proto_arg ].attacks[ attack_arg ].attack_th );
182 
183             pthread_mutex_destroy( &node->protocol[ proto_arg ].attacks[ attack_arg ].attack_th.finished );
184 
185             return 1;
186         }
187     }
188 
189     return 0 ;
190 }
191 
attack_th_exit(struct attacks * attacks)192 int8_t attack_th_exit(struct attacks *attacks)
193 {
194     write_log(0," attack_th_exit -> attack_th.stop=%d   attack_th.id=%X....\n",attacks->attack_th.stop, attacks->attack_th.id);
195 
196     if (attacks->attack_th.stop == 0)
197         attacks->attack_th.id = 0;
198     else
199         attacks->attack_th.stop = 0;
200 
201     if (attacks->helper_th.id)
202     {
203         write_log(0," attack_th_exit: %X thread_destroy helper %X...\n", (int)pthread_self(), (int)attacks->helper_th.id);
204         thread_destroy(&attacks->helper_th);
205     }
206 
207     pthread_mutex_destroy(&attacks->helper_th.finished);
208 
209     if (attacks->data)
210         free(attacks->data);
211 
212     if (attacks->params)
213     {
214         attack_free_params(attacks->params, attacks->nparams);
215         free(attacks->params);
216     }
217 
218     attacks->data   = NULL;
219     attacks->params = NULL;
220     attacks->up     = 0;
221 
222     dlist_delete(attacks->used_ints->list);
223 
224     if (attacks->used_ints)
225         free(attacks->used_ints);
226 
227     write_log(0, " attack_th_exit: %X finished\n", (int) pthread_self());
228 
229     return 0;
230 }
231 
232 
233 /*
234  *  macof.c
235  *  gen_mac from Dug Song's macof-1.1 C port
236  */
237 void
attack_gen_mac(u_int8_t * mac)238 attack_gen_mac(u_int8_t *mac)
239 {
240     *((in_addr_t *)mac) = libnet_get_prand(LIBNET_PRu32);
241     *((u_int16_t *)(mac + 4)) = libnet_get_prand(LIBNET_PRu16);
242 }
243 
244 
245 int8_t
attack_init_params(struct term_node * node,struct attack_param * param,u_int8_t nparams)246 attack_init_params(struct term_node *node, struct attack_param *param, u_int8_t nparams)
247 {
248    u_int8_t i, j, a;
249 
250    for (i=0; i < nparams; i++)
251    {
252        if ( (param[i].value = calloc(1, param[i].size) ) == NULL)
253        {
254            thread_error("attack_init_parameter calloc",errno);
255            for (a=0; a<i; a++)
256               free(param[a].value);
257            return -1;
258        }
259    }
260 
261    if (node->type == TERM_CON)
262    {
263       for (j=0; j < nparams; j++)
264       {
265            if ( (param[j].print = calloc(1, param[j].size_print+1) ) == NULL)
266            {
267                thread_error("attack_init_parameter calloc",errno);
268                for (a=0; a<j; a++)
269                   free(param[a].print);
270                for (a=0; a<i; a++)
271                   free(param[a].value);
272                return -1;
273            }
274        }
275    }
276 
277    return 0;
278 }
279 
280 void
attack_free_params(struct attack_param * param,u_int8_t nparams)281 attack_free_params(struct attack_param *param, u_int8_t nparams)
282 {
283    u_int8_t i;
284 
285    for (i=0; i < nparams; i++)
286    {
287        if (param[i].value)
288        {
289           free(param[i].value);
290        }
291        if (param[i].print)
292        {
293           free(param[i].print);
294        }
295    }
296 }
297 
298 
299 /*
300  * Filter all attack parameters
301  * On success Return 0.
302  * On error Return -1 and error field number on "field".
303  */
304 int8_t
attack_filter_all_params(struct attack_param * attack_param,u_int8_t nparams,u_int8_t * field)305 attack_filter_all_params(struct attack_param *attack_param, u_int8_t nparams, u_int8_t *field)
306 {
307     u_int8_t j;
308 
309     for (j=0; j<nparams; j++)
310     {
311        if ( parser_filter_param(attack_param[j].type,
312                                 attack_param[j].value,
313                                 attack_param[j].print,
314                                 attack_param[j].size_print,
315                                 attack_param[j].size ) < 0 )
316        {
317           *field = j;
318           return -1;
319        }
320     }
321 
322     return 0;
323 }
324