diff --git a/wifi_deauth.py b/wifi_deauth.py index 41320de..1a64ef8 100644 --- a/wifi_deauth.py +++ b/wifi_deauth.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 -"""airodump-ng CSV parsing + wireless-interface discovery for the wifi deauth tool.""" +"""CSV parsing, interface discovery, and monitor-mode + card-state handling.""" import os import re import subprocess import sys import tempfile +import time def run(cmd, timeout=30): @@ -58,6 +59,59 @@ def _phy_has_monitor(phy): return False +class CardState: + def __init__(self, iface): + self.orig_iface = iface["iface"] + self.orig_addr = iface["addr"] + self.nm_was_active = ( + run(["systemctl", "is-active", "NetworkManager"]).stdout.strip() == "active" + ) + self.mon_iface = None + self.used_airmon = False + + +def enable_monitor(state): + run(["airmon-ng", "check", "kill"]) + before = {i["iface"] for i in list_wifi_interfaces()} + res = run(["airmon-ng", "start", state.orig_iface]) + state.used_airmon = True + time.sleep(1) + after = list_wifi_interfaces() + new = {i["iface"] for i in after} - before + if new: + state.mon_iface = new.pop() + else: + m = re.search(r"enabled (?:for \[[^\]]+\]\S+ )?on (?:\[[^\]]+\])?(\S+?)\)", res.stdout) + if m: + state.mon_iface = m.group(1) + else: + for i in after: + if i["iface"] == state.orig_iface and i["type"] == "monitor": + state.mon_iface = state.orig_iface + if not state.mon_iface: + raise RuntimeError("Could not determine monitor interface:\n" + res.stdout + res.stderr) + return state.mon_iface + + +def reset_card(state): + if not state: + return + if state.mon_iface and state.used_airmon: + run(["airmon-ng", "stop", state.mon_iface]) + names = {i["iface"]: i for i in list_wifi_interfaces()} + if state.orig_iface not in names and state.mon_iface in names: + run(["iw", state.mon_iface, "set", "type", "managed"]) + run(["ip", "link", "set", state.mon_iface, "name", state.orig_iface]) + names = {i["iface"]: i for i in list_wifi_interfaces()} + it = names.get(state.orig_iface) + if it and state.orig_addr not in ("?", None) and it["addr"].lower() != state.orig_addr.lower(): + run(["ip", "link", "set", state.orig_iface, "down"]) + run(["ip", "link", "set", state.orig_iface, "address", state.orig_addr]) + run(["ip", "link", "set", state.orig_iface, "up"]) + if state.nm_was_active: + run(["systemctl", "start", "NetworkManager"]) + + def parse_airodump_csv(path): try: with open(path, encoding="utf-8", errors="replace") as f: