| 114 | requirements = {'system': ["aircrack-ng/airodump-ng"]} |
| 115 | |
| 116 | def scan(self, interface, timeout=300, silent=False): |
| 117 | if not silent: |
| 118 | self.logger.warning("Press Ctrl+C to interrupt") |
| 119 | s = self.console.state['STATIONS'] |
| 120 | t = self.console.state['TARGETS'] |
| 121 | p = self.console.state['PASSWORDS'] |
| 122 | s.unlock() |
| 123 | t.unlock() |
| 124 | cmd = "sudo airodump-ng {}".format(interface) |
| 125 | try: |
| 126 | for line in self.console._jobs.run_iter(cmd, timeout=int(timeout)): |
| 127 | # parse AP-related line for its WiFi information |
| 128 | m = TARGET_REGEX.search(line) |
| 129 | if m is not None: |
| 130 | # when matching, recreate the data dictionary |
| 131 | data = {} |
| 132 | for k in ["essid", "bssid", "channel", "power", "enc", "cipher", "auth"]: |
| 133 | v = m.group(k) |
| 134 | data[k] = int(v) if v.isdigit() and k != "essid" else v |
| 135 | e = data['essid'] |
| 136 | data['password'] = p.get(e) |
| 137 | data['stations'] = [] |
| 138 | if self._filter_func(e): |
| 139 | if e not in t.keys(): |
| 140 | self.logger.info("Found {}".format(e)) |
| 141 | else: |
| 142 | # when updating, do not forget to copy previous extra information |
| 143 | for k in ['password', 'stations']: |
| 144 | data[k] = t[e].get(k) |
| 145 | t[e] = data |
| 146 | continue |
| 147 | # parse client-related line for its MAC address |
| 148 | m = STATION_REGEX.search(line) |
| 149 | if m is not None: |
| 150 | e = [tgt for tgt, data in t.items() if data['bssid'] == m.group("bssid")] |
| 151 | if len(e) == 1: |
| 152 | e = e[0] |
| 153 | sta = m.group("station") |
| 154 | if sta in self.console.root.self_mac_addresses: |
| 155 | continue |
| 156 | if sta not in t[e]['stations']: |
| 157 | # first remove from the list of stations for the old ESSID |
| 158 | if sta in s.keys() and sta in t[s[sta]]['stations']: |
| 159 | t[s[sta]]['stations'].remove(sta) |
| 160 | # now add the station to the list for the new ESSID |
| 161 | t[e]['stations'].append(sta) |
| 162 | self.logger.info("Found {} connected to {}".format(sta, e)) |
| 163 | s[sta] = e |
| 164 | except Exception as err: |
| 165 | self.logger.exception(err) |
| 166 | finally: |
| 167 | s.lock() |
| 168 | t.lock() |
| 169 | |