Skip to content

FTP mixin: Report if host is up but service doesn't match#21575

Open
g0tmi1k wants to merge 1 commit into
rapid7:masterfrom
g0tmi1k:ftp_mixin3
Open

FTP mixin: Report if host is up but service doesn't match#21575
g0tmi1k wants to merge 1 commit into
rapid7:masterfrom
g0tmi1k:ftp_mixin3

Conversation

@g0tmi1k

@g0tmi1k g0tmi1k commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

This has come from: #21416

When ftp_version (or any module using the FTP mixin) connects to an open port that responds with a non-FTP banner, the greeting fails to match /^(120|220)[\s-]/.
Currently, the connection simply closes with nothing added to the workspace.

This uses report_service() to update the workspace with the unknown service (and also host).

Demo

Before

  • Nothing recorded when a non-FTP service responds
$ 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/ftp/ftp_version;
set RHOSTS 10.0.0.10;
set RPORT 22;
run'
[*] Deleted workspace: default
[*] Recreated the default workspace
RHOSTS => 10.0.0.10
RPORT => 22
[*] 10.0.0.10:22          - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ftp/ftp_version) > workspace -v

Workspaces
==========

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

msf auxiliary(scanner/ftp/ftp_version) >

After

  • Host and service recorded with banner info
$ git status
On branch ftp_mixin3
Your branch is up to date with 'origin/ftp_mixin3'.

nothing to commit, working tree clean
$
$ ./msfconsole -q -x 'workspace -D;
use auxiliary/scanner/ftp/ftp_version;
set RHOSTS 10.0.0.10;
set RPORT 22;
run;'
[*] Deleted workspace: default
[*] Recreated the default workspace
RHOSTS => 10.0.0.10
RPORT => 22
[*] 10.0.0.10:22          - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ftp/ftp_version) > workspace -v

Workspaces
==========

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

msf auxiliary(scanner/ftp/ftp_version) > hosts

Hosts
=====

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

msf auxiliary(scanner/ftp/ftp_version) > services
Services
========

host       port  proto  name     state  info             resource  parents
----       ----  -----  ----     -----  ----             --------  -------
10.0.0.10  22    tcp    unknown  open   Non-FTP service  {}        tcp (22/tcp)
10.0.0.10  22    tcp    tcp      open                    {}

msf auxiliary(scanner/ftp/ftp_version) >

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 updates the shared FTP remote mixin so that when an FTP module connects to an open TCP port but the initial greeting does not look like an FTP banner, Metasploit still reports the host/service to the workspace (instead of silently closing without recording anything).

Changes:

  • Add a fallback report_service() path in Ftp#connect when the greeting does not match an FTP RFC-959 style banner.
  • Record the service as unknown with a TCP parent, and store a short info string intended to capture the banner (or a fallback message).

Impact Analysis:

  • Blast radius: medium/high (all modules/mixins calling Msf::Exploit::Remote::Ftp#connect, including scanners like auxiliary/scanner/ftp/ftp_version; downstream effect is limited to DB/workspace reporting).
  • Data and contract effects: introduces additional service rows for (host, port) when the port is open but not FTP (or when no FTP banner is received), potentially increasing “services” counts and persisting “unknown” service entries.
  • Rollback and test focus: easy rollback (single mixin change); validate against (1) real FTP services (still reports ftp and note), (2) non-FTP banner services (records banner/info as intended), and (3) no-banner/timeouts (does not mislead or spam).

Comment on lines +94 to +106
report_service(
host: rhost,
port: rport,
proto: 'tcp',
name: 'unknown',
info: Rex::Text.to_hex_ascii(banner.to_s.strip).presence || 'Non-FTP service',
parents: {
host: rhost,
port: rport,
proto: 'tcp',
name: 'tcp'
}
)
@cgranleese-r7 cgranleese-r7 added the rn-enhancement release notes enhancement label Jul 10, 2026
@cgranleese-r7

Copy link
Copy Markdown
Contributor

Tested and seems to work as expected:

msf auxiliary(scanner/ftp/ftp_version) > services
Services
========

host            port  proto  name     state  info             resource  parents
----            ----  -----  ----     -----  ----             --------  -------
10.140.106.183  22    tcp    unknown  open   Non-FTP service  {}        tcp (22/tcp)
10.140.106.183  22    tcp    tcp      open                    {}

msf auxiliary(scanner/ftp/ftp_version) >

We have some merged conflicts and I believe that copilot comment may be worth looking into. Once those are resolved I can get this merged for you 👍

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

Labels

rn-enhancement release notes enhancement

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

5 participants