Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1edba23c32 | ||
|
|
96e846aa82 |
@@ -148,20 +148,12 @@ class Arguments(object):
|
|||||||
|
|
||||||
|
|
||||||
def _add_eviltwin_args(self, group):
|
def _add_eviltwin_args(self, group):
|
||||||
group.add_argument('-et',
|
group.add_argument('-ev',
|
||||||
'--eviltwin',
|
'--eviltwin',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='use_eviltwin',
|
dest='use_eviltwin',
|
||||||
help=Color.s('Use the "Evil Twin" attack against all targets (default: {G}off{W})'))
|
help=Color.s('Use the "Evil Twin" attack against all targets (default: {G}off{W})'))
|
||||||
|
# TODO: Args to specify deauth interface, server port, etc.
|
||||||
group.add_argument('-eti',
|
|
||||||
'--evitwin-iface',
|
|
||||||
type=str,
|
|
||||||
dest='eviltwin_iface',
|
|
||||||
metavar='[iface]',
|
|
||||||
default=None,
|
|
||||||
help=Color.s('Wireless interface to use when creating the Fake AP (evil twin)'))
|
|
||||||
# TODO: Args to specify other options (server port, etc).
|
|
||||||
|
|
||||||
|
|
||||||
def _add_wep_args(self, wep):
|
def _add_wep_args(self, wep):
|
||||||
|
|||||||
@@ -1,224 +0,0 @@
|
|||||||
#!/usr/bin/python2.7
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
from ..model.attack import Attack
|
|
||||||
from ..tools.airodump import Airodump
|
|
||||||
from ..tools.dnsmasq import Dnsmasq
|
|
||||||
from ..tools.hostapd import Hostapd
|
|
||||||
from ..tools.ifconfig import Ifconfig
|
|
||||||
from ..tools.iptables import Iptables
|
|
||||||
from ..tools.eviltwin_server import EviltwinServer
|
|
||||||
from ..util.color import Color
|
|
||||||
from ..util.deauther import Deauther
|
|
||||||
from ..config import Configuration
|
|
||||||
|
|
||||||
class EvilTwinAttack(Attack):
|
|
||||||
'''
|
|
||||||
Monitor-mode card should be used for deauthing (packet injection).
|
|
||||||
Other card can be put into AP mode.
|
|
||||||
'''
|
|
||||||
|
|
||||||
def __init__(self, target, deauth_iface, ap_iface):
|
|
||||||
super(EvilTwinAttack, self).__init__(target)
|
|
||||||
|
|
||||||
# Args
|
|
||||||
self.target = target
|
|
||||||
self.deauth_iface = deauth_iface
|
|
||||||
self.ap_iface = ap_iface
|
|
||||||
|
|
||||||
# State
|
|
||||||
self.success = False
|
|
||||||
self.completed = False
|
|
||||||
self.crack_result = None
|
|
||||||
self.error_msg = None
|
|
||||||
|
|
||||||
# Processes
|
|
||||||
self.hostapd = None
|
|
||||||
self.dnsmasq = None
|
|
||||||
self.webserver = None
|
|
||||||
self.deauther = None
|
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
#raise Exception('Eviltwin attack not implemented yet, see https://github.com/derv82/wifite2/issues/81')
|
|
||||||
|
|
||||||
# Start airodump on deuath iface, wait for target, etc.
|
|
||||||
try:
|
|
||||||
|
|
||||||
with Airodump(channel=self.target.channel,
|
|
||||||
target_bssid=self.target.bssid,
|
|
||||||
skip_wps=True, # Don't check for WPS-compatibility
|
|
||||||
output_file_prefix='airodump') as airodump:
|
|
||||||
Color.clear_line()
|
|
||||||
Color.p('\r{+} {O}waiting{W} for target to appear...')
|
|
||||||
airodump_target = self.wait_for_target(airodump)
|
|
||||||
Color.clear_entire_line()
|
|
||||||
|
|
||||||
self.pattack(airodump_target, 'setting up {C}%s{W}' % self.ap_iface)
|
|
||||||
Ifconfig.up(self.ap_iface, ['10.0.0.1/24'])
|
|
||||||
Color.clear_entire_line()
|
|
||||||
|
|
||||||
self.pattack(airodump_target, 'configuring {C}iptables{W}')
|
|
||||||
self.configure_iptables(self.ap_iface)
|
|
||||||
Color.clear_entire_line()
|
|
||||||
|
|
||||||
self.pattack(airodump_target, 'enabling {C}port forwarding{W}')
|
|
||||||
self.set_port_forwarding(enabled=True)
|
|
||||||
Color.clear_entire_line()
|
|
||||||
|
|
||||||
self.pattack(airodump_target, 'starting {C}hostapd{W} on {C}%s{W}' % self.ap_iface)
|
|
||||||
self.hostapd = Hostapd(self.target, self.ap_iface)
|
|
||||||
self.hostapd.start()
|
|
||||||
Color.clear_entire_line()
|
|
||||||
|
|
||||||
self.pattack(airodump_target, 'starting {C}dnsmasq{W} on {C}%s{W}' % self.ap_iface)
|
|
||||||
self.dnsmasq = Dnsmasq(self.ap_iface)
|
|
||||||
self.dnsmasq.start()
|
|
||||||
Color.clear_entire_line()
|
|
||||||
|
|
||||||
self.pattack(airodump_target, 'starting {C}evil webserver{W}...')
|
|
||||||
self.webserver = EviltwinServer(self.success_callback, self.error_callback)
|
|
||||||
self.webserver.start()
|
|
||||||
Color.clear_entire_line()
|
|
||||||
|
|
||||||
self.pattack(airodump_target, 'starting {C}deauther{W}...')
|
|
||||||
self.deauther = Deauther(self.deauth_iface, self.target)
|
|
||||||
#self.deauther.start()
|
|
||||||
Color.clear_entire_line()
|
|
||||||
|
|
||||||
while not self.completed:
|
|
||||||
time.sleep(1)
|
|
||||||
airodump_target = self.wait_for_target(airodump)
|
|
||||||
|
|
||||||
# TODO: Check hostapd, dnsmasq, and webserver statistics
|
|
||||||
self.pattack(airodump_target, 'waiting for clients')
|
|
||||||
|
|
||||||
# Update deauther with latest client information
|
|
||||||
self.deauther.update_target(airodump_target)
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
# Cleanup
|
|
||||||
Color.pl('\n{!} {O}Interrupted{W}')
|
|
||||||
|
|
||||||
if self.success:
|
|
||||||
# TODO: print status & save
|
|
||||||
self.cleanup()
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.error_msg:
|
|
||||||
self.cleanup()
|
|
||||||
raise Exception(self.error_msg)
|
|
||||||
|
|
||||||
self.cleanup()
|
|
||||||
|
|
||||||
|
|
||||||
def pattack(self, airodump_target, status):
|
|
||||||
Color.pattack('EvilTwin', airodump_target, 'attack', status)
|
|
||||||
|
|
||||||
|
|
||||||
def success_callback(self, crack_result):
|
|
||||||
# Called by webserver when we get a password
|
|
||||||
self.crack_result = crack_result
|
|
||||||
self.success = True
|
|
||||||
self.completed = True
|
|
||||||
|
|
||||||
|
|
||||||
def status_callback(self, status_message):
|
|
||||||
# Called by webserver on status update
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def error_callback(self, error_msg):
|
|
||||||
# Called by webserver on error / failure
|
|
||||||
self.completed = True
|
|
||||||
self.error_msg = error_msg
|
|
||||||
|
|
||||||
|
|
||||||
def cleanup(self):
|
|
||||||
if self.dnsmasq:
|
|
||||||
self.dnsmasq.stop()
|
|
||||||
|
|
||||||
if self.hostapd:
|
|
||||||
self.hostapd.stop()
|
|
||||||
|
|
||||||
if self.webserver:
|
|
||||||
self.webserver.stop()
|
|
||||||
# From https://stackoverflow.com/a/268686
|
|
||||||
|
|
||||||
if self.deauther:
|
|
||||||
self.deauther.stop()
|
|
||||||
|
|
||||||
self.set_port_forwarding(enabled=False)
|
|
||||||
|
|
||||||
Iptables.flush() #iptables -F
|
|
||||||
Iptables.flush(table='nat') #iptables -t nat -F
|
|
||||||
Iptables.flush(table='mangle') #iptables -t mangle -F
|
|
||||||
|
|
||||||
Iptables.delete_chain() #iptables -X
|
|
||||||
Iptables.delete_chain(table='nat') #iptables -t nat -X
|
|
||||||
Iptables.delete_chain(table='mangle') #iptables -t mangle -X
|
|
||||||
|
|
||||||
|
|
||||||
def set_port_forwarding(self, enabled=True):
|
|
||||||
# echo "1" > /proc/sys/net/ipv4/ip_forward
|
|
||||||
# TODO: Are there other/better ways to do this?
|
|
||||||
with open('/proc/sys/net/ipv4/ip_forward', 'w') as ip_forward:
|
|
||||||
ip_forward.write('1' if enabled else '0')
|
|
||||||
|
|
||||||
|
|
||||||
def configure_iptables(self, interface):
|
|
||||||
# iptables -N internet -t mangle
|
|
||||||
Iptables.new_chain('internet', 'mangle')
|
|
||||||
|
|
||||||
#iptables -t mangle -A PREROUTING -j internet
|
|
||||||
Iptables.append('PREROUTING', table='mangle', rules=[
|
|
||||||
'-j', 'internet'
|
|
||||||
])
|
|
||||||
|
|
||||||
#iptables -t mangle -A internet -j MARK --set-mark 99
|
|
||||||
Iptables.append('PREROUTING', table='mangle', rules=[
|
|
||||||
'-j', 'MARK',
|
|
||||||
'--set-mark', '99',
|
|
||||||
])
|
|
||||||
|
|
||||||
#iptables -t nat -A PREROUTING -m mark --mark 99 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1
|
|
||||||
Iptables.append('PREROUTING', table='nat', rules=[
|
|
||||||
'--match', 'mark',
|
|
||||||
'--mark', '99',
|
|
||||||
'--protocol', 'tcp',
|
|
||||||
'--dport', '80',
|
|
||||||
'--jump', 'DNAT',
|
|
||||||
'--to-destination', '10.0.0.1',
|
|
||||||
])
|
|
||||||
|
|
||||||
#iptables -A FORWARD -i eth0 -o wlan0 -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|
||||||
Iptables.append('FORWARD', rules=[
|
|
||||||
'--in-interface', 'eth0',
|
|
||||||
'--out-interface', interface,
|
|
||||||
'--match', 'state',
|
|
||||||
'--state', 'ESTABLISHED,RELATED',
|
|
||||||
'--jump', 'ACCEPT',
|
|
||||||
])
|
|
||||||
|
|
||||||
#iptables -A FORWARD -m mark --mark 99 -j REJECT
|
|
||||||
Iptables.append('FORWARD', rules=[
|
|
||||||
'--match', 'mark',
|
|
||||||
'--mark', '99',
|
|
||||||
'--jump', 'REJECT',
|
|
||||||
])
|
|
||||||
|
|
||||||
#iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
|
|
||||||
Iptables.append('FORWARD', rules=[
|
|
||||||
'--in-interface', interface,
|
|
||||||
'--out-interface', 'eth0',
|
|
||||||
'--jump', 'ACCEPT',
|
|
||||||
])
|
|
||||||
|
|
||||||
#iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
|
||||||
Iptables.append('POSTROUTING', table='nat', rules=[
|
|
||||||
'--out-interface', 'eth0',
|
|
||||||
'--jump', 'MASQUERADE',
|
|
||||||
])
|
|
||||||
|
|
||||||
@@ -4,13 +4,11 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from .util.color import Color
|
from .util.color import Color
|
||||||
from .util.input import raw_input
|
|
||||||
from .tools.iwconfig import Iwconfig
|
|
||||||
from .tools.macchanger import Macchanger
|
from .tools.macchanger import Macchanger
|
||||||
|
|
||||||
class Configuration(object):
|
class Configuration(object):
|
||||||
''' Stores configuration variables and functions for Wifite. '''
|
''' Stores configuration variables and functions for Wifite. '''
|
||||||
version = '2.1.5'
|
version = '2.1.6'
|
||||||
|
|
||||||
initialized = False # Flag indicating config has been initialized
|
initialized = False # Flag indicating config has been initialized
|
||||||
temp_dir = None # Temporary directory
|
temp_dir = None # Temporary directory
|
||||||
@@ -57,7 +55,8 @@ class Configuration(object):
|
|||||||
# EvilTwin variables
|
# EvilTwin variables
|
||||||
cls.use_eviltwin = False
|
cls.use_eviltwin = False
|
||||||
cls.eviltwin_port = 80
|
cls.eviltwin_port = 80
|
||||||
cls.eviltwin_iface = None
|
cls.eviltwin_deauth_iface = None
|
||||||
|
cls.eviltwin_fakeap_iface = None
|
||||||
|
|
||||||
# WEP variables
|
# WEP variables
|
||||||
cls.wep_filter = False # Only attack WEP networks
|
cls.wep_filter = False # Only attack WEP networks
|
||||||
@@ -123,52 +122,9 @@ class Configuration(object):
|
|||||||
if cls.random_mac:
|
if cls.random_mac:
|
||||||
Macchanger.random()
|
Macchanger.random()
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def get_eviltwin_interface(cls):
|
def get_wireless_interface():
|
||||||
if cls.eviltwin_iface is None:
|
pass
|
||||||
Color.pl('\n{+} {G}Evil Twin attack{W}')
|
|
||||||
Color.p('{+} looking for wireless interfaces in "Managed" mode... ')
|
|
||||||
|
|
||||||
ifaces = Iwconfig.get_interfaces(mode='Managed')
|
|
||||||
|
|
||||||
if len(ifaces) == 0:
|
|
||||||
Color.pl('\n{!} {O}no other wireless interfaces in "Managed" mode!{W}')
|
|
||||||
raise Exception('eviltwin attack requires two wireless cards (1 monitor-mode, 1 managed-mode)')
|
|
||||||
|
|
||||||
Color.clear_entire_line()
|
|
||||||
|
|
||||||
while True:
|
|
||||||
# Ask user to select eviltwin interface
|
|
||||||
Color.pl(' select the interface for the {C}evil twin{W} access point:')
|
|
||||||
for index, iface in enumerate(ifaces, start=1):
|
|
||||||
Color.pl(' {G}%d{W}. {C}%s{W}' % (index, iface))
|
|
||||||
|
|
||||||
question = '{+} enter number ({G}'
|
|
||||||
if len(ifaces) == 1:
|
|
||||||
question += '1'
|
|
||||||
else:
|
|
||||||
question += '1-%d' % len(ifaces)
|
|
||||||
question += '{W}): '
|
|
||||||
selection = raw_input(Color.s(question))
|
|
||||||
|
|
||||||
if selection.strip() in ifaces:
|
|
||||||
selection = str(ifaces.index(selection.strip()) + 1)
|
|
||||||
|
|
||||||
elif not selection.isdigit():
|
|
||||||
Color.pl('\n{!} {O}selection must be numeric{W}')
|
|
||||||
continue
|
|
||||||
|
|
||||||
selection = int(selection)
|
|
||||||
|
|
||||||
if selection < 1 or selection > len(ifaces):
|
|
||||||
Color.pl('\n{!} {O}selection must be between {R}1{O} and {R}%d{W}' % len(ifaces))
|
|
||||||
continue
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
cls.eviltwin_iface = ifaces[selection - 1]
|
|
||||||
|
|
||||||
return cls.eviltwin_iface
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_from_arguments(cls):
|
def load_from_arguments(cls):
|
||||||
@@ -219,23 +175,10 @@ class Configuration(object):
|
|||||||
cls.kill_conflicting_processes = True
|
cls.kill_conflicting_processes = True
|
||||||
Color.pl('{+} {C}option:{W} kill conflicting processes {G}enabled{W}')
|
Color.pl('{+} {C}option:{W} kill conflicting processes {G}enabled{W}')
|
||||||
|
|
||||||
|
|
||||||
# EvilTwin
|
# EvilTwin
|
||||||
if args.eviltwin_iface:
|
|
||||||
# Check that eviltwin_iface exists in iwconfig
|
|
||||||
existing_ifaces = Iwconfig.get_interfaces()
|
|
||||||
if args.eviltwin_iface not in existing_ifaces:
|
|
||||||
raise Exception('Interface "%s" was not found by iwconfig (found %s)' % (args.eviltwin_iface, ','.join(existing_ifaces)))
|
|
||||||
# TODO: Put device into managed mode?
|
|
||||||
|
|
||||||
cls.eviltwin_iface = args.eviltwin_iface
|
|
||||||
Color.pl('{+} {C}option:{W} using {G}%s{W} to create fake AP for evil twin attacks' % cls.eviltwin_iface)
|
|
||||||
|
|
||||||
if args.use_eviltwin:
|
if args.use_eviltwin:
|
||||||
# TODO: Or ask user to select a different wireless device?
|
|
||||||
cls.use_eviltwin = True
|
cls.use_eviltwin = True
|
||||||
Color.pl('{+} {C}option:{W} attacking all targets using {G}eviltwin attacks{W}')
|
Color.pl('{+} {C}option:{W} using {G}eviltwin attacks{W} against all targets')
|
||||||
|
|
||||||
|
|
||||||
# WEP
|
# WEP
|
||||||
if args.wep_filter:
|
if args.wep_filter:
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ class AirmonIface(object):
|
|||||||
self.chipset = chipset
|
self.chipset = chipset
|
||||||
self.mac_address = Ifconfig.get_mac(interface)
|
self.mac_address = Ifconfig.get_mac(interface)
|
||||||
|
|
||||||
# Max length of fields. Used for printing a table of interfaces.
|
# Max length of fields.
|
||||||
|
# Used for printing a table of interfaces.
|
||||||
INTERFACE_LEN = 12
|
INTERFACE_LEN = 12
|
||||||
PHY_LEN = 6
|
PHY_LEN = 6
|
||||||
DRIVER_LEN = 20
|
DRIVER_LEN = 20
|
||||||
CHIPSET_LEN = 30
|
CHIPSET_LEN = 30
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
''' Colored string representation of interface '''
|
''' Colored string representation of interface '''
|
||||||
s = ''
|
s = ''
|
||||||
@@ -37,7 +37,6 @@ class AirmonIface(object):
|
|||||||
s += Color.s('{W}%s' % self.chipset.ljust(self.CHIPSET_LEN))
|
s += Color.s('{W}%s' % self.chipset.ljust(self.CHIPSET_LEN))
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def menu_header():
|
def menu_header():
|
||||||
''' Colored header row for interfaces '''
|
''' Colored header row for interfaces '''
|
||||||
@@ -53,13 +52,12 @@ class AirmonIface(object):
|
|||||||
|
|
||||||
class Airmon(Dependency):
|
class Airmon(Dependency):
|
||||||
''' Wrapper around the 'airmon-ng' program '''
|
''' Wrapper around the 'airmon-ng' program '''
|
||||||
|
|
||||||
dependency_required = True
|
dependency_required = True
|
||||||
dependency_name = 'airmon-ng'
|
dependency_name = 'airmon-ng'
|
||||||
dependency_url = 'https://www.aircrack-ng.org/install.html'
|
dependency_url = 'https://www.aircrack-ng.org/install.html'
|
||||||
|
|
||||||
base_interface = None # Interface *before* it was put into monitor mode.
|
base_interface = None
|
||||||
killed_network_manager = False # If we killed network-manager
|
killed_network_manager = False
|
||||||
|
|
||||||
# Drivers that need to be manually put into monitor mode
|
# Drivers that need to be manually put into monitor mode
|
||||||
BAD_DRIVERS = ['rtl8821au']
|
BAD_DRIVERS = ['rtl8821au']
|
||||||
@@ -68,8 +66,11 @@ class Airmon(Dependency):
|
|||||||
ARPHRD_IEEE80211_RADIOTAP = 803 #monitor
|
ARPHRD_IEEE80211_RADIOTAP = 803 #monitor
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.interfaces = Airmon.get_interfaces()
|
self.refresh()
|
||||||
|
|
||||||
|
def refresh(self):
|
||||||
|
''' Get airmon-recognized interfaces '''
|
||||||
|
self.interfaces = Airmon.get_interfaces()
|
||||||
|
|
||||||
def print_menu(self):
|
def print_menu(self):
|
||||||
''' Prints menu '''
|
''' Prints menu '''
|
||||||
@@ -77,7 +78,6 @@ class Airmon(Dependency):
|
|||||||
for idx, iface in enumerate(self.interfaces, start=1):
|
for idx, iface in enumerate(self.interfaces, start=1):
|
||||||
Color.pl(" {G}%d{W}. %s" % (idx, iface))
|
Color.pl(" {G}%d{W}. %s" % (idx, iface))
|
||||||
|
|
||||||
|
|
||||||
def get(self, index):
|
def get(self, index):
|
||||||
''' Gets interface at index (starts at 1) '''
|
''' Gets interface at index (starts at 1) '''
|
||||||
if type(index) is str:
|
if type(index) is str:
|
||||||
@@ -105,7 +105,6 @@ class Airmon(Dependency):
|
|||||||
|
|
||||||
return interfaces
|
return interfaces
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def start_bad_driver(iface):
|
def start_bad_driver(iface):
|
||||||
'''
|
'''
|
||||||
@@ -125,7 +124,6 @@ class Airmon(Dependency):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def stop_bad_driver(iface):
|
def stop_bad_driver(iface):
|
||||||
'''
|
'''
|
||||||
@@ -145,7 +143,6 @@ class Airmon(Dependency):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def start(iface):
|
def start(iface):
|
||||||
'''
|
'''
|
||||||
@@ -200,26 +197,18 @@ class Airmon(Dependency):
|
|||||||
|
|
||||||
return enabled_iface
|
return enabled_iface
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _parse_airmon_start(airmon_output):
|
def _parse_airmon_start(airmon_output):
|
||||||
'''Returns the interface name that was put into monitor mode (if any)'''
|
'''Find the interface put into monitor mode (if any)'''
|
||||||
|
|
||||||
# airmon-ng output: (mac80211 monitor mode vif enabled for [phy10]wlan0 on [phy10]wlan0mon)
|
# airmon-ng output: (mac80211 monitor mode vif enabled for [phy10]wlan0 on [phy10]wlan0mon)
|
||||||
enabled_re = re.compile(r'\s*\(mac80211 monitor mode (?:vif )?enabled for [^ ]+ on (?:\[\w+\])?(\w+)\)\s*')
|
enabled_re = re.compile(r'\s*\(mac80211 monitor mode (?:vif )?enabled for [^ ]+ on (?:\[\w+\])?(\w+)\)\s*')
|
||||||
|
|
||||||
# airmon-ng output from https://www.aircrack-ng.org/doku.php?id=iwlagn
|
|
||||||
enabled_re2 = re.compile(r'\s*\(monitor mode enabled on (\w+)\)')
|
|
||||||
|
|
||||||
for line in airmon_output.split('\n'):
|
for line in airmon_output.split('\n'):
|
||||||
matches = enabled_re.match(line)
|
matches = enabled_re.match(line)
|
||||||
if matches:
|
if matches:
|
||||||
return matches.group(1)
|
return matches.group(1)
|
||||||
|
|
||||||
matches = enabled_re2.match(line)
|
|
||||||
if matches:
|
|
||||||
return matches.group(1)
|
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -286,16 +275,15 @@ class Airmon(Dependency):
|
|||||||
|
|
||||||
Airmon.terminate_conflicting_processes()
|
Airmon.terminate_conflicting_processes()
|
||||||
|
|
||||||
Color.p('\n{+} looking for {C}wireless interfaces{W}... ')
|
Color.pl('\n{+} looking for {C}wireless interfaces{W}')
|
||||||
monitor_interfaces = Iwconfig.get_interfaces(mode='Monitor')
|
monitor_interfaces = Iwconfig.get_interfaces(mode='Monitor')
|
||||||
if len(monitor_interfaces) == 1:
|
if len(monitor_interfaces) == 1:
|
||||||
# Assume we're using the device already in montior mode
|
# Assume we're using the device already in montior mode
|
||||||
iface = monitor_interfaces[0]
|
iface = monitor_interfaces[0]
|
||||||
Color.pl('using interface {G}%s{W} (already in monitor mode)' % iface);
|
Color.pl(' using interface {G}%s{W} (already in monitor mode)' % iface);
|
||||||
#Color.pl(' you can specify the wireless interface using {C}-i wlan0{W}')
|
Color.pl(' you can specify the wireless interface using {C}-i wlan0{W}')
|
||||||
Airmon.base_interface = None
|
Airmon.base_interface = None
|
||||||
return iface
|
return iface
|
||||||
Color.pl('')
|
|
||||||
|
|
||||||
a = Airmon()
|
a = Airmon()
|
||||||
count = len(a.interfaces)
|
count = len(a.interfaces)
|
||||||
@@ -376,7 +364,6 @@ class Airmon(Dependency):
|
|||||||
Ifconfig.up(iface)
|
Ifconfig.up(iface)
|
||||||
Color.pl(" {G}done{W}")
|
Color.pl(" {G}done{W}")
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def start_network_manager():
|
def start_network_manager():
|
||||||
Color.p("{!} {O}restarting {R}NetworkManager{O}...")
|
Color.p("{!} {O}restarting {R}NetworkManager{O}...")
|
||||||
@@ -417,4 +404,3 @@ if __name__ == '__main__':
|
|||||||
(disabled_iface, enabled_iface) = Airmon.stop(iface)
|
(disabled_iface, enabled_iface) = Airmon.stop(iface)
|
||||||
print("Disabled:", disabled_iface)
|
print("Disabled:", disabled_iface)
|
||||||
print("Enabled:", enabled_iface)
|
print("Enabled:", enabled_iface)
|
||||||
|
|
||||||
|
|||||||
@@ -192,10 +192,9 @@ class Airodump(Dependency):
|
|||||||
'''Returns list of Target objects parsed from CSV file.'''
|
'''Returns list of Target objects parsed from CSV file.'''
|
||||||
targets = []
|
targets = []
|
||||||
import csv
|
import csv
|
||||||
with open(csv_filename, 'rb') as csvopen:
|
with open(csv_filename, 'r') as csvopen:
|
||||||
lines = []
|
lines = []
|
||||||
for line in csvopen:
|
for line in csvopen:
|
||||||
if type(line) is bytes: line = line.decode('utf-8')
|
|
||||||
line = line.replace('\0', '')
|
line = line.replace('\0', '')
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
csv_reader = csv.reader(lines,
|
csv_reader = csv.reader(lines,
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
#!/usr/bin/python2.7
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from .dependency import Dependency
|
|
||||||
from ..util.process import Process
|
|
||||||
from ..config import Configuration
|
|
||||||
|
|
||||||
class Dnsmasq(Dependency):
|
|
||||||
'''Wrapper for dnsmasq program.'''
|
|
||||||
|
|
||||||
dependency_required = False
|
|
||||||
dependency_name = 'dnsmasq'
|
|
||||||
dependency_url = 'apt-get install dnsmasq'
|
|
||||||
|
|
||||||
def __init__(self, interface):
|
|
||||||
self.interface = interface
|
|
||||||
self.pid = None
|
|
||||||
self.config_file = None
|
|
||||||
|
|
||||||
|
|
||||||
def create_config_file(self):
|
|
||||||
self.config_file = os.path.join(Configuration.temp(), 'dnsmasq.conf')
|
|
||||||
if os.path.exists(self.config_file):
|
|
||||||
os.remove(self.config_file)
|
|
||||||
|
|
||||||
with open(self.config_file, 'w') as config:
|
|
||||||
config.write('interface={}\n'.format(self.interface))
|
|
||||||
config.write('dhcp-range=10.0.0.10,10.0.0.100,8h\n')
|
|
||||||
config.write('dhcp-option=3,10.0.0.1\n')
|
|
||||||
config.write('dhcp-option=6,10.0.0.1\n')
|
|
||||||
config.write('server=8.8.8.8\n')
|
|
||||||
config.write('log-queries\n')
|
|
||||||
config.write('log-dhcp\n')
|
|
||||||
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
self.create_config_file()
|
|
||||||
|
|
||||||
# Stop already-running dnsmasq process
|
|
||||||
self.killall()
|
|
||||||
|
|
||||||
# Start new dnsmasq process
|
|
||||||
self.pid = Process([
|
|
||||||
'dnsmasq',
|
|
||||||
'-C', self.config_file
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
# Kill dnsmasq process
|
|
||||||
if self.pid and self.pid.poll() is not None:
|
|
||||||
self.pid.interrupt()
|
|
||||||
|
|
||||||
self.killall()
|
|
||||||
|
|
||||||
if self.config_file and os.path.exists(self.config_file):
|
|
||||||
os.remove(self.config_file)
|
|
||||||
|
|
||||||
|
|
||||||
def killall(self):
|
|
||||||
Process(['killall', 'dnsmasq']).wait()
|
|
||||||
# TODO: Wait until dnsmasq is completely stopped.
|
|
||||||
|
|
||||||
|
|
||||||
def check(self):
|
|
||||||
if self.pid.poll() is not None:
|
|
||||||
raise Exception('dnsmasq stopped running, exit code: %d, output: %s' % (self.pid.poll(), self.pid.stdout()))
|
|
||||||
# TODO: Check logs/output for problems
|
|
||||||
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
#!/usr/bin/python2.7
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
|
|
||||||
from threading import Thread
|
|
||||||
|
|
||||||
class EviltwinServer(HTTPServer, object):
|
|
||||||
|
|
||||||
def __init__(self, success_callback, error_callback, port=80):
|
|
||||||
self.thread = None
|
|
||||||
# Store state in server
|
|
||||||
self.success_callback = success_callback
|
|
||||||
self.error_callback = error_callback
|
|
||||||
self.request_count = 0
|
|
||||||
self.router_pages_served = 0
|
|
||||||
# Initialize with our request handler
|
|
||||||
super(EviltwinServer, self).__init__(('', port), EviltwinRequestHandler)
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
self.thread = Thread(target=self.serve_forever)
|
|
||||||
self.thread.start()
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
# From https://stackoverflow.com/a/268686
|
|
||||||
self.shutdown()
|
|
||||||
self.socket.close()
|
|
||||||
|
|
||||||
if self.thread:
|
|
||||||
self.thread.join()
|
|
||||||
|
|
||||||
def request_count(self):
|
|
||||||
return self.request_count
|
|
||||||
|
|
||||||
def router_pages_served(self):
|
|
||||||
return self.router_pages_served
|
|
||||||
|
|
||||||
|
|
||||||
class EviltwinRequestHandler(BaseHTTPRequestHandler):
|
|
||||||
|
|
||||||
def do_GET(self):
|
|
||||||
self.server.request_count += 1
|
|
||||||
request_path = self.path
|
|
||||||
|
|
||||||
# TODO: URL mappings to load specific pages. E.g. Apple/Android "pings"
|
|
||||||
|
|
||||||
print('\n----- Request Start ----->\n')
|
|
||||||
print(request_path)
|
|
||||||
print(self.headers)
|
|
||||||
print('<----- Request End -----\n')
|
|
||||||
|
|
||||||
self.send_response(200)
|
|
||||||
self.send_header('Content-type', 'text/html')
|
|
||||||
self.end_headers()
|
|
||||||
self.wfile.write('<html><head><title>Title goes here.</title></head>')
|
|
||||||
self.wfile.write('<body><p>This is a test.</p>')
|
|
||||||
# If someone went to 'http://something.somewhere.net/foo/bar/',
|
|
||||||
# then s.path equals '/foo/bar/'.
|
|
||||||
self.wfile.write('<p>You accessed path: %s</p>' % self.path)
|
|
||||||
self.wfile.write('</body></html>')
|
|
||||||
|
|
||||||
|
|
||||||
def do_POST(self):
|
|
||||||
self.server.request_count += 1
|
|
||||||
request_path = self.path
|
|
||||||
|
|
||||||
# TODO: If path includes router password, call self.server.success_callback
|
|
||||||
# TODO: Verify router passwords via separate interface?
|
|
||||||
|
|
||||||
print('\n----- Request Start ----->\n')
|
|
||||||
print(request_path)
|
|
||||||
|
|
||||||
request_headers = self.headers
|
|
||||||
content_length = request_headers.getheaders('content-length')
|
|
||||||
length = int(content_length[0]) if content_length else 0
|
|
||||||
|
|
||||||
print(request_headers)
|
|
||||||
print(self.rfile.read(length))
|
|
||||||
print('<----- Request End -----\n')
|
|
||||||
|
|
||||||
self.send_response(200)
|
|
||||||
|
|
||||||
do_PUT = do_POST
|
|
||||||
do_DELETE = do_GET
|
|
||||||
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
#!/usr/bin/python2.7
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
|
|
||||||
from .dependency import Dependency
|
|
||||||
from ..config import Configuration
|
|
||||||
from ..util.process import Process
|
|
||||||
|
|
||||||
class Hostapd(Dependency):
|
|
||||||
process_name = 'hostapd'
|
|
||||||
|
|
||||||
dependency_required = False
|
|
||||||
dependency_name = process_name
|
|
||||||
dependency_url = 'apt-get install hostapd'
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def exists(cls):
|
|
||||||
return Process.exists(cls.process_name)
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, target, interface):
|
|
||||||
self.target = target
|
|
||||||
self.interface = interface
|
|
||||||
self.pid = None
|
|
||||||
self.config_file = None
|
|
||||||
self.output_file = None
|
|
||||||
self.output_write = None
|
|
||||||
self.state = 'Initializing'
|
|
||||||
|
|
||||||
|
|
||||||
def create_config_file(self):
|
|
||||||
if not self.target.essid_known:
|
|
||||||
self.state = 'Error: Target ESSID is not known'
|
|
||||||
raise Exception('Cannot start hostapd if target has unknown SSID')
|
|
||||||
|
|
||||||
self.config_file = os.path.abspath(os.path.join(Configuration.temp(), 'hostapd.conf'))
|
|
||||||
|
|
||||||
with open(self.config_file, 'w') as config:
|
|
||||||
config.write('driver=nl80211\n')
|
|
||||||
config.write('ssid={}\n'.format(self.target.essid))
|
|
||||||
# TODO: support 5ghz
|
|
||||||
config.write('hw_mode=g\n')
|
|
||||||
config.write('channel={}\n'.format(self.target.channel))
|
|
||||||
config.write('logger_syslog=-1\n')
|
|
||||||
config.write('logger_syslog_level=2\n')
|
|
||||||
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
self.create_config_file()
|
|
||||||
|
|
||||||
self.killall()
|
|
||||||
|
|
||||||
temp = Configuration.temp()
|
|
||||||
self.output_file = os.path.abspath(os.path.join(temp, 'hostapd.out'))
|
|
||||||
self.output_write = open(self.output_file, 'a')
|
|
||||||
|
|
||||||
command = [
|
|
||||||
self.process_name,
|
|
||||||
'-i', self.interface,
|
|
||||||
self.config_file
|
|
||||||
]
|
|
||||||
|
|
||||||
self.pid = Process(command, stdout=self.output_write, cwd=temp)
|
|
||||||
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
if self.pid and self.pid.poll() is not None:
|
|
||||||
self.pid.interrupt()
|
|
||||||
|
|
||||||
self.killall()
|
|
||||||
# TODO: Wait until hostapd is completely stopped.
|
|
||||||
|
|
||||||
if self.output_write:
|
|
||||||
self.output_write.close()
|
|
||||||
|
|
||||||
if self.config_file and os.path.exists(self.config_file):
|
|
||||||
os.remove(self.config_file)
|
|
||||||
|
|
||||||
if self.output_file and os.path.exists(self.output_file):
|
|
||||||
os.remove(self.output_file)
|
|
||||||
|
|
||||||
|
|
||||||
def killall(self):
|
|
||||||
Process(['killall', self.process_name]).wait()
|
|
||||||
|
|
||||||
|
|
||||||
def check(self):
|
|
||||||
if self.pid.poll() is not None:
|
|
||||||
raise Exception('hostapd stopped running, exit code: %d, output: %s' % (self.pid.poll(), self.pid.stdout()))
|
|
||||||
# TODO: Check hostapd logs / output for any problems.
|
|
||||||
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
#!/usr/bin/python2.7
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
from .dependency import Dependency
|
|
||||||
from ..util.process import Process
|
|
||||||
|
|
||||||
class Iptables(Dependency):
|
|
||||||
|
|
||||||
process_name = 'iptables'
|
|
||||||
|
|
||||||
dependency_required = False
|
|
||||||
dependency_name = process_name
|
|
||||||
dependency_url = 'apt-get install iptables'
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def exists(cls):
|
|
||||||
return Process.exists(cls.process_name)
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def __exec(cls, args, expect_return_code=0):
|
|
||||||
# Helper method for executing iptables commands.
|
|
||||||
|
|
||||||
if type(args) is str:
|
|
||||||
args = args.split(' ')
|
|
||||||
|
|
||||||
command = [cls.process_name] + args
|
|
||||||
|
|
||||||
pid = Process(command)
|
|
||||||
pid.wait()
|
|
||||||
if expect_return_code and pid.poll() != 0:
|
|
||||||
raise Exception('Error executing %s:\n%s\n%s' % (' '.join(command), pid.stdout(), pid.stderr()))
|
|
||||||
|
|
||||||
|
|
||||||
# -N, --new-chain <chain>
|
|
||||||
@classmethod
|
|
||||||
def new_chain(cls, chain_name, table):
|
|
||||||
args = ['-N', chain_name, '-t', table]
|
|
||||||
cls.__exec(args)
|
|
||||||
|
|
||||||
# -A, --append <chain> <rule-specification>
|
|
||||||
@classmethod
|
|
||||||
def append(cls, chain, table=None, rules=[]):
|
|
||||||
args = []
|
|
||||||
if table is not None:
|
|
||||||
args.extend(['-t', table])
|
|
||||||
args.extend(['-A', chain])
|
|
||||||
args.extend(rules)
|
|
||||||
cls.__exec(args)
|
|
||||||
|
|
||||||
|
|
||||||
# -F, --flush <chain>
|
|
||||||
@classmethod
|
|
||||||
def flush(cls, table=None):
|
|
||||||
args = []
|
|
||||||
if table is not None:
|
|
||||||
args.extend(['-t', table])
|
|
||||||
args.append('-F')
|
|
||||||
cls.__exec(args)
|
|
||||||
|
|
||||||
|
|
||||||
# -X, --delete-chain <chain>
|
|
||||||
@classmethod
|
|
||||||
def delete_chain(cls, table=None):
|
|
||||||
args = []
|
|
||||||
if table is not None:
|
|
||||||
args.extend(['-t', table])
|
|
||||||
args.append('-X')
|
|
||||||
cls.__exec(args)
|
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ class Iwconfig(Dependency):
|
|||||||
if mode is None:
|
if mode is None:
|
||||||
interfaces.add(iface)
|
interfaces.add(iface)
|
||||||
|
|
||||||
if mode is not None and 'mode:{}'.format(mode.lower()) in line.lower():
|
if mode is not None and 'Mode:{}'.format(mode) in line:
|
||||||
interfaces.add(iface)
|
interfaces.add(iface)
|
||||||
|
|
||||||
return list(interfaces)
|
return list(interfaces)
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
#!/usr/bin/python2.7
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
from ..tools.aireplay import Aireplay
|
|
||||||
from ..tools.ifconfig import Ifconfig
|
|
||||||
|
|
||||||
class Deauther(object):
|
|
||||||
'''
|
|
||||||
Deauthenticates clients associated with a target.
|
|
||||||
For use with EvilTwin.
|
|
||||||
'''
|
|
||||||
|
|
||||||
def __init__(self, interface, target):
|
|
||||||
self.interface = interface
|
|
||||||
self.interface_mac = Ifconfig.get_mac(interface)
|
|
||||||
self.target = target
|
|
||||||
self.running = False
|
|
||||||
self.clients = set()
|
|
||||||
|
|
||||||
|
|
||||||
def update_target(self, target):
|
|
||||||
# Refresh target (including list of clients)
|
|
||||||
self.target = target
|
|
||||||
|
|
||||||
|
|
||||||
def update_clients(self):
|
|
||||||
# Refreshes list of clients connected to target
|
|
||||||
for client in self.target.clients:
|
|
||||||
bssid = client.station
|
|
||||||
if bssid.lower() == self.interface_mac:
|
|
||||||
continue # Ignore this interface
|
|
||||||
elif bssid not in self.clients:
|
|
||||||
self.clients.add(bssid)
|
|
||||||
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
self.running = True
|
|
||||||
|
|
||||||
while self.running:
|
|
||||||
# Refresh list of clients
|
|
||||||
self.update_clients()
|
|
||||||
|
|
||||||
# Deauth clients
|
|
||||||
bssid = self.target.bssid
|
|
||||||
essid = self.target.essid if self.target.essid_known else None
|
|
||||||
for client_mac in clients:
|
|
||||||
Aireplay.deauth(bssid, essid=essid, client_mac=client_mac)
|
|
||||||
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
self.running = False
|
|
||||||
|
|
||||||
@@ -39,10 +39,7 @@ class Scanner(object):
|
|||||||
self.err_msg = '\r{!} {R}Airodump exited unexpectedly (Code: %d){O} Command: {W}%s' % (airodump.pid.poll(), " ".join(airodump.pid.command))
|
self.err_msg = '\r{!} {R}Airodump exited unexpectedly (Code: %d){O} Command: {W}%s' % (airodump.pid.poll(), " ".join(airodump.pid.command))
|
||||||
raise KeyboardInterrupt
|
raise KeyboardInterrupt
|
||||||
|
|
||||||
try:
|
self.targets = airodump.get_targets()
|
||||||
self.targets = airodump.get_targets()
|
|
||||||
except Exception as e:
|
|
||||||
break
|
|
||||||
|
|
||||||
if self.found_target():
|
if self.found_target():
|
||||||
# We found the target we want
|
# We found the target we want
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ from .util.input import raw_input
|
|||||||
from .attack.wep import AttackWEP
|
from .attack.wep import AttackWEP
|
||||||
from .attack.wpa import AttackWPA
|
from .attack.wpa import AttackWPA
|
||||||
from .attack.wps import AttackWPS
|
from .attack.wps import AttackWPS
|
||||||
from .attack.eviltwin import EvilTwinAttack
|
|
||||||
from .model.result import CrackResult
|
from .model.result import CrackResult
|
||||||
from .model.handshake import Handshake
|
from .model.handshake import Handshake
|
||||||
|
|
||||||
@@ -41,10 +40,8 @@ class Wifite(object):
|
|||||||
|
|
||||||
elif Configuration.check_handshake:
|
elif Configuration.check_handshake:
|
||||||
self.check_handshake(Configuration.check_handshake)
|
self.check_handshake(Configuration.check_handshake)
|
||||||
|
|
||||||
elif Configuration.crack_handshake:
|
elif Configuration.crack_handshake:
|
||||||
CrackHandshake()
|
CrackHandshake()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
Configuration.get_monitor_mode_interface()
|
Configuration.get_monitor_mode_interface()
|
||||||
self.run()
|
self.run()
|
||||||
@@ -58,9 +55,6 @@ class Wifite(object):
|
|||||||
from .tools.aireplay import Aireplay
|
from .tools.aireplay import Aireplay
|
||||||
from .tools.ifconfig import Ifconfig
|
from .tools.ifconfig import Ifconfig
|
||||||
from .tools.iwconfig import Iwconfig
|
from .tools.iwconfig import Iwconfig
|
||||||
from .tools.hostapd import Hostapd
|
|
||||||
from .tools.dnsmasq import Dnsmasq
|
|
||||||
from .tools.iptables import Iptables
|
|
||||||
from .tools.bully import Bully
|
from .tools.bully import Bully
|
||||||
from .tools.reaver import Reaver
|
from .tools.reaver import Reaver
|
||||||
from .tools.wash import Wash
|
from .tools.wash import Wash
|
||||||
@@ -81,9 +75,6 @@ class Wifite(object):
|
|||||||
Macchanger
|
Macchanger
|
||||||
]
|
]
|
||||||
|
|
||||||
if Configuration.use_eviltwin:
|
|
||||||
apps.extend([Hostapd, Dnsmasq, Iptables])
|
|
||||||
|
|
||||||
missing_required = any([app.fails_dependency_check() for app in apps])
|
missing_required = any([app.fails_dependency_check() for app in apps])
|
||||||
|
|
||||||
if missing_required:
|
if missing_required:
|
||||||
@@ -148,10 +139,6 @@ class Wifite(object):
|
|||||||
else:
|
else:
|
||||||
targets = s.select_targets()
|
targets = s.select_targets()
|
||||||
|
|
||||||
if Configuration.use_eviltwin:
|
|
||||||
# Ask user to select interface if needed
|
|
||||||
Configuration.get_eviltwin_interface()
|
|
||||||
|
|
||||||
attacked_targets = 0
|
attacked_targets = 0
|
||||||
targets_remaining = len(targets)
|
targets_remaining = len(targets)
|
||||||
for idx, t in enumerate(targets, start=1):
|
for idx, t in enumerate(targets, start=1):
|
||||||
@@ -165,7 +152,7 @@ class Wifite(object):
|
|||||||
# TODO: Check if Eviltwin attack is selected.
|
# TODO: Check if Eviltwin attack is selected.
|
||||||
|
|
||||||
if Configuration.use_eviltwin:
|
if Configuration.use_eviltwin:
|
||||||
attack = EvilTwinAttack(t, Configuration.interface, Configuration.eviltwin_iface)
|
pass
|
||||||
|
|
||||||
elif 'WEP' in t.encryption:
|
elif 'WEP' in t.encryption:
|
||||||
attack = AttackWEP(t)
|
attack = AttackWEP(t)
|
||||||
|
|||||||
Reference in New Issue
Block a user