rapid7 / metasploit-framework

Metasploit Framework
https://www.metasploit.com/
Other
34.3k stars 14.01k forks source link

[msfrpc] Include action information in auxiliary/post modules #14456

Open scmanjarrez opened 3 years ago

scmanjarrez commented 3 years ago

Summary

Include the action description on module.info calls.

Basic example

Current behaviour:

>> rpc.call('module.info', 'auxiliary', 'scanner/ssl/openssl_heartbleed')
{"type"=>"auxiliary", "name"=>"OpenSSL Heartbeat (Heartbleed) Information Leak", ... 
"RPORT"=>{"type"=>"port", "required"=>true, "advanced"=>false, "desc"=>"The target port", "default"=>443}, 
"actions"=>{0=>"SCAN", 1=>"DUMP", 2=>"KEYS"}, ...}

Proposed behaviour:

>> rpc.call('module.info', 'auxiliary', 'scanner/ssl/openssl_heartbleed')
{"type"=>"auxiliary", "name"=>"OpenSSL Heartbeat (Heartbleed) Information Leak", ... 
"RPORT"=>{"type"=>"port", "required"=>true, "advanced"=>false, "desc"=>"The target port", "default"=>443},
"actions"=>{"SCAN"=>"Check hosts for vulnerability", "DUMP"=>"Dump memory contents to loot", "KEYS"=>"Recover private keys from memory"}, ...}

P.S.: Action description can be obtained from msfconsole.

Motivation

Index doesn't have any meaningful information, you don't use it either. You set the option with the action value, e.g. DUMP, SCAN... Other module options have a desc attribute, describing the option, e.g. RPORT

agalway-r7 commented 3 years ago

This looks like an easy win at first glance. Adding the action descriptions should be possible by pulling them from the m instance of the module object

https://github.com/rapid7/metasploit-framework/blob/7f162b3504f5a1ba797feb5058544802599fcb6a/lib/msf/core/rpc/v10/rpc_module.rb#L250

We'd have to double check the indexes aren't used for anything else though. I take it you haven't found any uses for them in pymetasploit3 @scmanjarrez?

scmanjarrez commented 3 years ago

If you're referring to pymetasploit3, then no. It take into account only the value, e.g: DUMP, SCAN, etc. Index isn't used at all.

    @action.setter
    def action(self, action):
        if action not in self.actions.values():
            raise ValueError('Action must be one of %s' % repr(list(self.actions.values())))
        self._action = action
        self._runopts['ACTION'] = self._action