diff --git a/capabilities/network-ops/capability.yaml b/capabilities/network-ops/capability.yaml index 7016351..1f7ee57 100644 --- a/capabilities/network-ops/capability.yaml +++ b/capabilities/network-ops/capability.yaml @@ -1,6 +1,6 @@ schema: 1 name: network-ops -version: "2.1.1" +version: "2.1.2" description: > Network operations and Active Directory exploitation. Multi-agent pipeline for autonomous red teaming with Nmap scanning, Netexec diff --git a/capabilities/network-ops/scripts/install_coercion_tools.sh b/capabilities/network-ops/scripts/install_coercion_tools.sh index 27438be..5e65ab0 100755 --- a/capabilities/network-ops/scripts/install_coercion_tools.sh +++ b/capabilities/network-ops/scripts/install_coercion_tools.sh @@ -8,7 +8,7 @@ set -euo pipefail # runtime Python can't import impacket, install it explicitly. if ! python3 -c "import impacket" 2>/dev/null; then echo "[+] Installing impacket into runtime Python" - python3 -m pip install --quiet "impacket>=0.12.0" 2>/dev/null \ + python3 -m pip install --quiet "impacket>=0.12.0" \ || python3 -m pip install --quiet --break-system-packages "impacket>=0.12.0" else echo "[*] impacket already importable, skipping" diff --git a/capabilities/network-ops/tools/impacket.py b/capabilities/network-ops/tools/impacket.py index fef4fcb..f3bd0c2 100644 --- a/capabilities/network-ops/tools/impacket.py +++ b/capabilities/network-ops/tools/impacket.py @@ -60,6 +60,51 @@ def _extract_real_path_from_wrapper(wrapper_path: Path) -> Path | None: return None +def _ensure_impacket_installed() -> None: + """Install impacket into the running Python if it's not importable. + + The runtime may not process ``dependencies.python`` from + ``capability.yaml``, so we do a best-effort pip install at import + time as a fallback. + + Set ``DREADNODE_SKIP_AUTO_INSTALL=1`` to disable (useful in tests/CI). + """ + if os.environ.get("DREADNODE_SKIP_AUTO_INSTALL", "").strip() in ("1", "true", "yes"): + return + + try: + import impacket as _ # noqa: F401 + except ImportError: + import subprocess + + logger.warning("impacket not importable — attempting pip install") + for extra_args in ([], ["--break-system-packages"]): + try: + subprocess.run( + [ + sys.executable, + "-m", + "pip", + "install", + "--quiet", + "impacket>=0.12.0", + *extra_args, + ], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + check=True, + timeout=120, + ) + logger.info("impacket installed successfully") + return + except (subprocess.CalledProcessError, subprocess.TimeoutExpired, OSError): + continue + logger.error("Failed to install impacket — impacket tools will not work") + + +_ensure_impacket_installed() + + def _get_impacket_script_path() -> Path: """ Auto-discover the impacket scripts directory.