Skip to content

Add extra fields to MCP tools#21579

Open
zeroSteiner wants to merge 4 commits into
rapid7:masterfrom
zeroSteiner:feat/mcp/add-extra-fields
Open

Add extra fields to MCP tools#21579
zeroSteiner wants to merge 4 commits into
rapid7:masterfrom
zeroSteiner:feat/mcp/add-extra-fields

Conversation

@zeroSteiner

@zeroSteiner zeroSteiner commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds additional information to data returned through the MCP server.

Related Issue:

Breaking Changes

This is not a breaking change.

Reviewer Notes

Verification Steps

    • Configure the MCP server for a tool such as claude (the one used for testing
    • Make sure there's some data in metasploit to query that shows the new fields
  • Run a module such as psexec that logs into something and registers a credential with an Active Directory domain
    • Ask the LLM about AD credentials, e.g. "do I have any user credentials for the MSFLAB active directory domain?"
    • Ask the LLM a question that uses the host data, e.g. "Are any windows hosts x64?"
    • Ask the LLM a questoin about the host resources / services

Using claude code, you can use the Ctrl+O key to show the IO from the MCP tool which is useful to verify the shape of the data. You can also ask Claude to just verify the fields look right too.

Test Evidence

Test evidence includes tests for features that were dropped in this PR due to them being added in #21247.

❯ What host is a honey pot?                                                                                                                                                                                                                                                               

  Called metasploit 2 times (ctrl+o to expand)
                                
● 192.168.159.132 (hostname ubuntu2404, Ubuntu 24.04) is the honey pot.

  Its host comment reads "This host is a honey pot", which is also recorded in a host.comments note. Worth treating it as a deception/monitoring trap — avoid interacting with it during engagements.

✻ Cogitated for 11s

❯ Do I have any user credentials for the MSFLAB active directory domain?                                                                                                                                                                                                                  

  Called metasploit (ctrl+o to expand)

● Yes — one credential matches the MSFLAB Active Directory domain:

  ┌──────────────┬──────────────────────────────────┐
  │    Field     │              Value               │
  ├──────────────┼──────────────────────────────────┤
  │ Username     │ smcintyre                        │
  ├──────────────┼──────────────────────────────────┤
  │ Password     │ Password1!                       │
  ├──────────────┼──────────────────────────────────┤
  │ Realm        │ msflab (Active Directory Domain) │
  ├──────────────┼──────────────────────────────────┤
  │ Host/Service │ 192.168.159.10 — smb/445 (tcp)   │
  └──────────────┴──────────────────────────────────┘

  Notes:
  - There's an identical credential stored with realm . (local/default realm) — same user/password against the same host.
  - There's also a smcintyre non-replayable hash ($6$..., a Linux SHA-512 crypt) with no realm — that's not an AD credential.

  So for the MSFLAB domain specifically, you have msflab\smcintyre : Password1!.

✻ Cooked for 8s

❯ Are any of the MS17-010 exploits noted as crash safe?                                                                                                                                                                                                                                   

  Called metasploit 3 times (ctrl+o to expand)

● No — neither MS17-010 exploit is noted as crash safe.

  Both exploit modules report Stability: ["unknown-stability"] in their notes metadata (no CRASH_SAFE flag on either):

  - exploit/windows/smb/ms17_010_eternalblue — Stability: unknown. Its description explicitly warns the opposite: "On some systems, this module may cause system instability and crashes, such as a BSOD or a reboot."
  - exploit/windows/smb/ms17_010_psexec (EternalRomance/Synergy/Champion) — Stability: unknown. Described as "more reliable than the EternalBlue exploit," but still not flagged crash safe.

  Practically, the psexec/EternalRomance chain is the safer of the two, but neither carries the CRASH_SAFE stability rating. Given the honey pot at 192.168.159.132, also worth noting these only matter for the Windows SMB targets anyway (e.g., the DC at 192.168.159.10).

✻ Worked for 16s

❯ Are any windows hosts x64?                                                                                                                                                                                                                                                              

● Yes. There's one Windows host, and it's x64:

  - 192.168.159.10 (DC) — Windows Server 2019, x64

  This comes from its host.os.session_fingerprint note (arch: x64). The only other host (192.168.159.132) is the Ubuntu honey pot.

✻ Baked for 7s

❯ Do I know of any services running on port 445?                                                                                                                                                                                                                                          

  Called metasploit (ctrl+o to expand)

● Yes — one SMB service on port 445:

  - 192.168.159.10 (DC) — 445/tcp open, smb
    - Info: "Module: exploit/windows/smb/psexec, last negotiated version: SMBv3 (dialect = 0x0311)"

  That's the Windows Server 2019 DC. SMBv3 (dialect 0x0311 = SMB 3.1.1) means it's a modern stack — consistent with it not being vulnerable to the MS17-010 exploits discussed earlier. You also have the msflab\smcintyre : Password1! credential for this same host/service if you need
  authenticated access.

✻ Cogitated for 8s

Environment

I used a Windows Server 2019 as a target to populate some data, otherwise everything else was local using Claude Code.

AI Usage Disclosure

Of course I used claude code to perform the tests. I also used claude to update the specs as necessary.

Pre-Submission Checklist

  • Ran rubocop on new files with no new offenses (net new files only)
  • Ran msftidy on changed module files with no new offenses (modules only)
  • Ran msftidy_docs on changed documentation files with no new offenses (documentation files only)
  • Included a corresponding documentation markdown file in documentation/modules (new modules only)
  • No sensitive information (IP addresses, credentials, API keys, hashes) in code or documentation
  • Tested on the target environment specified in the Environment section above
  • Included RSpec tests for library changes (encouraged for lib/ changes)
  • Read the CONTRIBUTING.md and module acceptance guidelines

Comment thread lib/msf/core/mcp/metasploit/response_transformer.rb
@cdelafuente-r7

Copy link
Copy Markdown
Contributor

Thanks @zeroSteiner , it looks good to me now. I tested with the MCP inspector tool and a LLM. I confirmed the new fields are correctly handled.

One note unrelated to this PR, but regarding the underlying db.services RPC endpoint: a service parent services includes the full JSON structure, which includes child services. These services are also returned individually and many duplicates are returned. For example (simplified JSON):

    {
      "port": 443,
      "name": "othercms",
      "parents": [ { "port": 443, "name": "https", "parents": [
                    { "port": 443, "name": "ssl", "parents": [
                      { "port": 443, "name": "tcp", "parents": [] } ] } ] } ]
    },
    {
      "port": 443,
      "name": "https",
      "parents": [ { "port": 443, "name": "ssl", "parents": [
                    { "port": 443, "name": "tcp", "parents": [] } ] } ]
    },
    {
      "port": 443,
      "name": "ssl",
      "parents": [ { "port": 443, "name": "tcp", "parents": [] } ]
    },
    {
      "port": 443,
      "name": "tcp",
      "parents": []
    }

I was thinking about returning only the service ID for children, the way the actual DB records are built with associations, and let the client (LLM) reconstruct the service chain:

    {
      "SID": 1,
      "port": 80,
      "name": "othercms",
      "parents": [ 2 ]
    },
    {
      "SID": 2,
      "port": 443,
      "name": "https",
      "parents": [ 3 ]
    },
    {
      "SID": 3,
      "port": 443,
      "name": "ssl",
      "parents": [ 4 ]
    },
    {
      "SID": 4,
      "port": 443,
      "name": "tcp",
      "parents": []
    }

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: In Progress

3 participants