aegis-node 0.1.0__tar.gz

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.
@@ -0,0 +1,76 @@
1
+ Metadata-Version: 2.4
2
+ Name: aegis-node
3
+ Version: 0.1.0
4
+ Summary: Aegis WiFi Node Agent — connect a local USB WiFi adapter to the Aegis pentest platform
5
+ Author-email: Divolt <hello@divoltbtc.com>
6
+ License-Expression: LicenseRef-Proprietary
7
+ Project-URL: Homepage, https://divoltbtc.com
8
+ Project-URL: Documentation, https://portal.aegis.divoltbtc.com
9
+ Keywords: pentest,wifi,wireless,security,aegis
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Information Technology
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Security
16
+ Requires-Python: >=3.9
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: requests>=2.28
19
+
20
+ # Aegis WiFi Node Agent
21
+
22
+ Connect a local USB WiFi adapter to the [Aegis](https://divoltbtc.com) pentest platform for wireless network assessments.
23
+
24
+ ## Install
25
+
26
+ ```bash
27
+ pipx install aegis-node
28
+ ```
29
+
30
+ If pipx is not available:
31
+
32
+ ```bash
33
+ pip install --user aegis-node
34
+ ```
35
+
36
+ ## Quick start
37
+
38
+ ```bash
39
+ # 1. Check system readiness
40
+ aegis-node preflight
41
+
42
+ # 2. Auto-install missing tools (requires sudo)
43
+ aegis-node preflight --install
44
+
45
+ # 3. Connect to Aegis (opens browser for authorization)
46
+ aegis-node connect
47
+ ```
48
+
49
+ The `connect` command opens your browser to authorize the device.
50
+ Confirm the verification code matches your terminal, click **Authorize Device**, and the agent connects automatically.
51
+
52
+ ## Options
53
+
54
+ ```
55
+ aegis-node connect # browser auth (default server)
56
+ aegis-node connect --no-browser # print URL instead of opening browser
57
+ aegis-node connect --server URL # custom server URL
58
+ aegis-node preflight # check adapter + tools
59
+ aegis-node preflight --install # auto-install missing tools
60
+ ```
61
+
62
+ ## Requirements
63
+
64
+ - Linux (Kali recommended) or WSL2
65
+ - Python 3.9+
66
+ - USB WiFi adapter with monitor mode support (e.g., WIFISKY WS-980WG, Alfa AWUS036ACM)
67
+ - aircrack-ng, nmap, hashcat, tcpdump (auto-installed via `preflight --install`)
68
+
69
+ ## Supported adapters
70
+
71
+ | Adapter | Chipset | Monitor | Inject | Bands |
72
+ |---------|---------|---------|--------|-------|
73
+ | WIFISKY WS-980WG | RTL8187L | Yes | Yes | 2.4 GHz |
74
+ | Alfa AWUS036ACM | MT7612U | Yes | Yes | 2.4+5 GHz |
75
+ | Alfa AWUS036ACH | RTL8812AU | Yes | Yes | 2.4+5 GHz |
76
+ | Alfa AWUS036NHA | AR9271 | Yes | Yes | 2.4 GHz |
@@ -0,0 +1,57 @@
1
+ # Aegis WiFi Node Agent
2
+
3
+ Connect a local USB WiFi adapter to the [Aegis](https://divoltbtc.com) pentest platform for wireless network assessments.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pipx install aegis-node
9
+ ```
10
+
11
+ If pipx is not available:
12
+
13
+ ```bash
14
+ pip install --user aegis-node
15
+ ```
16
+
17
+ ## Quick start
18
+
19
+ ```bash
20
+ # 1. Check system readiness
21
+ aegis-node preflight
22
+
23
+ # 2. Auto-install missing tools (requires sudo)
24
+ aegis-node preflight --install
25
+
26
+ # 3. Connect to Aegis (opens browser for authorization)
27
+ aegis-node connect
28
+ ```
29
+
30
+ The `connect` command opens your browser to authorize the device.
31
+ Confirm the verification code matches your terminal, click **Authorize Device**, and the agent connects automatically.
32
+
33
+ ## Options
34
+
35
+ ```
36
+ aegis-node connect # browser auth (default server)
37
+ aegis-node connect --no-browser # print URL instead of opening browser
38
+ aegis-node connect --server URL # custom server URL
39
+ aegis-node preflight # check adapter + tools
40
+ aegis-node preflight --install # auto-install missing tools
41
+ ```
42
+
43
+ ## Requirements
44
+
45
+ - Linux (Kali recommended) or WSL2
46
+ - Python 3.9+
47
+ - USB WiFi adapter with monitor mode support (e.g., WIFISKY WS-980WG, Alfa AWUS036ACM)
48
+ - aircrack-ng, nmap, hashcat, tcpdump (auto-installed via `preflight --install`)
49
+
50
+ ## Supported adapters
51
+
52
+ | Adapter | Chipset | Monitor | Inject | Bands |
53
+ |---------|---------|---------|--------|-------|
54
+ | WIFISKY WS-980WG | RTL8187L | Yes | Yes | 2.4 GHz |
55
+ | Alfa AWUS036ACM | MT7612U | Yes | Yes | 2.4+5 GHz |
56
+ | Alfa AWUS036ACH | RTL8812AU | Yes | Yes | 2.4+5 GHz |
57
+ | Alfa AWUS036NHA | AR9271 | Yes | Yes | 2.4 GHz |
@@ -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'
@@ -0,0 +1,4 @@
1
+ """Allow `python -m aegis_node`."""
2
+ from .agent import main
3
+
4
+ main()
@@ -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
+ }