Writing and Importing Custom Modules into Metasploit

Overview

Metasploit’s modular design allows users to extend its functionality by writing or importing custom modules. This capability is essential for creating tailored exploits, auxiliary tools, and post-exploitation modules to target unique scenarios.

Why Write Custom Modules?

  1. Expand Functionality:

    • Address vulnerabilities or scenarios not covered by existing modules.

  2. Customization:

    • Adapt modules to specific environments or requirements.

  3. Port Existing Exploits:

    • Convert scripts written in Python, Perl, or other languages into Ruby-based Metasploit modules.

  4. Reusability:

    • Use standardized frameworks to streamline future testing.

Installing Pre-Existing Modules

  1. Update Metasploit to Access Latest Modules:

    • Ensure the framework has the latest modules:

      msfupdate
  2. Download External Modules:

    • Use platforms like Exploit-DB or GitHub to find third-party modules.

    • Example: Clone DarkOperator plugins:

      git clone https://github.com/darkoperator/Metasploit-Plugins
  3. Copy Module to the Correct Directory:

    • Default module directories:

      /usr/share/metasploit-framework/modules/
    • Example for a web exploit:

      cp custom_exploit.rb /usr/share/metasploit-framework/modules/exploits/web/custom_exploit.rb
  4. Reload Modules in Metasploit:

    • Refresh the module list without restarting Metasploit:

      reload_all

Writing Custom Modules

  1. Create a Module Directory:

    • Custom modules can be placed in the user directory:

      ~/.msf4/modules/<category>/<type>/<module_name>.rb
  2. Follow Ruby Naming Conventions:

    • Use descriptive names with snake_case, avoiding spaces or special characters.

    • Example:

      my_custom_exploit.rb
  3. Basic Structure of a Module:

    Example Exploit Template:

    class MetasploitModule < Msf::Exploit::Remote
      Rank = ExcellentRanking
    
      include Msf::Exploit::Remote::HttpClient
    
      def initialize(info = {})
        super(update_info(info,
          'Name'           => 'Custom Exploit',
          'Description'    => 'This is a custom HTTP exploit.',
          'License'        => MSF_LICENSE,
          'Author'         => ['YourName'],
          'References'     => [['URL', 'https://example.com/exploit']],
          'Platform'       => 'win',
          'Targets'        =>
            [
              ['Windows Server', { 'Offset' => 0x1234 }]
            ],
          'DefaultTarget'  => 0
        ))
    
        register_options(
          [
            Opt::RPORT(80),
            OptString.new('TARGETURI', [true, 'Path to vulnerable endpoint', '/vulnerable'])
          ]
        )
      end
    
      def exploit
        print_status("Sending malicious payload...")
        send_request_cgi({
          'method'  => 'GET',
          'uri'     => datastore['TARGETURI'],
          'vars_get' => {
            'cmd' => "calc.exe"
          }
        })
        print_good("Payload delivered successfully.")
      end
    end

Defining Module Options

Common Option Types:

  • Strings:

    OptString.new('TARGETURI', [true, 'Target URI', '/'])
  • Ports:

    Opt::RPORT(80)
  • IP Addresses:

    OptAddress.new('RHOST', [true, 'Target address', ''])

Registering Options:

register_options(
  [
    OptString.new('USERNAME', [true, 'Username for authentication', 'admin']),
    OptString.new('PASSWORD', [true, 'Password for authentication', 'password'])
  ]
)

Testing Your Module

  1. Reload the Custom Module:

    reload_all
  2. Load the Module in Metasploit:

    use <category>/<type>/<module_name>
  3. Verify Functionality:

    • Use info to check module details.

      info
    • Run the module to ensure it behaves as expected.

Porting Existing Exploits

Steps to Port Scripts:

  1. Identify a script (e.g., Python or Perl) suitable for porting.

  2. Break down the script into components:

    • Payload delivery mechanism.

    • Vulnerability triggering code.

    • Exploit parameters (IP, port, etc.).

  3. Translate the components into Ruby:

    • Use Metasploit’s Msf::Exploit::Remote mixin for remote exploits.

  4. Test the module rigorously.

Example:

  • Original Python Script:

    import requests
    
    target = "http://example.com/vulnerable"
    response = requests.get(f"{target}?cmd=calc.exe")
    print("Exploit sent.")
  • Ported Ruby Module:

    def exploit
      print_status("Sending exploit payload...")
      send_request_cgi({
        'method'  => 'GET',
        'uri'     => datastore['TARGETURI'],
        'vars_get' => {
          'cmd' => "calc.exe"
        }
      })
      print_good("Payload delivered successfully.")
    end

Best Practices for Custom Modules

  1. Follow Metasploit Standards:

    • Use existing modules as references.

    • Follow Rapid7’s Ruby documentation.

  2. Document Your Code:

    • Include clear comments and module metadata for easy maintenance.

  3. Test Thoroughly:

    • Test in isolated environments to prevent unintended consequences.

  4. Organize Module Files:

    • Place modules in the correct directory hierarchy for easier management.

  5. Keep It Modular:

    • Reuse common functionality across modules using Ruby mixins.


Command Cheatsheet

Command
Description

reload_all

Reload all modules.

use <module_path>

Load a custom module.

info

View module details.

edit <module_path>

Open the module in a text editor.

set <option> <value>

Set a parameter for the module.