Code cleanup

This commit is contained in:
derv82
2018-04-18 14:42:24 -04:00
parent 8f32972546
commit 2b40ce3706
9 changed files with 333 additions and 279 deletions

View File

@@ -67,7 +67,7 @@ class Arguments(object):
glob.add_argument('--channel', help=argparse.SUPPRESS, action='store', dest='channel', type=int)
glob.add_argument('-mac',
'---random-mac',
'--random-mac',
action='store_true',
dest='random_mac',
help=Color.s('Randomize wireless card MAC address (default: {G}off{W})'))

View File

@@ -1,18 +1,19 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
import os
from .util.color import Color
from .tools.macchanger import Macchanger
import os
class Configuration(object):
''' Stores configuration variables and functions for Wifite. '''
verbose = 0
version = '2.1.3'
initialized = False # Flag indicating config has been initialized
temp_dir = None # Temporary directory
version = '2.1.3'
interface = None
verbose = 0
@staticmethod
def initialize(load_interface=True):
@@ -315,15 +316,18 @@ class Configuration(object):
Configuration.delete_temp()
Macchanger.reset_if_changed()
from .tools.airmon import Airmon
if hasattr(Configuration, "interface") and Configuration.interface is not None and Airmon.base_interface is not None:
Color.pl('{!} Leaving interface {C}%s{W} in Monitor Mode.' % Configuration.interface)
Color.pl('{!} You can disable Monitor Mode when finished ({C}airmon-ng stop %s{W})' % Configuration.interface)
#Airmon.stop(Configuration.interface)
#Airmon.put_interface_up(Airmon.base_interface)
if Configuration.interface is not None and Airmon.base_interface is not None:
#Color.pl('{!} Leaving interface {C}%s{W} in Monitor Mode.' % Configuration.interface)
#Color.pl('{!} You can disable Monitor Mode when finished ({C}airmon-ng stop %s{W})' % Configuration.interface)
# Stop monitor mode
Airmon.stop(Configuration.interface)
# Bring original interface back up
Airmon.put_interface_up(Airmon.base_interface)
if Airmon.killed_network_manager:
Color.pl('{!} You can restart NetworkManager when finished ({C}service network-manager start{W})')
#Airmon.start_network_manager()
#Color.pl('{!} You can restart NetworkManager when finished ({C}service network-manager start{W})')
Airmon.start_network_manager()
exit(code)

View File

@@ -4,9 +4,7 @@
import time
class Attack(object):
'''
Contains functionality common to all attacks
'''
'''Contains functionality common to all attacks.'''
target_wait = 20
@@ -17,17 +15,13 @@ class Attack(object):
raise Exception("Unimplemented method: run")
def wait_for_target(self, airodump):
'''
Waits for target to appear in airodump
'''
'''Waits for target to appear in airodump.'''
start_time = time.time()
targets = airodump.get_targets(apply_filter=False)
while len(targets) == 0:
# Wait for target to appear in airodump.
if int(time.time() - start_time) > Attack.target_wait:
raise Exception(
"Target did not appear after %d seconds, stopping"
% Attack.target_wait)
raise Exception('Target did not appear after %d seconds, stopping' % Attack.target_wait)
time.sleep(1)
targets = airodump.get_targets()
continue

View File

@@ -13,11 +13,49 @@ import re
import os
import signal
class AirmonIface(object):
def __init__(self, phy, interface, driver, chipset):
self.phy = phy
self.interface = interface
self.driver = driver
self.chipset = chipset
self.mac_address = Ifconfig.get_mac(interface)
# Max length of fields.
# Used for printing a table of interfaces.
PHY_LEN = 6
INTERFACE_LEN = 12
DRIVER_LEN = 20
CHIPSET_LEN = 30
def __str__(self):
''' Colored string representation of interface '''
s = Color.s('{W}%s' % self.phy.ljust(self.PHY_LEN))
s += Color.s('{G}%s' % self.interface.ljust(self.INTERFACE_LEN))
s += Color.s('{C}%s' % self.driver.ljust(self.DRIVER_LEN))
s += Color.s('{W}%s' % self.chipset.ljust(self.CHIPSET_LEN))
return s
@staticmethod
def menu_header():
''' Colored header row for interfaces '''
s = ' '
s += 'PHY'.ljust(AirmonIface.PHY_LEN)
s += 'Interface'.ljust(AirmonIface.INTERFACE_LEN)
s += 'Driver'.ljust(AirmonIface.DRIVER_LEN)
s += 'Chipset'.ljust(AirmonIface.CHIPSET_LEN)
s += '\n'
s += '-' * (Interface.PHY_LEN + Interface.INTERFACE_LEN + Interface.DRIVER_LEN + Interface.CHIPSET_LEN + 3)
return s
class Airmon(object):
''' Wrapper around the 'airmon-ng' program '''
base_interface = None
killed_network_manager = False
# Drivers that need to be manually put into monitor mode
BAD_DRIVERS = ['rtl8821au']
#see if_arp.h
ARPHRD_ETHER = 1 #managed
ARPHRD_IEEE80211_RADIOTAP = 803 #monitor
@@ -31,7 +69,7 @@ class Airmon(object):
def print_menu(self):
''' Prints menu '''
print(Interface.menu_header())
print(AirmonIface.menu_header())
for idx, iface in enumerate(self.interfaces, start=1):
Color.pl(" {G}%d{W}. %s" % (idx, iface))
@@ -44,44 +82,57 @@ class Airmon(object):
@staticmethod
def get_interfaces():
'''
Returns:
List of Interface objects known by airmon-ng
'''
'''Returns List of AirmonIface objects known by airmon-ng'''
interfaces = []
p = Process('airmon-ng')
for line in p.stdout().split('\n'):
# Ignore blank/header lines
if len(line) == 0 or line.startswith('Interface') or line.startswith('PHY'):
# [PHY ]IFACE DRIVER CHIPSET
airmon_re = re.compile(r'^(?:([^\t]*)\t+)?([^\t]*)\t+([^\t]*)\t+([^\t]*)$')
matches = airmon_re.match(line)
if not matches:
continue
# Strip out interface information
fields = line.split("\t")
while '' in fields:
fields.remove('')
# Add Interface object to list
interfaces.append(Interface(fields))
phy, interface, driver, chipset = matches.groups()
if phy == 'PHY' or phy == 'Interface':
continue # Header
interfaces.append(AirmonIface(phy, interface, driver, chipset))
return interfaces
@staticmethod
def start_baddriver(iface): #fix for bad drivers like the rtl8812AU
def start_bad_driver(iface):
'''
Manually put interface into monitor mode (no airmon-ng or vif).
Fix for bad drivers like the rtl8812AU.
'''
Ifconfig.down(iface)
Iwconfig.mode(iface, 'monitor')
Ifconfig.up(iface)
with open("/sys/class/net/" + iface + "/type", "r") as f:
# /sys/class/net/wlan0/type
iface_type_path = os.path.join('/sys/class/net', iface, 'type')
if os.path.exists(iface_type_path):
with open(iface_type_path, 'r') as f:
if (int(f.read()) == Airmon.ARPHRD_IEEE80211_RADIOTAP):
return iface
return None
@staticmethod
def stop_baddriver(iface):
def stop_bad_driver(iface):
'''
Manually put interface into managed mode (no airmon-ng or vif).
Fix for bad drivers like the rtl8812AU.
'''
Ifconfig.down(iface)
Iwconfig.mode(iface, 'managed')
Ifconfig.up(iface)
with open("/sys/class/net/" + iface + "/type", "r") as f:
# /sys/class/net/wlan0/type
iface_type_path = os.path.join('/sys/class/net', iface, 'type')
if os.path.exists(iface_type_path):
with open(iface_type_path, 'r') as f:
if (int(f.read()) == Airmon.ARPHRD_ETHER):
return iface
@@ -93,7 +144,7 @@ class Airmon(object):
Starts an interface (iface) in monitor mode
Args:
iface - The interface to start in monitor mode
Either an instance of Interface object,
Either an instance of AirmonIface object,
or the name of the interface (string).
Returns:
Name of the interface put into monitor mode.
@@ -101,95 +152,100 @@ class Airmon(object):
Exception - If an interface can't be put into monitor mode
'''
# Get interface name from input
if type(iface) == Interface:
iface = iface.interface
Airmon.base_interface = iface
if type(iface) == AirmonIface:
iface_name = iface.interface
driver = iface.driver
else:
iface_name = iface
driver = None
# Call airmon-ng
Color.p("{+} enabling {G}monitor mode{W} on {C}%s{W}... " % iface)
(out,err) = Process.call('airmon-ng start %s' % iface)
# Remember this as the "base" interface.
Airmon.base_interface = iface_name
mon_iface = Airmon._parse_airmon_start(out)
Color.p("{+} enabling {G}monitor mode{W} on {C}%s{W}... " % iface_name)
if mon_iface is None:
# Airmon did not enable monitor mode on an interface
mon_iface = Airmon.start_baddriver(iface)
airmon_output = Process(['airmon-ng', 'start', iface_name]).stdout()
if mon_iface is None:
enabled_iface = Airmon._parse_airmon_start(airmon_output)
if enabled_iface is None and driver in Airmon.BAD_DRIVERS:
Color.p('{O}"bad driver" detected{W} ')
enabled_iface = Airmon.start_bad_driver(iface_name)
if enabled_iface is None:
Color.pl("{R}failed{W}")
mon_ifaces = Airmon.get_interfaces_in_monitor_mode()
monitor_interfaces = Iwconfig.get_interfaces(mode='Monitor')
# Assert that there is an interface in monitor mode
if len(mon_ifaces) == 0:
if len(monitor_interfaces) == 0:
Color.pl("{R}failed{W}")
raise Exception("iwconfig does not see any interfaces in Mode:Monitor")
raise Exception("Cannot find any interfaces in Mode:Monitor")
# Assert that the interface enabled by airmon-ng is in monitor mode
if mon_iface not in mon_ifaces:
if enabled_iface not in monitor_interfaces:
Color.pl("{R}failed{W}")
raise Exception("iwconfig does not see %s in Mode:Monitor" % mon_iface)
raise Exception("Cannot find %s with Mode:Monitor" % enabled_iface)
# No errors found; the device 'mon_iface' was put into MM.
Color.pl("{G}enabled {C}%s{W}" % mon_iface)
# No errors found; the device 'enabled_iface' was put into Mode:Monitor.
Color.pl("{G}enabled {C}%s{W}" % enabled_iface)
Configuration.interface = mon_iface
return mon_iface
return enabled_iface
@staticmethod
def _parse_airmon_start(stdout):
# Find the interface put into monitor mode (if any)
mon_iface = None
for line in stdout.split('\n'):
if 'monitor mode' in line and 'enabled' in line and ' on ' in line:
mon_iface = line.split(' on ')[1]
if ']' in mon_iface:
mon_iface = mon_iface.split(']')[1]
if ')' in mon_iface:
mon_iface = mon_iface.split(')')[0]
break
return mon_iface
def _parse_airmon_start(airmon_output):
'''Find the interface put into monitor mode (if any)'''
# 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*')
for line in airmon_output.split('\n'):
matches = enabled_re.match(line)
if matches:
return matches.group(1)
return None
@staticmethod
def stop(iface):
Color.p("{!} {R}disabling {O}monitor mode{O} on {R}%s{O}... " % iface)
(out,err) = Process.call('airmon-ng stop %s' % iface)
mon_iface = None
for line in out.split('\n'):
# aircrack-ng 1.2 rc2
if 'monitor mode' in line and 'disabled' in line and ' for ' in line:
mon_iface = line.split(' for ')[1]
if ']' in mon_iface:
mon_iface = mon_iface.split(']')[1]
if ')' in mon_iface:
mon_iface = mon_iface.split(')')[0]
break
# aircrack-ng 1.2 rc1
match = re.search('([a-zA-Z0-9]+).*\(removed\)', line)
if match:
mon_iface = match.groups()[0]
break
airmon_output = Process(['airmon-ng', 'stop', iface]).stdout()
if not mon_iface:
mon_iface = Airmon.stop_baddriver(iface)
disabled_iface = Airmon._parse_airmon_stop(airmon_output)
if mon_iface:
Color.pl('{R}disabled %s{W}' % mon_iface)
if not disabled_iface and iface in Airmon.BAD_DRIVERS:
Color.p('{O}"bad driver" detected{W} ')
disabled_iface = Airmon.stop_bad_driver(iface)
if disabled_iface:
Color.pl('{G}disabled %s{W}' % disabled_iface)
else:
Color.pl('{O}could not disable on {R}%s{W}' % iface)
@staticmethod
def get_interfaces_in_monitor_mode():
'''
Uses 'iwconfig' to find all interfaces in monitor mode
Returns:
List of interface names that are in monitor mode
'''
return Iwconfig.get_interfaces(mode='Monitor')
def _parse_airmon_stop(airmon_output):
'''Find the interface taken out of into monitor mode (if any)'''
# airmon-ng 1.2rc2 output: (mac80211 monitor mode vif enabled for [phy10]wlan0 on [phy10]wlan0mon)
disabled_re = re.compile(r'\s*\(mac80211 monitor mode (?:vif )?disabled for (?:\[\w+\])?(\w+)\)\s*')
# airmon-ng 1.2rc1 output: wlan0mon (removed)
removed_re = re.compile(r'([a-zA-Z0-9]+).*\(removed\)')
disabled_iface = None
for line in airmon_output.split('\n'):
matches = disabled_re.match(line)
if matches:
return matches.group(1)
matches = removed_re.match(line)
if matches:
return matches.group(1)
return None
@staticmethod
@@ -198,20 +254,19 @@ class Airmon(object):
Asks user to define which wireless interface to use.
Does not ask if:
1. There is already an interface in monitor mode, or
2. There is only one wireles interface (automatically selected).
2. There is only one wireless interface (automatically selected).
Puts selected device into Monitor Mode.
'''
Airmon.terminate_conflicting_processes()
Color.pl('\n{+} looking for {C}wireless interfaces{W}')
mon_ifaces = Airmon.get_interfaces_in_monitor_mode()
mon_count = len(mon_ifaces)
if mon_count == 1:
monitor_interfaces = Iwconfig.get_interfaces(mode='Monitor')
if len(monitor_interfaces) == 1:
# Assume we're using the device already in montior mode
iface = mon_ifaces[0]
Color.pl('{+} using interface {G}%s{W} which is already in monitor mode'
% iface);
iface = monitor_interfaces[0]
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}')
Airmon.base_interface = None
return iface
@@ -240,7 +295,7 @@ class Airmon(object):
iface = a.get(choice)
if a.get(choice).interface in mon_ifaces:
if a.get(choice).interface in monitor_interfaces:
Color.pl('{+} {G}%s{W} is already in monitor mode' % iface.interface)
else:
iface.interface = Airmon.start(iface)
@@ -251,52 +306,48 @@ class Airmon(object):
def terminate_conflicting_processes():
''' Deletes conflicting processes reported by airmon-ng '''
'''
% airmon-ng check
airmon_output = Process(['airmon-ng', 'check']).stdout()
Found 3 processes that could cause trouble.
If airodump-ng, aireplay-ng or airtun-ng stops working after
a short period of time, you may want to kill (some of) them!
-e
PID Name
2272 dhclient
2293 NetworkManager
3302 wpa_supplicant
'''
# Conflicting process IDs and names
pid_pnames = []
out = Process(['airmon-ng', 'check']).stdout()
if 'processes that could cause trouble' not in out:
# No proceses to kill
# 2272 dhclient
# 2293 NetworkManager
pid_pname_re = re.compile(r'^\s*(\d+)\s*([a-zA-Z0-9_\-]+)\s*$')
for line in airmon_output.split('\n'):
match = pid_pname_re.match(line)
if match:
pid = match.group(1)
pname = match.group(2)
pid_pnames.append( (pid, pname) )
if len(pid_pnames) == 0:
return
hit_pids = False
for line in out.split('\n'):
if re.search('^ *PID', line):
hit_pids = True
continue
if not hit_pids or line.strip() == '':
continue
match = re.search('^[ \t]*(\d+)[ \t]*([a-zA-Z0-9_\-]+)[ \t]*$', line)
if match:
# Found process
pid = match.groups()[0]
pname = match.groups()[1]
if Configuration.kill_conflicting_processes:
if not Configuration.kill_conflicting_processes:
# Don't kill processes, warn user
for pid, pname in pid_pnames:
Color.pl('{!} {O}conflicting process: {R}%s{O} (PID {R}%s{O})' % (pname, pid))
Color.pl('{!} {O}if you have problems: {R}kill -9 PID{O} or re-run wifite with {R}--kill{O}){W}')
return
Color.pl('{!} {O}killing {R}%d {O}conflicting processes' % len(pid_pnames))
for pid, pname in pid_pnames:
if pname == 'NetworkManager' and Process.exists('service'):
Color.pl('{!} {O}stopping network-manager ({R}service network-manager stop{O})')
# Can't just pkill network manager; it's a service
Process(['service', 'network-manager', 'stop']).wait()
Airmon.killed_network_manager = True
else:
Color.pl('{!} {R}terminating {O}conflicting process {R}%s{O} (PID {R}%s{O})' % (pname, pid))
os.kill(int(pid), signal.SIGTERM)
if pname == 'NetworkManager':
Airmon.killed_network_manager= True
else:
Color.pl('{!} {O}conflicting process: {R}%s{O} (PID {R}%s{O})' % (pname, pid))
if not Configuration.kill_conflicting_processes:
Color.pl('{!} {O}if you have problems, try killing these processes ({R}kill -9 PID{O}){W}')
@staticmethod
def put_interface_up(iface):
Color.p("{!} {O}putting interface {R}%s up{O}..." % (iface))
Ifconfig.up(iface)
Color.pl(" {R}done{W}")
Color.pl(" {G}done{W}")
@staticmethod
def start_network_manager():

View File

@@ -16,9 +16,7 @@ class Airodump(object):
def __init__(self, interface=None, channel=None, encryption=None,\
wps=False, target_bssid=None, output_file_prefix='airodump',\
ivs_only=False, skip_wps=False):
'''
Sets up airodump arguments, doesn't start process yet
'''
'''Sets up airodump arguments, doesn't start process yet.'''
Configuration.initialize()
@@ -67,22 +65,15 @@ class Airodump(object):
'-w', self.csv_file_prefix, # Output file prefix
'--write-interval', '1' # Write every second
]
if self.channel:
command.extend(['-c', str(self.channel)])
elif self.five_ghz:
command.extend(['--band', 'a'])
if self.channel: command.extend(['-c', str(self.channel)])
elif self.five_ghz: command.extend(['--band', 'a'])
if self.encryption:
command.extend(['--enc', self.encryption])
if self.wps:
command.extend(['--wps'])
if self.target_bssid:
command.extend(['--bssid', self.target_bssid])
if self.encryption: command.extend(['--enc', self.encryption])
if self.wps: command.extend(['--wps'])
if self.target_bssid: command.extend(['--bssid', self.target_bssid])
if self.ivs_only:
command.extend(['--output-format', 'ivs,csv'])
else:
command.extend(['--output-format', 'pcap,csv'])
if self.ivs_only: command.extend(['--output-format', 'ivs,csv'])
else: command.extend(['--output-format', 'pcap,csv'])
# Start the process
self.pid = Process(command, devnull=True)
@@ -104,10 +95,14 @@ class Airodump(object):
def find_files(self, endswith=None):
''' Finds all files in the temp directory that start with the output_file_prefix '''
result = []
for fil in os.listdir(Configuration.temp()):
if fil.startswith(self.output_file_prefix):
temp = Configuration.temp()
for fil in os.listdir(temp):
if not fil.startswith(self.output_file_prefix):
continue
if not endswith or fil.endswith(endswith):
result.append(Configuration.temp() + fil)
result.append(os.path.join(temp, fil))
return result
def delete_airodump_temp_files(self):
@@ -130,14 +125,12 @@ class Airodump(object):
# Find the .CSV file
csv_filename = None
for fil in self.find_files(endswith='-01.csv'):
# Found the file
csv_filename = fil
csv_filename = fil # Found the file
break
if csv_filename is None or not os.path.exists(csv_filename):
# No file found
return self.targets
# Parse the .CSV file
if csv_filename is None or not os.path.exists(csv_filename):
return self.targets # No file found
targets = Airodump.get_targets_from_csv(csv_filename)
# Check targets for WPS
@@ -156,9 +149,12 @@ class Airodump(object):
# Sort by power
targets.sort(key=lambda x: x.power, reverse=True)
# Identify decloaked targets
for old_target in self.targets:
for new_target in targets:
if old_target.bssid != new_target.bssid: continue
if old_target.bssid != new_target.bssid:
continue
if new_target.essid_known and not old_target.essid_known:
# We decloaked a target!
new_target.decloaked = True
@@ -175,9 +171,7 @@ class Airodump(object):
@staticmethod
def get_targets_from_csv(csv_filename):
'''
Returns list of Target objects parsed from CSV file
'''
'''Returns list of Target objects parsed from CSV file.'''
targets = []
import csv
with open(csv_filename, 'rb') as csvopen:
@@ -275,11 +269,11 @@ class Airodump(object):
'''
self.decloaking = False
# Do not deauth if requested
if Configuration.no_deauth: return
if Configuration.no_deauth:
return # Do not deauth if requested
# Do not deauth if channel is not fixed.
if self.channel is None: return
if self.channel is None:
return # Do not deauth if channel is not fixed.
# Reusable deauth command
deauth_cmd = [
@@ -288,22 +282,27 @@ class Airodump(object):
str(Configuration.num_deauths), # Number of deauth packets to send
'--ignore-negative-one'
]
for target in self.targets:
if target.essid_known: continue
if target.essid_known:
continue
now = int(time.time())
secs_since_decloak = now - self.decloaked_times.get(target.bssid, 0)
# Decloak every AP once every 30 seconds
if secs_since_decloak < 30: continue
if secs_since_decloak < 30:
continue # Decloak every AP once every 30 seconds
self.decloaking = True
self.decloaked_times[target.bssid] = now
if Configuration.verbose > 1:
from ..util.color import Color
verbout = " [?] Deauthing %s" % target.bssid
verbout += " (broadcast & %d clients)" % len(target.clients)
Color.pe("\n{C}" + verbout + "{W}")
Color.pe('{C} [?] Deauthing %s (broadcast & %d clients){W}' % (target.bssid, len(target.clients)))
# Deauth broadcast
iface = Configuration.interface
Process(deauth_cmd + ['-a', target.bssid, iface])
# Deauth clients
for client in target.clients:
Process(deauth_cmd + ['-a', target.bssid, '-c', client.bssid, iface])

View File

@@ -18,7 +18,8 @@ class Ifconfig(object):
pid = Process(command)
pid.wait()
return pid.poll() == 0
if pid.poll() != 0:
raise Exception('Error putting interface %s up:\n%s\n%s' % (interface, pid.stdout(), pid.stderr()))
@classmethod
@@ -26,15 +27,10 @@ class Ifconfig(object):
'''Put interface down'''
from ..util.process import Process
command = ['ifconfig', interface, 'down']
if type(args) is list:
command.extend(args)
elif type(args) is 'str':
command.append(args)
pid = Process(command)
pid = Process(['ifconfig', interface, 'down'])
pid.wait()
return pid.poll() == 0
if pid.poll() != 0:
raise Exception('Error putting interface %s down:\n%s\n%s' % (interface, pid.stdout(), pid.stderr()))
@classmethod
@@ -43,11 +39,17 @@ class Ifconfig(object):
output = Process(['ifconfig', interface]).stdout()
mac_regex = ('[a-zA-Z0-9]{2}-' * 6)[:-1]
match = re.search(' (%s)' % mac_regex, output)
# Mac address separated by dashes
mac_dash_regex = ('[a-zA-Z0-9]{2}-' * 6)[:-1]
match = re.search(' ({})'.format(mac_dash_regex), output)
if match:
return match.group(1).replace('-', ':')
# Mac address separated by colons
mac_colon_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1]
match = re.search(' ({})'.format(mac_colon_regex), output)
if match:
return match.group(1)
if not match:
raise Exception('Could not find the mac address for %s' % interface)
return match.groups()[0].replace('-', ':')

View File

@@ -4,7 +4,9 @@
class Iwconfig(object):
@classmethod
def exists(cls):
pass
from ..util.process import Process
return Process.exists('iwconfig')
@classmethod
def mode(cls, iface, mode_name):
@@ -15,6 +17,7 @@ class Iwconfig(object):
return pid.poll()
@classmethod
def get_interfaces(cls, mode=None):
from ..util.process import Process
@@ -34,5 +37,6 @@ class Iwconfig(object):
if mode is not None and 'Mode:{}'.format(mode) in line:
interfaces.add(iface)
return list(interfaces)

View File

@@ -6,76 +6,80 @@ from ..tools.ifconfig import Ifconfig
from ..util.color import Color
class Macchanger(object):
is_init = False
is_changed = False
original_mac = None
@classmethod
def init(cls):
if cls.is_init: return
from ..config import Configuration
iface = Configuration.interface
if type(iface) == Interface:
iface = iface.interface
cls.original_mac = Ifconfig.get_mac(iface)
cls.is_init = True
@classmethod
def down_macch_up(cls, macch_option):
cls.init()
def down_macch_up(cls, iface, options):
'''Put interface down, run macchanger with options, put interface up'''
from ..util.process import Process
from ..config import Configuration
iface = Configuration.interface
Color.clear_entire_line()
Color.p("\r{+} {C}macchanger{W}: Taking interface {C}%s{W} down..." % iface)
Color.p('\r{+} {C}macchanger{W}: taking interface {C}%s{W} down...' % iface)
if Ifconfig.down(iface) != 0:
Color.pl("{!} {C}macchanger{W}: Error running %s" % " ".join(cmd))
Color.pl("{!} Output: %s, %s" % (ifdown.stdout(), ifdown.stderr()))
return False
Ifconfig.down(iface)
cmd = ["macchanger", macch_option, iface]
Color.clear_entire_line()
Color.p("\r{+} {C}macchanger{W}: Changing MAC address of interface {C}%s{W}..." % iface)
macch = Process(cmd)
Color.p('\r{+} {C}macchanger{W}: changing mac address of interface {C}%s{W}...' % iface)
command = ['macchanger']
command.extend(options)
command.append(iface)
macch = Process(command)
macch.wait()
if macch.poll() != 0:
Color.pl("{!} {C}macchanger{W}: Error running %s" % " ".join(cmd))
Color.pl("{!} Output: %s, %s" % (macch.stdout(), macch.stderr()))
Color.pl('\n{!} {R}macchanger{O}: error running {R}%s{O}' % ' '.join(command))
Color.pl('{!} {R}output: {O}%s, %s{W}' % (macch.stdout(), macch.stderr()))
return False
Color.clear_entire_line()
Color.p("\r{+} {C}macchanger{W}: Bringing interface {C}%s{W} up..." % iface)
Color.p('\r{+} {C}macchanger{W}: bringing interface {C}%s{W} up...' % iface)
Ifconfig.up(iface)
if Ifconfig.up(iface) != 0:
Color.pl("{!} {C}macchanger{W}: Error running %s" % " ".join(cmd))
Color.pl("{!} Output: %s, %s" % (ifup.stdout(), ifup.stderr()))
return False
return True
@classmethod
def get_interface(cls):
# Helper method to get interface from configuration
from ..config import Configuration
return Configuration.interface
@classmethod
def reset(cls):
# --permanent to reset to permanent MAC address
if not cls.down_macch_up("-p"): return
Color.pl("\r{+} {C}macchanger{W}: Resetting MAC address...")
from ..config import Configuration
new_mac = Ifconfig.get_mac(Configuration.interface)
iface = cls.get_interface()
Color.pl('\r{+} {C}macchanger{W}: resetting mac address on %s...' % iface)
# -p to reset to permanent MAC address
if cls.down_macch_up(iface, ['-p']):
new_mac = Ifconfig.get_mac(iface)
Color.clear_entire_line()
Color.pl("\r{+} {C}macchanger{W}: Reset MAC address back to {C}%s{W}" % new_mac)
Color.pl('\r{+} {C}macchanger{W}: reset mac address back to {C}%s{W} on {C}%s{W}' % (new_mac, iface))
@classmethod
def random(cls):
# Use --permanent to use random MAC address
if not cls.down_macch_up("-r"): return
from ..util.process import Process
if not Process.exists('macchanger'):
Color.pl('{!} {R}macchanger: {O}not installed')
return
iface = cls.get_interface()
Color.pl('\n{+} {C}macchanger{W}: changing mac address on {C}%s{W}' % iface)
# -r to use random MAC address
# -e to keep vendor bytes the same
if cls.down_macch_up(iface, ['-e']):
cls.is_changed = True
from ..config import Configuration
new_mac = Ifconfig.get_mac(Configuration.interface)
new_mac = Ifconfig.get_mac(iface)
Color.clear_entire_line()
Color.pl("\r{+} {C}macchanger{W}: Changed MAC address to {C}%s{W}" % new_mac)
Color.pl('\r{+} {C}macchanger{W}: changed mac address to {C}%s{W} on {C}%s{W}' % (new_mac, iface))
@classmethod
def reset_if_changed(cls):
if not cls.is_changed: return
if cls.is_changed:
cls.reset()

View File

@@ -45,17 +45,13 @@ class Color(object):
@staticmethod
def pl(text):
'''
Prints text using colored format with trailing new line.
'''
'''Prints text using colored format with trailing new line.'''
Color.p('%s\n' % text)
Color.last_sameline_length = 0
@staticmethod
def pe(text):
'''
Prints text using colored format with leading and trailing new line to STDERR.
'''
'''Prints text using colored format with leading and trailing new line to STDERR.'''
sys.stderr.write(Color.s('%s\n' % text))
Color.last_sameline_length = 0
@@ -85,14 +81,14 @@ class Color(object):
@staticmethod
def pattack(attack_type, target, attack_name, progress):
'''
Prints a one-liner for an attack
Includes attack type (WEP/WPA), target BSSID/ESSID & power, attack type, and progress
[name] ESSID (MAC @ Pwr) Attack_Type: Progress
e.g.: [WEP] Router2G (00:11:22 @ 23db) replay attack: 102 IVs
Prints a one-liner for an attack.
Includes attack type (WEP/WPA), target ESSID & power, attack type, and progress.
ESSID (Pwr) Attack_Type: Progress
e.g.: Router2G (23db) WEP replay attack: 102 IVs
'''
essid = "{C}%s{W}" % target.essid if target.essid_known else "{O}unknown{W}"
Color.p("\r{+} {G}%s{W} ({C}%s @ %sdb{W}) {G}%s {C}%s{W}: %s " % (
essid, target.bssid, target.power, attack_type, attack_name, progress))
Color.p("\r{+} {G}%s{W} ({C}%sdb{W}) {G}%s {C}%s{W}: %s " % (
essid, target.power, attack_type, attack_name, progress))
if __name__ == '__main__':
Color.pl("{R}Testing{G}One{C}Two{P}Three{W}Done")