Skip to content

network-ops 2.0: multi-agent pipeline + tool gap fills#78

Draft
mkultraWasHere wants to merge 8 commits into
mainfrom
nops/ma
Draft

network-ops 2.0: multi-agent pipeline + tool gap fills#78
mkultraWasHere wants to merge 8 commits into
mainfrom
nops/ma

Conversation

@mkultraWasHere

@mkultraWasHere mkultraWasHere commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Restructure network-ops from a single monolithic agent into a coordinated multi-agent pipeline following the ASM pattern, then fill critical tool gaps.

Added

  • Worker-coordinated pipeline with 6 stages: scope normalization → network discovery → AD enumeration → exploitation → credential harvesting → report synthesis (workers/coordinator.py)
  • 6 pipeline agents in agents/pipeline/ — each scoped to a single phase with explicit stage boundaries
  • network-ops-agent updated with pipeline-vs-direct decision criteria, skill references, and specific tool names
  • run_netops_pipeline tool for programmatic pipeline invocation (tools/pipeline.py)
  • 3 skills: network-ops-methodology (hard rules, confidence levels, anti-patterns), ad-enumeration-playbook (decision tree, tool mapping), ad-attack-patterns (attack chain sequences, coercion/relay/lateral movement method selection)
  • 5 lateral movement tools wrapping existing impacket scripts: impacket_wmiexec, impacket_psexec, impacket_smbexec, impacket_atexec, impacket_dcomexec
  • Coercion toolset (tools/coercion.py) wrapping PetitPotam (MS-EFSRPC), DFSCoerce (MS-DFSNM), ShadowCoerce (MS-FSRVP)
  • smb_upload_file on SmbClient for staging files to remote shares
  • 20 coordinator unit tests covering scope validation, finding extraction, prompt data threading, and naming conventions

Changed

  • capability.yaml bumped to 2.0.0 with agents/, skills/, tools/, workers/ auto-load sections and loguru dependency
  • _extract_findings in coordinator filters to credentials, hashes, and weaknesses only — drops enumeration noise
  • Agent turn timeout raised from 45s to 300s; stage budget caps raised to realistic levels (6/30/40/50/30/10)
  • Timeout detection uses a [NETOPS_STAGE_TIMEOUT] sentinel instead of substring matching

Fixed

  • smbclient methods now check binary existence before executing, returning an install hint instead of a raw traceback
  • Coercion tool wrappers validate script paths via _resolve_script() with clear FileNotFoundError messages
  • Pipeline tool (tools/pipeline.py) stubs loguru when loading coordinator in-process, preventing ModuleNotFoundError

Notes

  • network-ops-agent name preserved for backwards compatibility — existing TUI selections and configs continue to work
  • Agent stage boundaries are documented but not runtime-enforced — agents see all 118 tools
  • Coercion and lateral movement tools require their underlying binaries/scripts installed (impacket, PetitPotam, DFSCoerce, ShadowCoerce, smbclient)
  • No integration tests against live AD — coordinator unit tests cover pure logic only

mkultraWasHere and others added 4 commits July 7, 2026 17:24
Decompose the monolithic network-ops-agent into a 6-stage coordinated
pipeline following the attack-surface-management pattern. Adds worker
coordinator, pipeline launcher tool, methodology and tactical skills,
and specialized pipeline agents for each phase of AD exploitation.

- Replace single agent with netops-operator (standalone) + 6 pipeline
  agents (scope-normalizer, discovery-operator, ad-enumerator,
  exploit-operator, credential-harvester, report-synthesizer)
- Add coordinator worker with event-driven orchestration, stage budgets,
  timeout handling, and deterministic synthesis fallback
- Add run_netops_pipeline tool for programmatic pipeline invocation
- Add 3 skills: network-ops-methodology (hard rules, confidence levels,
  anti-patterns), ad-enumeration-playbook (decision tree, tool mapping),
  ad-attack-patterns (attack chain sequences)
- Add coordinator unit tests (20 tests covering scope validation,
  finding extraction, prompt threading, naming conventions)
- Bump to 2.0.0 (breaking: new pipeline architecture)

Co-Authored-By: Claude <noreply@anthropic.com>
Wrap five impacket remote execution scripts that were available but
not exposed as tool methods: wmiexec, psexec, smbexec, atexec, and
dcomexec. These fill the critical gap where the agent could recover
credentials and confirm admin access but had no way to execute
commands on remote hosts.

Update exploit-operator and credential-harvester stage boundaries
and add lateral movement method selection guidance to the
ad-attack-patterns skill.

Co-Authored-By: Claude <noreply@anthropic.com>
Add Coercion toolset wrapping PetitPotam (MS-EFSRPC), DFSCoerce
(MS-DFSNM), and ShadowCoerce (MS-FSRVP) for authentication coercion
in relay attack chains. Add smb_upload_file to SmbClient for staging
files on remote shares.

Update ad-attack-patterns skill with NTLM relay chain, coercion
method selection table, and exploit-operator stage boundaries.

Co-Authored-By: Claude <noreply@anthropic.com>
All three SmbClient methods now verify smbclient is on PATH before
executing, returning a clear install hint instead of a raw traceback.

Co-Authored-By: Claude <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades the network-ops capability to a 2.0 multi-agent “ASM-style” pipeline coordinated by a worker, adds an agent-facing launcher tool, and fills key AD attack tooling gaps (lateral movement + coercion), along with methodology/playbook skills.

Changes:

  • Added a 6-stage worker-coordinated pipeline (netops.engagement.* events) with per-stage agents and unit tests for coordinator logic.
  • Added an agent tool to launch/monitor the pipeline (run_netops_pipeline) and introduced a new netops-operator agent (replacing network-ops-agent).
  • Expanded tooling for real engagements: SMB upload support, new Impacket lateral-movement wrappers, and RPC coercion wrappers.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
capabilities/network-ops/workers/coordinator.py New worker coordinating the staged multi-agent pipeline and report synthesis.
capabilities/network-ops/tools/smbclient.py Adds smbclient binary checks and introduces SMB upload support.
capabilities/network-ops/tools/pipeline.py Adds run_netops_pipeline launcher + runtime monitoring + direct coordinator fallback import.
capabilities/network-ops/tools/impacket.py Adds lateral movement wrappers (wmiexec/psexec/smbexec/atexec/dcomexec).
capabilities/network-ops/tools/coercion.py Adds coercion wrappers for PetitPotam/DFSCoerce/ShadowCoerce.
capabilities/network-ops/tests/test_worker_coordinator.py Adds unit tests for coordinator scope handling, prompt threading, findings extraction, and utilities.
capabilities/network-ops/skills/network-ops-methodology/SKILL.md Adds methodology “hard rules” + confidence/severity standards for netops.
capabilities/network-ops/skills/ad-enumeration-playbook/SKILL.md Adds AD enumeration decision tree and tool mapping.
capabilities/network-ops/skills/ad-attack-patterns/SKILL.md Adds AD attack-chain reference with coercion/lateral movement guidance.
capabilities/network-ops/capability.yaml Bumps to 2.0.0 and enables auto-loading for agents/skills/tools/workers + adds loguru dep.
capabilities/network-ops/agents/pipeline/scope-normalizer.md New dedicated scope normalization pipeline agent.
capabilities/network-ops/agents/pipeline/discovery-operator.md New dedicated discovery/scanning pipeline agent.
capabilities/network-ops/agents/pipeline/ad-enumerator.md New dedicated AD enumeration pipeline agent.
capabilities/network-ops/agents/pipeline/exploit-operator.md New dedicated exploitation pipeline agent (pre-harvest).
capabilities/network-ops/agents/pipeline/credential-harvester.md New dedicated credential dumping/cracking/verification pipeline agent.
capabilities/network-ops/agents/pipeline/report-synthesizer.md New dedicated report synthesis pipeline agent.
capabilities/network-ops/agents/network-ops-agent.md Removes the legacy monolithic agent (breaking change).
capabilities/network-ops/agents/netops-operator.md Adds replacement operator agent with pipeline-vs-direct decision criteria + skill references.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread capabilities/network-ops/tools/pipeline.py
Comment thread capabilities/network-ops/tools/pipeline.py
Comment thread capabilities/network-ops/tools/smbclient.py
Comment thread capabilities/network-ops/tools/smbclient.py Outdated
Comment thread capabilities/network-ops/tools/coercion.py
mkultraWasHere and others added 2 commits July 8, 2026 12:19
Keep the user-facing agent name as network-ops-agent to avoid breaking
existing TUI selections and saved configurations. Pipeline agents use
the netops-* prefix internally but the standalone agent name stays the
same as 1.x.

Co-Authored-By: Claude <noreply@anthropic.com>
- Restore loguru stub in sys.modules after coordinator import (pipeline.py)
- Fix max_steps docstring: per-stage clamp, not total budget (pipeline.py)
- Sanitize SMB paths to prevent smbclient command injection via ; and !
- Guard local_path against UnboundLocalError in smb_upload_file finally
- Include real repo URLs in coercion _resolve_script error messages

Co-Authored-By: Claude <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.


# --- Stage 2: Network Discovery ---
await _publish_progress(client, run_id, "discovery_started")
discovery_report, _ = await _run_agent_turn(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partially confirmed. Discovery tool_calls intentionally stay discarded — discovery only reports Targets/Services/DCs which _extract_findings filters out anyway. Fixed enumeration in 3f50678 since it can report Weakness items (unconstrained delegation, writable ACLs).

Comment thread capabilities/network-ops/workers/coordinator.py Outdated
# --- Stage 6: Report Synthesis ---
await _publish_progress(client, run_id, "report_synthesis_started")

all_tool_calls = exploit_tool_calls + harvest_tool_calls

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 3f50678all_tool_calls now includes enumeration_tool_calls + exploit_tool_calls + harvest_tool_calls. Discovery stays excluded since it only produces Target/Service/DC items that _extract_findings filters out.

Enumeration stage can report Weakness items via report_item (e.g.,
unconstrained delegation, writable ACLs). These were discarded with
`_` and not included in the structured findings for synthesis.

Co-Authored-By: Claude <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 4 comments.

@worker.on_event(REQUEST_EVENT)
async def run_engagement(event: EventEnvelope, client: RuntimeClient) -> None:
"""Run one network operations engagement pipeline end to end."""
payload = event.payload or {}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refuted. EventEnvelope.payload is typed dict | None in the dreadnode framework — the runtime never delivers non-dict payloads. The or {} handles the None case. ASM's coordinator uses the identical pattern at line 69.

Comment on lines +3193 to +3205
args.extend(
self._build_auth_flags(
hashes=hashes, kerberos=kerberos, aes_key=aes_key, password=password
)
)
args.extend(self._build_connection_flags(dc_ip=dc_ip, target_ip=target_ip))

return await execute(
self._build_script_command("wmiexec.py", args),
timeout=timeout or self.timeout + 60,
input=input,
env=env,
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6c48209 — sends exit\n via stdin when no command is given, so the shell terminates and returns the banner promptly.

Comment on lines +3307 to +3314
identity = self._build_identity_with_target(
target, domain=domain, username=username, password=password
)

args = [identity]
if command:
args.append(command)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6c48209 — same exit\n stdin pattern applied to psexec for consistency with wmiexec and dcomexec.

Comment on lines +3690 to +3702
args.extend(
self._build_auth_flags(
hashes=hashes, kerberos=kerberos, aes_key=aes_key, password=password
)
)
args.extend(self._build_connection_flags(dc_ip=dc_ip, target_ip=target_ip))

return await execute(
self._build_script_command("dcomexec.py", args),
timeout=timeout or self.timeout + 60,
input=input,
env=env,
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6c48209 — sends exit\n via stdin when command=None, matching the wmiexec fix.

wmiexec, psexec, and dcomexec hang until timeout when called without
a command since the underlying scripts launch an interactive shell.
Now send exit via stdin when no command is given so the process
terminates and returns the banner promptly.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants