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