aegis-node 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
aegis_node/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ """Aegis WiFi Node Agent — connects a local USB WiFi adapter to the Aegis portal."""
2
+ __version__ = '0.1.0'
3
+
4
+ DEFAULT_SERVER = 'https://portal.aegis.divoltbtc.com'
aegis_node/__main__.py ADDED
@@ -0,0 +1,4 @@
1
+ """Allow `python -m aegis_node`."""
2
+ from .agent import main
3
+
4
+ main()
aegis_node/adapters.py ADDED
@@ -0,0 +1,128 @@
1
+ """USB WiFi adapter detection and capability probing."""
2
+ from __future__ import annotations
3
+
4
+ import logging
5
+ import re
6
+ import shutil
7
+ import subprocess
8
+
9
+ log = logging.getLogger('aegis.wifi_node.adapters')
10
+
11
+ # VID:PID → (chipset, driver, monitor_default, inject_default)
12
+ KNOWN_ADAPTERS: dict[str, tuple[str, str, bool, bool]] = {
13
+ # Proven pentest adapters
14
+ '0e8d:7612': ('MT7612U', 'mt76x2u', True, True),
15
+ '148f:761a': ('MT7612U', 'mt76x2u', True, True),
16
+ '0b05:17d1': ('MT7612U', 'mt76x2u', True, True), # ASUS USB-AC54
17
+ '0cf3:9271': ('AR9271', 'ath9k_htc', True, True), # Alfa AWUS036NHA
18
+ '0bda:8812': ('RTL8812AU', 'rtl8812au', True, True),
19
+ '0bda:881a': ('RTL8812AU', 'rtl8812au', True, True),
20
+ '0846:9052': ('RTL8812AU', 'rtl8812au', True, True), # Netgear A6100
21
+ '0bda:8187': ('RTL8187L', 'rtl8187', True, True), # WIFISKY WS-980WG
22
+ # Managed-mode only
23
+ '0bda:c832': ('RTL8832CU', 'rtl8832cu', False, False), # NEWFAST NF-U353
24
+ '0bda:b832': ('RTL8832CU', 'rtl8832cu', False, False),
25
+ '0bda:c82c': ('RTL8822CU', 'rtl8822cu', False, False),
26
+ '0bda:8179': ('RTL8188EUS', 'rtl8188eu', False, False),
27
+ '2357:011e': ('RTL8812AU', 'rtl8812au', True, True), # TP-Link T4U
28
+ }
29
+
30
+
31
+ def _run(cmd: list[str], timeout: int = 10) -> str:
32
+ try:
33
+ r = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
34
+ return r.stdout + r.stderr
35
+ except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
36
+ return ''
37
+
38
+
39
+ def detect_adapters() -> list[dict]:
40
+ """Detect USB WiFi adapters via lsusb + iw dev."""
41
+ adapters = []
42
+ lsusb = _run(['lsusb'])
43
+ for line in lsusb.splitlines():
44
+ m = re.match(r'Bus \d+ Device \d+: ID (\w{4}:\w{4})\s+(.*)', line)
45
+ if not m:
46
+ continue
47
+ vid_pid = m.group(1).lower()
48
+ desc = m.group(2).strip()
49
+ if vid_pid not in KNOWN_ADAPTERS:
50
+ continue
51
+ chipset, driver, mon_default, inj_default = KNOWN_ADAPTERS[vid_pid]
52
+ adapters.append({
53
+ 'vid_pid': vid_pid,
54
+ 'chipset': chipset,
55
+ 'driver': driver,
56
+ 'description': desc,
57
+ 'cap_monitor_mode': mon_default,
58
+ 'cap_injection': inj_default,
59
+ })
60
+
61
+ # Enrich with iw interface info
62
+ iw_out = _run(['iw', 'dev'])
63
+ ifaces = _parse_iw_dev(iw_out)
64
+ for a in adapters:
65
+ for iface in ifaces:
66
+ if iface.get('type') == 'managed':
67
+ a.setdefault('interface', iface['name'])
68
+ a.setdefault('mac', iface.get('addr', ''))
69
+ break
70
+
71
+ return adapters
72
+
73
+
74
+ def _parse_iw_dev(output: str) -> list[dict]:
75
+ """Parse `iw dev` output into a list of interface dicts."""
76
+ ifaces = []
77
+ current: dict | None = None
78
+ for line in output.splitlines():
79
+ line = line.strip()
80
+ if line.startswith('Interface'):
81
+ if current:
82
+ ifaces.append(current)
83
+ current = {'name': line.split()[-1]}
84
+ elif current:
85
+ if line.startswith('addr'):
86
+ current['addr'] = line.split()[-1]
87
+ elif line.startswith('type'):
88
+ current['type'] = line.split()[-1]
89
+ if current:
90
+ ifaces.append(current)
91
+ return ifaces
92
+
93
+
94
+ def probe_monitor_mode(interface: str) -> bool:
95
+ """Test if an interface supports monitor mode via iw."""
96
+ if not interface:
97
+ return False
98
+ out = _run(['iw', 'phy'])
99
+ return 'monitor' in out.lower()
100
+
101
+
102
+ def probe_injection(interface: str) -> bool:
103
+ """Test packet injection via aireplay-ng (requires monitor mode active)."""
104
+ if not shutil.which('aireplay-ng'):
105
+ return False
106
+ out = _run(['aireplay-ng', '--test', interface], timeout=15)
107
+ return 'Injection is working!' in out
108
+
109
+
110
+ def detect_host_tools() -> dict[str, bool]:
111
+ """Check which security tools are available on the host."""
112
+ tools = {}
113
+ for tool in ('airmon-ng', 'airodump-ng', 'aireplay-ng', 'aircrack-ng',
114
+ 'nmap', 'hashcat', 'hcxdumptool', 'hcxpcapngtool',
115
+ 'hostapd', 'dnsmasq', 'tcpdump', 'tshark', 'iw', 'iwconfig',
116
+ 'reaver', 'arpspoof', 'macchanger'):
117
+ tools[tool] = shutil.which(tool) is not None
118
+ return tools
119
+
120
+
121
+ def get_host_info() -> dict:
122
+ """Collect host OS and hostname."""
123
+ import platform
124
+ return {
125
+ 'os': f'{platform.system()} {platform.release()}',
126
+ 'hostname': platform.node(),
127
+ 'tools': detect_host_tools(),
128
+ }