Skip to content

FTP mixin: Fixes & improvements#21416

Merged
cdelafuente-r7 merged 3 commits into
rapid7:masterfrom
g0tmi1k:ftp_mixin
Jul 8, 2026
Merged

FTP mixin: Fixes & improvements#21416
cdelafuente-r7 merged 3 commits into
rapid7:masterfrom
g0tmi1k:ftp_mixin

Conversation

@g0tmi1k

@g0tmi1k g0tmi1k commented May 6, 2026

Copy link
Copy Markdown
Contributor

This started from @cdelafuente-r7's feedback in #21380 (comment)

This PR fixes a few things:

  • Use recog (fall back to regex) with banner_version
  • If pointed at a non-ftp service, but one which is up, record
  • Check for complete response (e.g. two responses in one TCP burst - issue found when using STAT/FEAT with ftp_fingerprint)
  • Add ftp_fingerprint() & ftp_list_directory() to help enum targets.

Use recog

Target is Metasploitable 2.

After

$ ./msfconsole -q -x 'db_status; workspace -D;
setg VERBOSE true; setg RHOSTS 10.0.0.10; setg LHOST tap0'
[*] Connected to msf. Connection type: postgresql.
[*] Deleted workspace: default
[*] Recreated the default workspace
VERBOSE => true
RHOSTS => 10.0.0.10
LHOST => tap0
msf > use ftp_anonymous

Matching Modules
================

   #  Name                                 Disclosure Date  Rank    Check  Description
   -  ----                                 ---------------  ----    -----  -----------
   0  auxiliary/scanner/ftp/ftp_anonymous  .                normal  No     Anonymous FTP Access Detection


Interact with a module by name or index. For example info 0, use 0 or use auxiliary/scanner/ftp/ftp_anonymous

[*] Using auxiliary/scanner/ftp/ftp_anonymous
msf auxiliary(scanner/ftp/ftp_anonymous) > run
[*] 10.0.0.10:21          - Testing write access, creating test directory: fzgzOlMG
[+] 10.0.0.10:21          - Anonymous Read-only access (vsFTPd 2.3.4)
[*] 10.0.0.10:21          - Listing directory contents
[*] 10.0.0.10:21          - Directory listing: (empty)
[*] 10.0.0.10:21          - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ftp/ftp_anonymous) >

Proof

$ git diff ./lib/msf/core/exploit/remote/ftp.rb
diff --git a/lib/msf/core/exploit/remote/ftp.rb b/lib/msf/core/exploit/remote/ftp.rb
index a2a8855f6d..15a2ca2da9 100644
--- a/lib/msf/core/exploit/remote/ftp.rb
+++ b/lib/msf/core/exploit/remote/ftp.rb
@@ -119,7 +119,7 @@ module Exploit::Remote::Ftp
   #
   def banner_version
    info = recog_banner
-   return [info['service.product'], info['service.version']].compact.join(' ') if info
+   return [info['service.product'], info['service.product'], info['service.version']].compact.join(' ') if info

     # 220 (vsFTPd 2.3.4)\x0d\x0a                                   -> vsFTPd 2.3.4
     # 220 ProFTPD 1.3.1 Server (Debian) [::ffff:10.0.0.10]\x0d\x0a -> ProFTPD 1.3.1 Server (Debian)
$ ./msfconsole -q -x 'db_status; workspace -D;
setg VERBOSE true; setg RHOSTS 10.0.0.10; setg LHOST tap0; use ftp_anonymous; run'
[...]
[+] 10.0.0.10:21          - Anonymous Read-only access (vsFTPd vsFTPd 2.3.4)
[...]
msf auxiliary(scanner/ftp/ftp_anonymous) >

@g0tmi1k g0tmi1k force-pushed the ftp_mixin branch 2 times, most recently from cfba246 to d15b4b2 Compare May 6, 2026 16:27
Comment thread lib/msf/core/exploit/remote/ftp.rb Outdated
@g0tmi1k

g0tmi1k commented May 7, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the feedback @adfoster-r7 - Forced pushed with changes.

@g0tmi1k g0tmi1k changed the title ftp: Use recog (fall back to regex) with the banner_version FTP Mixin: Use recog (fall back to regex) with the banner_version May 19, 2026
@g0tmi1k g0tmi1k changed the title FTP Mixin: Use recog (fall back to regex) with the banner_version FTP mixin: Use recog (fall back to regex) with the banner_version May 19, 2026
@g0tmi1k g0tmi1k force-pushed the ftp_mixin branch 3 times, most recently from 0974f67 to f5ba15a Compare May 19, 2026 17:19
@g0tmi1k

g0tmi1k commented May 19, 2026

Copy link
Copy Markdown
Contributor Author

Its now able to report_service on a non-ftp service, as well as report_host on a service that is down.

Before

$ git checkout master
Already on 'master'
Your branch is up to date with 'origin/master'.
$ ./msfconsole -q -x 'workspace -D;
use auxiliary/scanner/ftp/ftp_version;
set RHOSTS 10.0.0.10;'
[*] Deleted workspace: default
[*] Recreated the default workspace
RHOSTS => 10.0.0.10
msf auxiliary(scanner/ftp/ftp_version) > set RPORT 22
RPORT => 22
msf auxiliary(scanner/ftp/ftp_version) > run
[*] 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) >
msf auxiliary(scanner/ftp/ftp_version) >
msf auxiliary(scanner/ftp/ftp_version) >
msf auxiliary(scanner/ftp/ftp_version) >
msf auxiliary(scanner/ftp/ftp_version) > set RPORT 999
RPORT => 999
msf auxiliary(scanner/ftp/ftp_version) > run
[*] 10.0.0.10:999         - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ftp/ftp_version) >
msf auxiliary(scanner/ftp/ftp_version) > workspace -v

Workspaces
==========

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

msf auxiliary(scanner/ftp/ftp_version) >

After

$ git checkout ftp_mixin
branch 'ftp_mixin' set up to track 'origin/ftp_mixin'.
Switched to a new branch 'ftp_mixin'
$ ./msfconsole -q -x 'workspace -D;
use auxiliary/scanner/ftp/ftp_version;
set RHOSTS 10.0.0.10;'
[*] Deleted workspace: default
[*] Recreated the default workspace
RHOSTS => 10.0.0.10
msf auxiliary(scanner/ftp/ftp_version) > set RPORT 22
RPORT => 22
msf auxiliary(scanner/ftp/ftp_version) > run
[*] 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      1         0      0      0      0

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

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

msf auxiliary(scanner/ftp/ftp_version) >
msf auxiliary(scanner/ftp/ftp_version) >
msf auxiliary(scanner/ftp/ftp_version) >
msf auxiliary(scanner/ftp/ftp_version) > workspace -D
[*] Deleted workspace: default
[*] Recreated the default workspace
msf auxiliary(scanner/ftp/ftp_version) > set RPORT 999
RPORT => 999
msf auxiliary(scanner/ftp/ftp_version) > run
[*] 10.0.0.10:999         - 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      0         0      0      0      0

msf auxiliary(scanner/ftp/ftp_version) >

@g0tmi1k

g0tmi1k commented May 21, 2026

Copy link
Copy Markdown
Contributor Author

Think I've finished tweaking with this PR!

@cdelafuente-r7 cdelafuente-r7 moved this from Todo to In Progress in Metasploit Kanban May 28, 2026

@cdelafuente-r7 cdelafuente-r7 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.

Thanks @g0tmi1k for these updates. I left a few suggestions and comments. Please, add specs to test all these changes. We started to require strict unit tests for library changes.

Also, this PR was suppose to be related to the fingerprinting using Recog, but, it looks like it updates more things in the library. Please, consider splitting it in multiple PR's if there is no dependency between these changes.

Comment thread lib/msf/core/exploit/remote/ftp.rb Outdated
Comment thread lib/msf/core/exploit/remote/ftp.rb
Comment thread lib/msf/core/exploit/remote/ftp.rb Outdated
Comment thread lib/msf/core/exploit/remote/ftp.rb Outdated
Comment thread lib/msf/core/exploit/remote/ftp.rb
Comment thread lib/msf/core/exploit/remote/ftp.rb Outdated
Comment thread lib/msf/core/exploit/remote/ftp.rb Outdated
Comment thread lib/msf/core/exploit/remote/ftp.rb Outdated
Comment thread lib/msf/core/exploit/remote/ftp.rb Outdated
Comment thread lib/msf/core/exploit/remote/ftp.rb
@cdelafuente-r7 cdelafuente-r7 moved this from In Progress to Waiting on Contributor in Metasploit Kanban Jun 15, 2026
@g0tmi1k g0tmi1k force-pushed the ftp_mixin branch 2 times, most recently from 45ffc94 to e909c17 Compare June 16, 2026 13:49
@g0tmi1k g0tmi1k requested a review from cdelafuente-r7 June 16, 2026 13:51
@g0tmi1k

g0tmi1k commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Hello once again @cdelafuente-r7.
I believe everything has been addressed (eview comments, specs etc).
I also have split this PR up into 3 parts now as requested.

Please let me know any other changes that fits!

@cdelafuente-r7 cdelafuente-r7 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.

Thanks @g0tmi1k for your last updates. I left some comments.

Comment thread spec/lib/msf/core/exploit/remote/ftp_spec.rb Outdated
Comment thread spec/lib/msf/core/exploit/remote/ftp_spec.rb Outdated
Comment thread spec/lib/msf/core/exploit/remote/ftp_spec.rb Outdated
Comment thread lib/msf/core/exploit/remote/ftp.rb
Comment thread spec/lib/msf/core/exploit/remote/ftp_spec.rb
Comment thread lib/msf/core/exploit/remote/ftp.rb
@g0tmi1k

g0tmi1k commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Hi once again @cdelafuente-r7 - think everything as been addressed/answered =)

@cdelafuente-r7 cdelafuente-r7 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.

Specs are failing due to the addition of # frozen_string_literal: true. This is due to an issue in #recv_ftp_resp (lib/msf/core/exploit/remote/ftp.rb): @ftpbuff is now frozen by default and this method tries to modify it. This is not related to this PR. So, please remove the # frozen_string_literal: true directive for now and we will fix the mixin later in an other PR. Sorry about that.

Also, a good practice is to run the specs locally to detect any issue like this, specially if you updated them:

bundle exec rspec spec/lib/msf/core/exploit/remote/ftp_spec.rb

Comment thread spec/lib/msf/core/exploit/remote/ftp_spec.rb
@g0tmi1k g0tmi1k requested a review from cdelafuente-r7 June 23, 2026 18:44
LLM was used here
@g0tmi1k

g0tmi1k commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Noted @cdelafuente-r7.
Reverted.

Think its good now (passing local!)

@github-project-automation github-project-automation Bot moved this from Waiting on Contributor to In Progress in Metasploit Kanban Jul 8, 2026
@cdelafuente-r7

Copy link
Copy Markdown
Contributor

Thanks @g0tmi1k ! This looks good to me. I'll go ahead and land it.

@cdelafuente-r7 cdelafuente-r7 merged commit 0293806 into rapid7:master Jul 8, 2026
44 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Metasploit Kanban Jul 8, 2026
@cdelafuente-r7

Copy link
Copy Markdown
Contributor

Release Notes

This updates the Exploit::Remote::Ftp mixin to improve target fingerprinting. It now leverages recog to fingerprint targets from their banners and adds ftp_fingerprint and ftp_list_directory methods to assist with target enumeration.

@g0tmi1k g0tmi1k deleted the ftp_mixin branch July 9, 2026 05:58
@g0tmi1k

g0tmi1k commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Woohoo! Thanks @cdelafuente-r7 🥳

@jheysel-r7 jheysel-r7 added the rn-enhancement release notes enhancement label Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement rn-enhancement release notes enhancement

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants