Path: blob/master/spec/integration/msfmcpd/tool_execution_module_info_spec.rb
70330 views
# frozen_string_literal: true12require 'msf/core/mcp'3require 'webmock/rspec'45RSpec.describe 'Tool Execution End-to-End - Module Info' do6before(:all) do7WebMock.disable_net_connect!(allow_localhost: false)8end910after(:all) do11WebMock.allow_net_connect!12end1314let(:host) { 'localhost' }15let(:port) { 55553 }16let(:endpoint) { '/api/' }17let(:api_url) { "https://#{host}:#{port}#{endpoint}" }18let(:user) { 'test_user' }19let(:password) { 'test_password' }2021let(:limiter) { Msf::MCP::Security::RateLimiter.new(requests_per_minute: 60, burst_size: 10) }22let(:client) do23c = Msf::MCP::Metasploit::MessagePackClient.new(host: host, port: port, endpoint: endpoint)24c.authenticate(user, password)25c26end27let(:server_context) { { msf_client: client, rate_limiter: limiter } }2829before do30stub_request(:post, api_url)31.with(body: ['auth.login', user, password].to_msgpack)32.to_return(33status: 200,34body: { 'result' => 'success', 'token' => 'test_token' }.to_msgpack,35headers: { 'Content-Type' => 'binary/message-pack' }36)37end3839describe 'Module Info Integration with HTTP' do40it 'retrieves module info through complete HTTP request flow' do41info_stub = stub_request(:post, api_url)42.with(body: ['module.info', 'test_token', 'exploit', 'windows/smb/ms17_010_eternalblue'].to_msgpack)43.to_return(44status: 200,45body: {46'type' => 'exploit',47'name' => 'MS17-010 EternalBlue',48'fullname' => 'exploit/windows/smb/ms17_010_eternalblue',49'rank' => 'excellent',50'disclosuredate' => '2017-03-14',51'description' => 'MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption',52'license' => 'MSF_LICENSE',53'filepath' => '/opt/metasploit-framework/modules/exploits/windows/smb/ms17_010_eternalblue.rb',54'arch' => ['x64', 'x86'],55'platform' => ['windows'],56'authors' => ['Author1', 'Author2'],57'privileged' => true,58'check' => true,59'references' => [['CVE', '2017-0144'], ['URL', 'https://example.com']],60'targets' => { 0 => 'Windows 7', 1 => 'Windows 8' },61'default_target' => 0,62'options' => { 'RHOSTS' => { 'type' => 'address', 'required' => true } }63}.to_msgpack,64headers: { 'Content-Type' => 'binary/message-pack' }65)6667result = Msf::MCP::Tools::ModuleInfo.call(68type: 'exploit',69name: 'windows/smb/ms17_010_eternalblue',70server_context: server_context71)7273expect(info_stub).to have_been_requested.once7475expect(result).to be_a(MCP::Tool::Response)76expect(result.error?).to be false7778data = result.structured_content[:data]79expect(data[:fullname]).to eq('exploit/windows/smb/ms17_010_eternalblue')80expect(data[:rank]).to eq('excellent')81expect(data[:architectures]).to eq(['x64', 'x86'])82expect(data[:has_check_method]).to be true8384# Verify filepath is stripped of install path85expect(data[:filepath]).to eq('modules/exploits/windows/smb/ms17_010_eternalblue.rb')86expect(data[:filepath]).not_to include('/opt/metasploit-framework/')8788# Verify references are transformed89expect(data[:references]).to eq([90{ type: 'CVE', value: '2017-0144' },91{ type: 'URL', value: 'https://example.com' }92])9394# Verify metadata95expect(result.structured_content[:metadata][:query_time]).to be_a(Float)96end9798it 'handles module not found through HTTP' do99stub_request(:post, api_url)100.with(body: ['module.info', 'test_token', 'exploit', 'nonexistent/module'].to_msgpack)101.to_return(102status: 500,103body: { 'error_message' => 'Module not found' }.to_msgpack104)105106result = Msf::MCP::Tools::ModuleInfo.call(107type: 'exploit',108name: 'nonexistent/module',109server_context: server_context110)111112expect(result.error?).to be true113expect(result.content.first[:text]).to include('Metasploit API error')114end115116it 'validates module type before making HTTP request' do117result = Msf::MCP::Tools::ModuleInfo.call(118type: 'invalid_type',119name: 'windows/smb/ms17_010_eternalblue',120server_context: server_context121)122123expect(result.error?).to be true124expect(result.content.first[:text]).to include('Module type')125end126end127end128129130