def post_scanning_configurations(self): # Escrever num ficheiro depois ler se for chamado no airhost card = NetworkCard(self.ap_interface) max_supported_access_points = card.get_number_of_supported_aps() print "Max aps: ", max_supported_access_points if self.max_access_points > max_supported_access_points: print "[-] max_access_points is higher than what card supports. Setting to {}".format( max_supported_access_points) self.max_access_points = max_supported_access_points self.aplauncher = APLauncher(self.hostapd_conf) self.dnsmasqhandler = DNSMasqHandler(self.dnsmasq_conf) rand_mac = "52:54:00:%02x:%02x:%02x" % (randint(0, 255), randint( 0, 255), randint(0, 255)) final_list = [] if len(self.lonely_probes) < self.max_access_points: print "[+] Adding all requested ssids to hostapd configuration." for probe in self.lonely_probes: print "[+] Adding '{}' with hit_count '{}' to hostapd configuration".format( probe, self.hit_count[probe]) final_list = list(self.lonely_probes) SessionManager().log_event( NeutralEvent("Added all found probes to Karma list.")) else: inverted_popular_ssids = { hit_count: ssid for ssid, hit_count in self.hit_count.iteritems() } ordered_popularity = sorted(inverted_popular_ssids.keys())[::-1] for i in ordered_popularity: popular_ssid = inverted_popular_ssids[i] final_list.append(popular_ssid) print "[+] Adding '{}' with hit_count '{}' to hostapd configuration".format( popular_ssid, self.hit_count[popular_ssid]) SessionManager().log_event( NeutralEvent( "Added '{}' to Karma list.".format(popular_ssid))) if len(final_list) == self.max_access_points: break self.number_of_configured_nets = len(final_list) NetworkManager().set_mac_and_unmanage(self.ap_interface, rand_mac, True, self.number_of_configured_nets) self.dnsmasqhandler.set_captive_portal_mode(self.captive_portal) self.dnsmasqhandler.write_dnsmasq_configurations( self.ap_interface, card.get_ip(), [ ".".join(card.get_ip().split(".")[:3] + ["2"]), ".".join(card.get_ip().split(".")[:3] + ["254"]) ], ["8.8.8.8", "8.8.4.4"], len(final_list)) self.aplauncher.write_hostapd_configurations(self.ap_interface, final_list, rand_mac)
def __init__(self, hostapd_config_path, dnsmasq_config_path): # Mandatory configuration files to start the access point successfully if (dnsmasq_config_path == None or hostapd_config_path == None) : raise MissingConfigurationFileException("dnsmasq and hostapd configuration files must be specified\n \ either by argument in the command line or in the etf.conf file") self.aplauncher = APLauncher(hostapd_config_path) self.dnsmasqhandler = DNSMasqHandler(dnsmasq_config_path) self.running_interface = None self.plugins = []
def __init__(self, config): """The AirHost module constructor.""" # Mandatory configuration files to start the access point successfully if (not isfile(config["dnsmasq_conf"]) or not isfile(config["hostapd_conf"])): raise MissingConfigurationFileException( "dnsmasq and hostapd configuration files must be specified\n \ either by argument in the command line or in the etf.conf file" ) self.aplauncher = APLauncher(config["hostapd_conf"]) self.dnsmasqhandler = DNSMasqHandler(config["dnsmasq_conf"]) self.running_interface = None self.plugins = []
def __init__(self, config): """The AirHost module constructor.""" # Mandatory configuration files to start the access point successfully if (not isfile(config["dnsmasq_conf"]) or not isfile(config["hostapd_conf"])): raise MissingConfigurationFileException("dnsmasq and hostapd configuration files must be specified\n \ either by argument in the command line or in the etf.conf file") self.aplauncher = APLauncher(config["hostapd_conf"]) self.dnsmasqhandler = DNSMasqHandler(config["dnsmasq_conf"]) self.running_interface = None self.plugins = []
def post_scanning_configurations(self): # Escrever num ficheiro depois ler se for chamado no airhost card = NetworkCard(self.ap_interface) max_supported_access_points = card.get_number_of_supported_aps() print "Max aps: ", max_supported_access_points if self.max_access_points > max_supported_access_points: print "[-] max_access_points is higher than what card supports. Setting to {}".format(max_supported_access_points) self.max_access_points = max_supported_access_points self.aplauncher = APLauncher(self.hostapd_conf) self.dnsmasqhandler = DNSMasqHandler(self.dnsmasq_conf) rand_mac = "52:54:00:%02x:%02x:%02x" % (randint(0, 255), randint(0, 255), randint(0, 255)) final_list = [] if len(self.lonely_probes) < self.max_access_points: print "[+] Adding all requested ssids to hostapd configuration." for probe in self.lonely_probes: print "[+] Adding '{}' with hit_count '{}' to hostapd configuration".format(probe, self.hit_count[probe]) final_list = list(self.lonely_probes) SessionManager().log_event(NeutralEvent("Added all found probes to Karma list.")) else: inverted_popular_ssids = { hit_count : ssid for ssid, hit_count in self.hit_count.iteritems() } ordered_popularity = sorted(inverted_popular_ssids.keys())[::-1] for i in ordered_popularity: popular_ssid = inverted_popular_ssids[i] final_list.append(popular_ssid) print "[+] Adding '{}' with hit_count '{}' to hostapd configuration".format(popular_ssid, self.hit_count[popular_ssid]) SessionManager().log_event(NeutralEvent("Added '{}' to Karma list.".format(popular_ssid))) if len(final_list) == self.max_access_points: break self.number_of_configured_nets = len(final_list) NetworkManager().set_mac_and_unmanage( self.ap_interface, rand_mac, True, self.number_of_configured_nets) self.dnsmasqhandler.set_captive_portal_mode(self.captive_portal) self.dnsmasqhandler.write_dnsmasq_configurations(self.ap_interface, card.get_ip(), [ ".".join(card.get_ip().split(".")[:3] + ["2"]), ".".join(card.get_ip().split(".")[:3] + ["254"]) ], ["8.8.8.8", "8.8.4.4"], len(final_list)) self.aplauncher.write_hostapd_configurations( self.ap_interface, final_list, rand_mac)
class AirHost(object): def __init__(self, hostapd_config_path, dnsmasq_config_path): # Mandatory configuration files to start the access point successfully if (dnsmasq_config_path == None or hostapd_config_path == None): raise MissingConfigurationFileException( "dnsmasq and hostapd configuration files must be specified\n \ either by argument in the command line or in the etf.conf file" ) self.aplauncher = APLauncher(hostapd_config_path) self.dnsmasqhandler = DNSMasqHandler(dnsmasq_config_path) self.running_interface = None self.plugins = [] def add_plugin(self, airhost_plugin): self.plugins.append(airhost_plugin) def start_access_point(self, interface): print "[+] Killing already started processes and restarting network services" self.stop_access_point( False ) # Restarting services helps avoiding some conflicts with dnsmasq for plugin in self.plugins: plugin.start() self.aplauncher.start_access_point(interface) if not self.dnsmasqhandler.start_dnsmasq(): print "[-] Error starting dnsmasq, aborting AP launch" return False self.running_interface = interface print "[+] Access Point launched successfully" return True def stop_access_point(self, free_plugins=True): print "[+] Stopping dnsmasq and hostapd services" self.aplauncher.stop_access_point() self.dnsmasqhandler.stop_dnsmasq() self.running_interface = None print "[+] Access Point stopped, restarting network services..." os.system('service networking restart') os.system('service NetworkManager restart') if free_plugins: for plugin in self.plugins: plugin.restore() del self.plugins[:] def is_running(self): return self.running_interface != None def cleanup(self): self.dnsmasqhandler.cleanup() self.aplauncher.cleanup()
class Karma(AirHostPlugin): def __init__(self, config): super(Karma, self).__init__(config, "karma") self.scan_time = self.config["scan_time"] # It will configure the hostapd file according self.ap_interface = self.config["ap_interface"] try: self.max_access_points = int(self.config["max_access_points"]) except: self.max_access_points = 1 self.dnsmasq_conf = self.config["dnsmasq_conf"] self.hostapd_conf = self.config["hostapd_conf"] self.aplauncher = None self.dnsmasqhandler = None self.ghost_ap = self.config["ghost_ap"].lower() == "true" self.captive_portal = self.config["captive_portal_mode"].lower( ) == "true" self.present_networks = set() self.lonely_probes = set() self.hit_count = {} # ssid: count self.number_of_configured_nets = 0 self.should_stop = False def pre_start(self): # Prepare Threads sniffer_thread = Thread(target=self.sniff_packets) printer_thread = Thread(target=self.print_status) # Start Threads and Timer sniffer_thread.start() printer_thread.start() self.stop_timer() SessionManager().log_event( NeutralEvent("Karma plugin sniffing for probe requests.")) # Wait for sniffer to finish sniffer_thread.join() # Configure hostapd and dnsmasq self.post_scanning_configurations() # Has to reconfigure interfaces after they are set up def post_start(self): # Wait for hostapd to setup all the access points sleep(1) card = NetworkCard(self.ap_interface) if card is not None: gateway = card.get_ip() for i in range(self.number_of_configured_nets - 1): interface_name = "{}_{}".format(self.ap_interface, i) if interface_name in pyw.winterfaces(): gateway = ".".join( gateway.split(".")[0:2] + [str(int(gateway.split(".")[2]) + 1)] + [gateway.split(".")[3]]) NetUtils().interface_config(interface_name, card.get_ip()) NetUtils().set_interface_mtu(interface_name, 1800) NetUtils().accept_forwarding(interface_name) self.dnsmasqhandler.start_dnsmasq() def print_status(self): print "[+] Starting Karma Sniffer thread and timer for {} seconds".format( self.scan_time) seconds = 0 while seconds < int(self.scan_time): sleep(5) seconds += 5 print "[+] Karma Sniffer running for {} seconds".format(seconds) print "[/] Probed ssids so far:" for ssid, count in self.hit_count.iteritems(): print "\t", ssid, count print "[+] Karma Sniffer finished scanning, will now configure hostapd" def sniff_packets(self): card = NetworkCard(self.ap_interface) if card.get_mode() != "monitor": card.set_mode("monitor") try: sniff(iface=self.ap_interface, store=0, prn=self.handle_packet, stop_filter=(lambda pkt: self.should_stop)) except Exception as e: print e print "[-] Exception occurred while sniffing on interface '{}'".format( self.ap_interface) self.should_stop = False if card.get_mode() != "managed": card.set_mode("managed") def stop_timer(self): try: sleep(int(self.scan_time)) except: print "[-] Karma scan time must be integer. Defaulting to 30 seconds." sleep(30) self.should_stop = True def handle_packet(self, packet): is_client_packet = False if Dot11Beacon in packet: packet = Beacon(packet) elif Dot11ProbeResp in packet: packet = ProbeResponse(packet) elif Dot11ProbeReq in packet: packet = ProbeRequest(packet) is_client_packet = True else: return if is_client_packet and packet.ssid is not None and packet.ssid != "": self.lonely_probes.add(packet.ssid) try: self.hit_count[packet.ssid] += 1 except: self.hit_count[packet.ssid] = 1 SessionManager().log_event( NeutralEvent("Karma found Probe Request for '{}'".format( packet.ssid))) else: self.present_networks.add(packet.ssid) if self.ghost_ap: self.lonely_probes -= self.present_networks def post_scanning_configurations(self): # Escrever num ficheiro depois ler se for chamado no airhost card = NetworkCard(self.ap_interface) max_supported_access_points = card.get_number_of_supported_aps() print "Max aps: ", max_supported_access_points if self.max_access_points > max_supported_access_points: print "[-] max_access_points is higher than what card supports. Setting to {}".format( max_supported_access_points) self.max_access_points = max_supported_access_points self.aplauncher = APLauncher(self.hostapd_conf) self.dnsmasqhandler = DNSMasqHandler(self.dnsmasq_conf) rand_mac = "52:54:00:%02x:%02x:%02x" % (randint(0, 255), randint( 0, 255), randint(0, 255)) final_list = [] if len(self.lonely_probes) < self.max_access_points: print "[+] Adding all requested ssids to hostapd configuration." for probe in self.lonely_probes: print "[+] Adding '{}' with hit_count '{}' to hostapd configuration".format( probe, self.hit_count[probe]) final_list = list(self.lonely_probes) SessionManager().log_event( NeutralEvent("Added all found probes to Karma list.")) else: inverted_popular_ssids = { hit_count: ssid for ssid, hit_count in self.hit_count.iteritems() } ordered_popularity = sorted(inverted_popular_ssids.keys())[::-1] for i in ordered_popularity: popular_ssid = inverted_popular_ssids[i] final_list.append(popular_ssid) print "[+] Adding '{}' with hit_count '{}' to hostapd configuration".format( popular_ssid, self.hit_count[popular_ssid]) SessionManager().log_event( NeutralEvent( "Added '{}' to Karma list.".format(popular_ssid))) if len(final_list) == self.max_access_points: break self.number_of_configured_nets = len(final_list) NetworkManager().set_mac_and_unmanage(self.ap_interface, rand_mac, True, self.number_of_configured_nets) self.dnsmasqhandler.set_captive_portal_mode(self.captive_portal) self.dnsmasqhandler.write_dnsmasq_configurations( self.ap_interface, card.get_ip(), [ ".".join(card.get_ip().split(".")[:3] + ["2"]), ".".join(card.get_ip().split(".")[:3] + ["254"]) ], ["8.8.8.8", "8.8.4.4"], len(final_list)) self.aplauncher.write_hostapd_configurations(self.ap_interface, final_list, rand_mac)
class AirHost(object): """ The AirHost class. Receives the hostapd and dnsmasq config path to configure and launch the services. """ def __init__(self, hostapd_config_path, dnsmasq_config_path): """The AirHost module constructor.""" # Mandatory configuration files to start the access point successfully if (dnsmasq_config_path is None or hostapd_config_path is None): raise MissingConfigurationFileException("dnsmasq and hostapd configuration files must be specified\n \ either by argument in the command line or in the etf.conf file") self.aplauncher = APLauncher(hostapd_config_path) self.dnsmasqhandler = DNSMasqHandler(dnsmasq_config_path) self.running_interface = None self.plugins = [] def add_plugin(self, airhost_plugin): """Add an AirHostPlugin to this module instance.""" self.plugins.append(airhost_plugin) def start_access_point(self, interface, print_credentials): """ This method starts an access point on the specified interface. It assumes that the interface is umanaged. It also starts the DHCP and DNS servers with dnsmasq alongside the access point so it is instantly fully functional. Access Point configurations are read by the APLauncher. The print_credentials flag is used by the APLauncher to print out EAP credentials caught by hostapd-wpe. """ print "[+] Killing already started processes and restarting network services" # Restarting services helps avoiding some conflicts with dnsmasq self.stop_access_point(False) print "[+] Running airhost plugins pre_start" for plugin in self.plugins: plugin.pre_start() self.aplauncher.print_creds = print_credentials self.aplauncher.start_access_point(interface) if not self.dnsmasqhandler.start_dnsmasq(): print "[-] Error starting dnsmasq, aborting AP launch" return False print "[+] Running airhost plugins post_start" for plugin in self.plugins: plugin.post_start() self.running_interface = interface print "[+] Access Point launched successfully" return True def stop_access_point(self, free_plugins = True): """This method cleanly stops the access point and all its background services.""" print "[+] Stopping dnsmasq and hostapd services" self.aplauncher.stop_access_point() self.dnsmasqhandler.stop_dnsmasq() self.running_interface = None print "[+] Access Point stopped..." for plugin in self.plugins: plugin.stop() if free_plugins and len(self.plugins) > 0: for plugin in self.plugins: plugin.restore() del self.plugins[:] print "[+] Cleared Airhost plugins" def is_running(self): """Checks if the access point is active.""" return self.running_interface is not None def cleanup(self): """Cleanup method for the airhost module.""" self.dnsmasqhandler.cleanup() self.aplauncher.cleanup()
class AirHost(object): """ The AirHost class. Receives the hostapd and dnsmasq config path to configure and launch the services. """ def __init__(self, config): """The AirHost module constructor.""" # Mandatory configuration files to start the access point successfully if (not isfile(config["dnsmasq_conf"]) or not isfile(config["hostapd_conf"])): raise MissingConfigurationFileException("dnsmasq and hostapd configuration files must be specified\n \ either by argument in the command line or in the etf.conf file") self.aplauncher = APLauncher(config["hostapd_conf"]) self.dnsmasqhandler = DNSMasqHandler(config["dnsmasq_conf"]) self.running_interface = None self.plugins = [] def add_plugin(self, airhost_plugin): """Add an AirHostPlugin to this module instance.""" self.plugins.append(airhost_plugin) def start_access_point(self, interface, print_credentials): """ This method starts an access point on the specified interface. It assumes that the interface is umanaged. It also starts the DHCP and DNS servers with dnsmasq alongside the access point so it is instantly fully functional. Access Point configurations are read by the APLauncher. The print_credentials flag is used by the APLauncher to print out EAP credentials caught by hostapd-wpe. """ SessionManager().log_event(NeutralEvent("Starting AirHost module.")) print "[+] Killing already started processes and restarting network services" # Restarting services helps avoiding some conflicts with dnsmasq self.stop_access_point(False) print "[+] Running airhost plugins pre_start" for plugin in self.plugins: plugin.pre_start() self.aplauncher.print_creds = print_credentials self.aplauncher.start_access_point(interface) if not self.dnsmasqhandler.start_dnsmasq(): SessionManager().log_event(UnsuccessfulEvent( "Error starting dnsmasq. AirHost module start was aborted."), True) self.stop_access_point() return False self.running_interface = interface print "[+] Running airhost plugins post_start" for plugin in self.plugins: plugin.post_start() print "[+] Access Point launched successfully" SessionManager().log_event(SuccessfulEvent("AirHost module started successfully.")) return True def stop_access_point(self, free_plugins = True): """This method cleanly stops the access point and all its background services.""" for plugin in self.plugins: SessionManager().log_event(NeutralEvent("Running pre_stop method for '{}' plugin.".format(plugin))) plugin.pre_stop() print "[+] Stopping dnsmasq and hostapd services" self.aplauncher.stop_access_point() self.dnsmasqhandler.stop_dnsmasq() self.running_interface = None SessionManager().log_event(NeutralEvent("AirHost module stopped.")) print "[+] Access Point stopped..." for plugin in self.plugins: SessionManager().log_event(NeutralEvent("Running post_stop method for '{}' plugin.".format(plugin))) plugin.post_stop() if free_plugins and len(self.plugins) > 0: for plugin in self.plugins: SessionManager().log_event(NeutralEvent( "Running restore method for '{}' plugin.".format(plugin))) plugin.restore() del self.plugins[:] print "[+] Cleared Airhost plugins" def is_running(self): """Checks if the access point is active.""" return self.running_interface is not None def cleanup(self): """Cleanup method for the airhost module.""" self.dnsmasqhandler.cleanup() self.aplauncher.cleanup()
class Karma(AirHostPlugin): def __init__(self, config): super(Karma, self).__init__(config, "karma") self.scan_time = self.config["scan_time"] # It will configure the hostapd file according self.ap_interface = self.config["ap_interface"] try: self.max_access_points = int(self.config["max_access_points"]) except: self.max_access_points = 1 self.dnsmasq_conf = self.config["dnsmasq_conf"] self.hostapd_conf = self.config["hostapd_conf"] self.aplauncher = None self.dnsmasqhandler = None self.ghost_ap = self.config["ghost_ap"].lower() == "true" self.captive_portal = self.config["captive_portal_mode"].lower() == "true" self.present_networks = set() self.lonely_probes = set() self.hit_count = {} # ssid: count self.number_of_configured_nets = 0 self.should_stop = False def pre_start(self): # Prepare Threads sniffer_thread = Thread(target=self.sniff_packets) printer_thread = Thread(target=self.print_status) # Start Threads and Timer sniffer_thread.start() printer_thread.start() self.stop_timer() SessionManager().log_event(NeutralEvent("Karma plugin sniffing for probe requests.")) # Wait for sniffer to finish sniffer_thread.join() # Configure hostapd and dnsmasq self.post_scanning_configurations() # Has to reconfigure interfaces after they are set up def post_start(self): # Wait for hostapd to setup all the access points sleep(1) card = NetworkCard(self.ap_interface) if card is not None: gateway = card.get_ip() for i in range(self.number_of_configured_nets - 1): interface_name = "{}_{}".format(self.ap_interface, i) if interface_name in pyw.winterfaces(): gateway = ".".join(gateway.split(".")[0:2] + [str(int(gateway.split(".")[2]) + 1)] + [gateway.split(".")[3]]) NetUtils().interface_config(interface_name, card.get_ip()) NetUtils().set_interface_mtu(interface_name, 1800) NetUtils().accept_forwarding(interface_name) self.dnsmasqhandler.start_dnsmasq() def print_status(self): print "[+] Starting Karma Sniffer thread and timer for {} seconds".format(self.scan_time) seconds = 0 while seconds < int(self.scan_time): sleep(5) seconds += 5 print "[+] Karma Sniffer running for {} seconds".format(seconds) print "[/] Probed ssids so far:" for ssid, count in self.hit_count.iteritems(): print "\t", ssid, count print "[+] Karma Sniffer finished scanning, will now configure hostapd" def sniff_packets(self): card = NetworkCard(self.ap_interface) if card.get_mode() != "monitor": card.set_mode("monitor") try: sniff(iface=self.ap_interface, store=0, prn=self.handle_packet, stop_filter= (lambda pkt: self.should_stop)) except Exception as e: print e print "[-] Exception occurred while sniffing on interface '{}'".format(self.ap_interface) self.should_stop = False if card.get_mode() != "managed": card.set_mode("managed") def stop_timer(self): try: sleep(int(self.scan_time)) except: print "[-] Karma scan time must be integer. Defaulting to 30 seconds." sleep(30) self.should_stop = True def handle_packet(self, packet): is_client_packet = False if Dot11Beacon in packet: packet = Beacon(packet) elif Dot11ProbeResp in packet: packet = ProbeResponse(packet) elif Dot11ProbeReq in packet: packet = ProbeRequest(packet) is_client_packet = True else: return if is_client_packet and packet.ssid is not None and packet.ssid != "": self.lonely_probes.add(packet.ssid) try: self.hit_count[packet.ssid] += 1 except: self.hit_count[packet.ssid] = 1 SessionManager().log_event(NeutralEvent("Karma found Probe Request for '{}'".format(packet.ssid))) else: self.present_networks.add(packet.ssid) if self.ghost_ap: self.lonely_probes -= self.present_networks def post_scanning_configurations(self): # Escrever num ficheiro depois ler se for chamado no airhost card = NetworkCard(self.ap_interface) max_supported_access_points = card.get_number_of_supported_aps() print "Max aps: ", max_supported_access_points if self.max_access_points > max_supported_access_points: print "[-] max_access_points is higher than what card supports. Setting to {}".format(max_supported_access_points) self.max_access_points = max_supported_access_points self.aplauncher = APLauncher(self.hostapd_conf) self.dnsmasqhandler = DNSMasqHandler(self.dnsmasq_conf) rand_mac = "52:54:00:%02x:%02x:%02x" % (randint(0, 255), randint(0, 255), randint(0, 255)) final_list = [] if len(self.lonely_probes) < self.max_access_points: print "[+] Adding all requested ssids to hostapd configuration." for probe in self.lonely_probes: print "[+] Adding '{}' with hit_count '{}' to hostapd configuration".format(probe, self.hit_count[probe]) final_list = list(self.lonely_probes) SessionManager().log_event(NeutralEvent("Added all found probes to Karma list.")) else: inverted_popular_ssids = { hit_count : ssid for ssid, hit_count in self.hit_count.iteritems() } ordered_popularity = sorted(inverted_popular_ssids.keys())[::-1] for i in ordered_popularity: popular_ssid = inverted_popular_ssids[i] final_list.append(popular_ssid) print "[+] Adding '{}' with hit_count '{}' to hostapd configuration".format(popular_ssid, self.hit_count[popular_ssid]) SessionManager().log_event(NeutralEvent("Added '{}' to Karma list.".format(popular_ssid))) if len(final_list) == self.max_access_points: break self.number_of_configured_nets = len(final_list) NetworkManager().set_mac_and_unmanage( self.ap_interface, rand_mac, True, self.number_of_configured_nets) self.dnsmasqhandler.set_captive_portal_mode(self.captive_portal) self.dnsmasqhandler.write_dnsmasq_configurations(self.ap_interface, card.get_ip(), [ ".".join(card.get_ip().split(".")[:3] + ["2"]), ".".join(card.get_ip().split(".")[:3] + ["254"]) ], ["8.8.8.8", "8.8.4.4"], len(final_list)) self.aplauncher.write_hostapd_configurations( self.ap_interface, final_list, rand_mac)