diff --git a/lib/msf/core/modules/external/python/metasploit/module.py b/lib/msf/core/modules/external/python/metasploit/module.py index f8c63fbe57..a74fc1b997 100644 --- a/lib/msf/core/modules/external/python/metasploit/module.py +++ b/lib/msf/core/modules/external/python/metasploit/module.py @@ -75,15 +75,32 @@ def report_wrong_password(username, password, **opts): report('wrong_password', info) -def run(metadata, module_callback): +def run(metadata, module_callback, soft_check=None): req = json.loads(os.read(0, 10000).decode("utf-8")) + callback = None if req['method'] == 'describe': - rpc_send({'jsonrpc': '2.0', 'id': req['id'], 'result': metadata}) + caps = [] + if soft_check: + caps.append('soft_check') + + meta = metadata.copy() + meta.update({'capabilities': caps}) + + rpc_send({'jsonrpc': '2.0', 'id': req['id'], 'result': meta}) + elif req['method'] == 'soft_check': + if soft_check: + callback = soft_check + else: + rpc_send({'jsonrpc': '2.0', 'id': req['id'], 'error': {'code': -32601, 'message': 'Soft checks are not supported'}}) elif req['method'] == 'run': + callback = module_callback + + if callback: args = req['params'] - module_callback(args) + ret = callback(args) rpc_send({'jsonrpc': '2.0', 'id': req['id'], 'result': { - 'message': 'Module completed' + 'message': 'Module completed', + 'return': ret }}) diff --git a/lib/msf/core/modules/external/ruby/metasploit.rb b/lib/msf/core/modules/external/ruby/metasploit.rb index 52186c4912..b3fdcdd8aa 100644 --- a/lib/msf/core/modules/external/ruby/metasploit.rb +++ b/lib/msf/core/modules/external/ruby/metasploit.rb @@ -33,18 +33,36 @@ module Metasploit report(:wrong_password, opts.merge(username: username, password: password)) end - def run(metadata, callback) + def run(metadata, callback, soft_check: nil) self.logging_prefix = '' + cb = nil req = JSON.parse($stdin.readpartial(10000), symbolize_names: true) if req[:method] == 'describe' + capabilities = [] + capabilities << 'soft_check' if soft_check + + meta = metadata.merge(capabilities: capabilities) rpc_send({ - jsonrpc: '2.0', id: req[:id], result: metadata + jsonrpc: '2.0', id: req[:id], result: meta }) + elsif req[:method] == 'soft_check' + if soft_check + cb = soft_check + else + rpc_send({ + jsonrpc: '2.0', id: req[:id], error: {code: -32601, message: 'Soft checks are not supported'} + }) + end elsif req[:method] == 'run' - callback.call req[:params] + cb = callback + end + + if cb + ret = cb.call req[:params] rpc_send({ jsonrpc: '2.0', id: req[:id], result: { - message: 'Module completed' + message: 'Module completed', + 'return' => ret } }) end diff --git a/lib/msf/core/modules/external/shim.rb b/lib/msf/core/modules/external/shim.rb index baf199aa4b..271e93c163 100644 --- a/lib/msf/core/modules/external/shim.rb +++ b/lib/msf/core/modules/external/shim.rb @@ -54,6 +54,8 @@ class Msf::Modules::External::Shim [#{o['required']}, #{o['description'].dump}, #{o['default'].inspect}])" end end.join(",\n ") + + meta[:capabilities] = mod.meta['capabilities'] meta end diff --git a/lib/msf/core/modules/external/templates/remote_exploit_cmd_stager.erb b/lib/msf/core/modules/external/templates/remote_exploit_cmd_stager.erb index c7499fd22e..5af3dee025 100644 --- a/lib/msf/core/modules/external/templates/remote_exploit_cmd_stager.erb +++ b/lib/msf/core/modules/external/templates/remote_exploit_cmd_stager.erb @@ -34,6 +34,13 @@ class MetasploitModule < Msf::Exploit::Remote ]) end + <% if meta[:capabilities].include? 'soft_check' %> + def check + code = execute_module(<%= meta[:path] %>, method: :soft_check) + return Msf::Exploit::CheckCode::Codes[code] + end + <% end %> + def execute_command(cmd, opts) execute_module(<%= meta[:path] %>, args: datastore.merge(command: cmd)) end