Skip to content

SSH mixin: New functions to help populate workspaces#21479

Open
g0tmi1k wants to merge 8 commits into
rapid7:masterfrom
g0tmi1k:ssh_mixin
Open

SSH mixin: New functions to help populate workspaces#21479
g0tmi1k wants to merge 8 commits into
rapid7:masterfrom
g0tmi1k:ssh_mixin

Conversation

@g0tmi1k
Copy link
Copy Markdown
Contributor

@g0tmi1k g0tmi1k commented May 19, 2026

This PR adds various new functions, with the goal to help auto update/populate the workspace:

  • connect_ssh()
  • connect_ssh_transport()
  • grab_ssh_banner()
  • report_ssh_host() - report_host() & report_note(ssh.cpe) via Recog (same as FTP mixin)
  • report_ssh_hostkeys() - report_note(ssh.hostkey)
  • report_ssh_service() - report_service()
    • Also able to report_host(), when host is up but the service is down or incorrect

All modules to use connect_ssh() & connect_ssh_transport() were applicable.

Examples of this being used:


This is a little older demo

Before

  • Hosts: 10.0.0.10 (Metasploitable 2)
  • Servies: Missing banner & parent
  • Notes: 0
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean
$ ./msfconsole -q -x 'workspace -D;
use auxiliary/scanner/ssh/ssh_enumusers;
set RHOSTS 10.0.0.10;
set USERNAME msfadmin;
run;'
[*] Deleted workspace: default
[*] Recreated the default workspace
[*] Setting default action Malformed Packet - view all 2 actions with the show actions command
RHOSTS => 10.0.0.10
USERNAME => msfadmin
[*] 10.0.0.10:22 - SSH - Using malformed packet technique
[*] 10.0.0.10:22 - SSH - Checking for false positives
[*] 10.0.0.10:22 - SSH - Starting scan
[+] 10.0.0.10:22 - SSH - User 'msfadmin' found
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ssh/ssh_enumusers) > workspace -v

Workspaces
==========

current  name     hosts  services  vulns  creds  loots  notes
-------  ----     -----  --------  -----  -----  -----  -----
*        default  1      1         0      1      0      0

msf auxiliary(scanner/ssh/ssh_enumusers) > hosts

Hosts
=====

address    mac  name  os_name  os_flavor  os_sp  purpose  info  comments
-------    ---  ----  -------  ---------  -----  -------  ----  --------
10.0.0.10

msf auxiliary(scanner/ssh/ssh_enumusers) > services
Services
========

host       port  proto  name  state  info  resource  parents
----       ----  -----  ----  -----  ----  --------  -------
10.0.0.10  22    tcp    ssh   open         {}

msf auxiliary(scanner/ssh/ssh_enumusers) >

After

  • Hosts: OS info added
  • Servies: SSH banner included & Added parent (matches other modules/mixins)
  • Notes: 2x
$ git checkout ssh_mixin
branch 'ssh_mixin' set up to track 'origin/ssh_mixin'.
Switched to a new branch 'ssh_mixin'
$ ./msfconsole -q -x 'workspace -D;
use auxiliary/scanner/ssh/ssh_enumusers;
set RHOSTS 10.0.0.10;
set USERNAME msfadmin;
run;'
[*] Deleted workspace: default
[*] Recreated the default workspace
[*] Setting default action Malformed Packet - view all 2 actions with the show actions command
RHOSTS => 10.0.0.10
USERNAME => msfadmin
[*] 10.0.0.10:22 - SSH - Using malformed packet technique
[*] 10.0.0.10:22 - SSH - Checking for false positives
[*] 10.0.0.10:22 - SSH - Starting scan
[+] 10.0.0.10:22 - SSH - User 'msfadmin' found
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ssh/ssh_enumusers) > workspace -v

Workspaces
==========

current  name     hosts  services  vulns  creds  loots  notes
-------  ----     -----  --------  -----  -----  -----  -----
*        default  1      2         0      1      0      2

msf auxiliary(scanner/ssh/ssh_enumusers) > hosts

Hosts
=====

address    mac  name  os_name  os_flavor  os_sp  purpose  info  comments
-------    ---  ----  -------  ---------  -----  -------  ----  --------
10.0.0.10             Linux    Ubuntu     8.04   server

msf auxiliary(scanner/ssh/ssh_enumusers) > services
Services
========

host       port  proto  name  state  info                                   resource  parents
----       ----  -----  ----  -----  ----                                   --------  -------
10.0.0.10  22    tcp    ssh   open   SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1  {}        tcp (22/tcp)
10.0.0.10  22    tcp    tcp   open                                          {}

msf auxiliary(scanner/ssh/ssh_enumusers) > notes

Notes
=====

 Time                     Host       Service  Port  Protocol  Type         Data
 ----                     ----       -------  ----  --------  ----         ----
 2026-05-19 06:30:57 UTC  10.0.0.10  ssh      22    tcp       ssh.cpe      {:cpe=>"cpe:/o:canonical:ubuntu_linux:8.04"}
 2026-05-19 06:30:57 UTC  10.0.0.10  ssh      22    tcp       ssh.hostkey  {:type=>"ssh-rsa", :fingerprint=>"SHA256:BQHm5EoHX9GCiOLuVscegPXLQOsuPs+E9d/rrJB84rk"}

msf auxiliary(scanner/ssh/ssh_enumusers) >

@g0tmi1k
Copy link
Copy Markdown
Contributor Author

g0tmi1k commented May 19, 2026

Before: * default 1 1 1 0 0 0
After: * default 1 2 1 0 0 2

Before

$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ ./msfconsole -q -x 'workspace -D;
use auxiliary/scanner/ssh/ssh_version;
set RHOSTS 10.0.0.10;
run;'
[...]
[*] Auxiliary module execution completed
msf auxiliary(scanner/ssh/ssh_version) > workspace -v

Workspaces
==========

current  name     hosts  services  vulns  creds  loots  notes
-------  ----     -----  --------  -----  -----  -----  -----
*        default  1      1         1      0      0      0

msf auxiliary(scanner/ssh/ssh_version) > hosts

Hosts
=====

address    mac  name  os_name  os_flavor  os_sp  purpose  info  comments
-------    ---  ----  -------  ---------  -----  -------  ----  --------
10.0.0.10             Linux               8.04   server

msf auxiliary(scanner/ssh/ssh_version) > services
Services
========

host       port  proto  name  state  info                                   resource  parents
----       ----  -----  ----  -----  ----                                   --------  -------
10.0.0.10  22    tcp    ssh   open   SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1  {}

msf auxiliary(scanner/ssh/ssh_version) >

After

$ git checkout ssh_mixin
Switched to branch 'ssh_mixin'
Your branch is up to date with 'origin/ssh_mixin'.
$ ./msfconsole -q -x 'workspace -D;
use auxiliary/scanner/ssh/ssh_version;
set RHOSTS 10.0.0.10;
run;'
[...]
[*] Auxiliary module execution completed
msf auxiliary(scanner/ssh/ssh_version) > workspace -v

Workspaces
==========

current  name     hosts  services  vulns  creds  loots  notes
-------  ----     -----  --------  -----  -----  -----  -----
*        default  1      2         1      0      0      2

msf auxiliary(scanner/ssh/ssh_version) > hosts

Hosts
=====

address    mac  name  os_name  os_flavor  os_sp  purpose  info  comments
-------    ---  ----  -------  ---------  -----  -------  ----  --------
10.0.0.10             Linux    Ubuntu     8.04   server

msf auxiliary(scanner/ssh/ssh_version) > services
Services
========

host       port  proto  name  state  info                                   resource  parents
----       ----  -----  ----  -----  ----                                   --------  -------
10.0.0.10  22    tcp    ssh   open   SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1  {}        tcp (22/tcp)
10.0.0.10  22    tcp    tcp   open                                          {}

msf auxiliary(scanner/ssh/ssh_version) > notes

Notes
=====

 Time                     Host       Service  Port  Protocol  Type         Data
 ----                     ----       -------  ----  --------  ----         ----
 2026-05-19 16:02:46 UTC  10.0.0.10  ssh      22    tcp       ssh.cpe      {:cpe=>"cpe:/o:canonical:ubuntu_linux:8.04"}
 2026-05-19 16:02:46 UTC  10.0.0.10  ssh      22    tcp       ssh.hostkey  {:type=>"ssh-rsa", :fingerprint=>"SHA256:BQHm5EoHX9GCiOLuVscegPXLQOsuPs+E9d/rrJB84rk"}

msf auxiliary(scanner/ssh/ssh_version) >

@g0tmi1k
Copy link
Copy Markdown
Contributor Author

g0tmi1k commented May 19, 2026

Also have it reporting_host:

  • Trying to use a SSH module on a up/open non-SSH service (such as 21/TCP - FTP)
  • As well as a port (999/TCP) that isn't open.

Before

  • Doesn't track the host at all:
msf auxiliary(scanner/ssh/ssh_version) > workspace -D
[*] Deleted workspace: default
[*] Recreated the default workspace
msf auxiliary(scanner/ssh/ssh_version) > set RPORT 21
RPORT => 21
msf auxiliary(scanner/ssh/ssh_version) > run
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ssh/ssh_version) > workspace -v

Workspaces
==========

current  name     hosts  services  vulns  creds  loots  notes
-------  ----     -----  --------  -----  -----  -----  -----
*        default  0      0         0      0      0      0

msf auxiliary(scanner/ssh/ssh_version) >
msf auxiliary(scanner/ssh/ssh_version) >
msf auxiliary(scanner/ssh/ssh_version) >
msf auxiliary(scanner/ssh/ssh_version) > set RPORT 999
RPORT => 999
msf auxiliary(scanner/ssh/ssh_version) > run
[*] Error: 10.0.0.10: Errno::ECONNREFUSED Connection refused - connect(2) for 10.0.0.10:999
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ssh/ssh_version) > workspace -v

Workspaces
==========

current  name     hosts  services  vulns  creds  loots  notes
-------  ----     -----  --------  -----  -----  -----  -----
*        default  0      0         0      0      0      0

msf auxiliary(scanner/ssh/ssh_version) >

After

  • Host up!
msf auxiliary(scanner/ssh/ssh_version) > workspace -D
[*] Deleted workspace: default
[*] Recreated the default workspace
msf auxiliary(scanner/ssh/ssh_version) > set RPORT 21
RPORT => 21
msf auxiliary(scanner/ssh/ssh_version) > run
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ssh/ssh_version) > workspace -v

Workspaces
==========

current  name     hosts  services  vulns  creds  loots  notes
-------  ----     -----  --------  -----  -----  -----  -----
*        default  1      1         0      0      0      0

msf auxiliary(scanner/ssh/ssh_version) > hosts

Hosts
=====

address    mac  name  os_name  os_flavor  os_sp  purpose  info  comments
-------    ---  ----  -------  ---------  -----  -------  ----  --------
10.0.0.10             Unknown                    device

msf auxiliary(scanner/ssh/ssh_version) > services
Services
========

host       port  proto  name  state  info  resource  parents
----       ----  -----  ----  -----  ----  --------  -------
10.0.0.10  21    tcp          open         {}

msf auxiliary(scanner/ssh/ssh_version) >
msf auxiliary(scanner/ssh/ssh_version) >
msf auxiliary(scanner/ssh/ssh_version) >

msf auxiliary(scanner/ssh/ssh_version) > workspace -D
[*] Deleted workspace: default
[*] Recreated the default workspace
msf auxiliary(scanner/ssh/ssh_version) > set RPORT 999
RPORT => 999
msf auxiliary(scanner/ssh/ssh_version) > run
[*] Error: 10.0.0.10: Errno::ECONNREFUSED Connection refused - connect(2) for 10.0.0.10:999
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ssh/ssh_version) > workspace -v

Workspaces
==========

current  name     hosts  services  vulns  creds  loots  notes
-------  ----     -----  --------  -----  -----  -----  -----
*        default  1      0         0      0      0      0

msf auxiliary(scanner/ssh/ssh_version) > hosts

Hosts
=====

address    mac  name  os_name  os_flavor  os_sp  purpose  info  comments
-------    ---  ----  -------  ---------  -----  -------  ----  --------
10.0.0.10

msf auxiliary(scanner/ssh/ssh_version) >

@g0tmi1k g0tmi1k force-pushed the ssh_mixin branch 3 times, most recently from 80cfdae to 5ee027a Compare May 21, 2026 12:25
@g0tmi1k g0tmi1k marked this pull request as draft May 21, 2026 13:49
And stop phantom service creation from `parents:` on port/proto lookup: ./lib/msf/core/db_manager/service.rb
@g0tmi1k g0tmi1k force-pushed the ssh_mixin branch 3 times, most recently from 21dcd37 to dea61ff Compare May 22, 2026 18:20
g0tmi1k added 2 commits May 26, 2026 19:32
For Msf::Auxiliary::ReportSummary and otherwise there is a ghost/phantom unnamed service entry due to infer_vuln_from_session() -> find_by_port()
@g0tmi1k g0tmi1k marked this pull request as ready for review May 27, 2026 06:53
@g0tmi1k g0tmi1k changed the title SSH mixin: Add connect_ssh() for report_service & report_host SSH mixin: New functions to help populate workspaces May 27, 2026
@g0tmi1k
Copy link
Copy Markdown
Contributor Author

g0tmi1k commented May 27, 2026

Think I've finished tweaking with this PR!

@adfoster-r7
Copy link
Copy Markdown
Contributor

Just a heads up that there's some syntax errors:

  4) modules it should behave like all modules with module type can be instantiated exploit linux/http/cisco_firepower_useradd behaves like a module with valid metadata verifies modules metadata
     Failure/Error: module_eval(module_content, module_path)

     SyntaxError:
       --> /home/runner/work/metasploit-framework/metasploit-framework/modules/exploits/linux/http/cisco_firepower_useradd.rb
       Unmatched `end', missing keyword (`do', `def`, `if`, etc.) ?
       > 266  gin
       > 268      ensure
       > 270      end
       > 271    end
       > 272  end
       
       /home/runner/work/metasploit-framework/metasploit-framework/modules/exploits/linux/http/cisco_firepower_useradd.rb:268: syntax error, unexpected `ensure' (SyntaxError)
           ensure
           ^~~~~~

@adfoster-r7
Copy link
Copy Markdown
Contributor

Give me a ping when that's resolved and we can try to get reviews/merges in place 🤞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

3 participants