Metasploit uses Facade design pattern which encapsulates/simplifies the complex part of the framework by implementing it as interfaces which makes development really easy and elegant. I found that the Wikipedia example of facades is descent to be presented
# Complex Parts | Computer frameworkclass CPUdef freeze; enddef jump(position); enddef execute; endend​class Memorydef load(position, data); endend​class HardDrivedef read(lba, size); endend​# Facade | Interfaceclass ComputerFacade​def initialize@processor = CPU.new@ram = Memory.new@hd = HardDrive.newend​def start@processor.freeze@ram.load(BOOT_ADDRESS, @hd.read(BOOT_SECTOR, SECTOR_SIZE))@processor.jump(BOOT_ADDRESS)@processor.executeendend​# Client (The Developer want to use the complex computer framework)computer_facade = ComputerFacade.newcomputer_facade.start
As you can see from the above code, the developer who wants to use the Computer framework don't have to deal with the complex codebase (classes, methods and calculations) directly. Instead, he will use a simple interface class called ComputerFacade
which instantiate(as objects) all classes once you call it.
Another exist example in ruby language itself is open-uri
standard library, which encapsulates net/http
and uri
libraries and makes theme looks like opening ordinary file. To see how open-uri
makes things easy, We'll write a code that send get request to Ruby.net and get the response with both regular and open-uri
way
regular way
require 'net/http'require 'uri'​url = URI.parse('http://rubyfu.net')​res = Net::HTTP.start(url.host, url.port) {|http|http.get('/content/index.html')}​puts res.body
facade way
require "open-uri"​puts open("http://rubyfu.net/content/index.html").read
More about Facade
[Sourcemaking | Facade Design Pattern][4]
As you can see in figure above, Metasploit libraries are working as interface serves all modules, interfaces, tools and plugins. That's exactly represents what we've explained in Code Design Pattern.
mkdir -p $HOME/.msf4/modules/{auxiliary,exploits,post}
Here is a very basic structure of a general module.
I'll Add some comments for explanation purpose.
### This module requires Metasploit: http://www.metasploit.com/download# Current source: https://github.com/rapid7/metasploit-framework##​require 'msf/core'​### Module Type ###class Metasploit3 < Msf::Exploit::Remote####################​### Module Requirements ###include Exploit::Remote::Tcp####################​### Exploit Rank ####Rank = ExcellentRanking####################​### Module Informationdef initialize(info = {})super(update_info(info,'Name' => 'Absolute MSF template','Description' => %q{This is an absolute MSF template that shows how all modules look like},'License' => MSF_LICENSE,'Author' =>['Rubyfu (@Rubyfu)','Sabri (@KINGSABRI)'],'References' =>[['URL', 'http://Rubyfu.net'],['URL', 'https://github.com/Rubyfu']],'Platform' => %w{ linux win osx solaris unix bsd android aix},'Targets' =>[['Universal', {}]],'DefaultTarget' => 0,'DisclosureDate' => '2015'))​# Module Options | show optionsregister_options([Opt::RPORT(22),OptString.new('USER', [ true, 'Valid username', 'admin' ]),OptString.new('PASS', [ true, 'Valid password for username', 'P@ssw0rd' ]),], self.class)​# Module Advanced Options | show advancedregister_advanced_options([OptInt.new('THREADS', [true, 'The number of concurrent threads', 5])], self.class)end####################​​### Module Operations ###def exploit # or 'run' for post and auxiliary modulesprint_status('Starting Rubyfu')print_warning("It's just a template.")print_good('Ruby goes evil!')print_error("Thank you!")end####################​​end
The result is
To load/reload the Metasploit module you're working on, you can put the script in your user's Metasploit path or in the Metasploit framework path
User's Metasploit path
~/msf4/modules
Metasploit framework path
metasploit-framework/modules/
To make Metasploit load/reload the script use one of the following ways
Exit from msfconsole then run it again
use reload_all
to reload all modules
If your module is previously loaded and you made changes on it just use reload
but you have to be using the module, in another work use [YOUR MODULE]
Note: It's really important to know the official Metasploit development documentation ( http://www.rubydoc.info/github/rapid7/metasploit-framework/ )