Inside Metasploit – Write a Simple Exploit Module

Table of Contents



The really interesting thing begins right here right now.

I am going to dig into metasploit, and try to write a simple metasploit module from scratch.

The Intention

The intention of doing this is to learn how to create exploit modules, and more, to gradually gain the ability to modify existing exploit codes to my need. Big thing!

Place to Start

The place to start is google, search for how to write metasploit module.

And let's first take a look at rapid7's official guide here.

Good, I have API document, I have a template code, and I understand the module's ranking system.

Let's dive right into it.

The Template

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'

class MetasploitModule < Msf::Exploit::Remote
  Rank = NormalRanking

  def initialize(info={})
    super(update_info(info,
      'Name'           => "[Vendor] [Software] [Root Cause] [Vulnerability type]",
      'Description'    => %q{
        Say something that the user might need to know
      },
      'License'        => MSF_LICENSE,
      'Author'         => [ 'Name' ],
      'References'     =>
        [
          [ 'URL', '' ]
        ],
      'Platform'       => 'win',
      'Targets'        =>
        [
          [ 'System or software version',
            {
              'Ret' => 0x41414141 # This will be available in `target.ret`
            }
          ]
        ],
      'Payload'        =>
        {
          'BadChars' => "\x00"
        },
      'Privileged'     => false,
      'DisclosureDate' => "",
      'DefaultTarget'  => 0))
  end

  def check
    # For the check command
  end

  def exploit
    # Main function
  end

end

This is the template. Let's dissect it and try to understand the essential bit.

  • Name - this field should begin with the name of the vendor, in my case, it should be "via". And followed by the software, ie. Apache. Then the root cause, means with function or component the bug is found. Finally the vulnerability the module is trying to exploit.

But, don't be so strict with yourself. Here is a screenshot of the smb_login module in metasploit, the name field is just as casual as my title.

在这里插入图片描述

  • Description - just filling some descriptive word to explains what you are going to do. But, the more specific, the better. List things like dependency issues, or other know issues is preferred.
  • Author - no need to say, put your name here.
  • References - any materials related to the bug
  • Platform - win, linux, osx, unix or bsd
  • Targets - contains an array of systems, applications, setups, or specific versions the exploit is targeting. If specified here, we can use set target command in msfconsole like we did before. If no, just leave it out.
  • Payloads - how the payload should be encoded and generated. The document is really thorough, you can specify Space, SaveRegisters, Prepend, PrependEncoder, BadChars, Append, AppendEncoder, MaxNops, MinNops, Encoder, Nop, EncoderType, EncoderOptions, ExtendedOptions, EncoderDontFallThrough.
  • DisclosureDate - trivial, the release date of the bug you found
  • exploit - this is the main function. write your code here.

And it suggests that the custom module should have a check method.

[How to write a check method](https://github.com/rapid7/metasploit-framework/wiki/How-to-write-a-check()-method)

Here is a example module

Right, that's all.

Be Creative

Let's create some lab environment, using existing vulnerabilities and create a my first very simple exploit module. I don't want to achieve something big, like a reverse shell or brute forcing, I just want to first create a connection to the target first. And everything start from there.

Refer to this guide on How to Send an HTTP Request Using HTTPClient.

The Prototype

I created a file fun.rb in /usr/share/metasploit-frameword/modules/auxiliary/scanner/smb.

And I pasted in the template.

在这里插入图片描述

The color scheme is horrible, but let's worry about that later.

I'm going to fill out the fields I talked about previously, and delete the ones that I don't need.

The code is like this now. And I want to make sure there's no syntax issues by calling ruby on my file.

在这里插入图片描述
And I got error.

在这里插入图片描述

Ritght, maybe I cannot just run the module like this, maybe I should run msfconsole and try use it in there.

I fired up msfconsole, and search fun.

在这里插入图片描述

😀 Here it is.

在这里插入图片描述

See if I can use it now.

在这里插入图片描述

Now I have an issue. Failed to load module.

I have to check out other codes in the smb directory to see how they managed to require all the stuff.

在这里插入图片描述

This is how smb_login did.

I am going to add the first line to my file and see what happens.

Still got error. Then I noticed I've got the inherite things wrong here, since I'm in scanner/smb folder, but I'm like inherit from remote

在这里插入图片描述

Modify that.

Still no.

And this link tells me how I should get my custom module to work.

IMPORTANT NOTE
When adding external modules, be careful and make sure to read the code. Bucause the
module will access to whatever you have permission to access, and it's gets worse when you're root.

So, I should put my custom module in ~/.msf4/modules/auxiliary/scanner/custom/my_module.rb.

在这里插入图片描述

I edited the code to print a Hello, world! when called by msf.

Let's try that.

First reload_all modules.

在这里插入图片描述

Then search my_module

在这里插入图片描述

My module is there. Stange enough, when I use with number 0, I got the error. But when I use with full path of my module, every thing is fine.

So I created a new exploits folder in ~/.msf4/modules and moved my auxiliary folder into it.

The path is now

在这里插入图片描述

And there's no errors any more.

在这里插入图片描述

It worked!

在这里插入图片描述

The Real Request

I've stumbled all the way here. Now, I know the basics of:

  • Where to put my own module - ~/.msf4/modules/exploits/...
  • The template code - Don't delete any of the default code in the template, because when I do that, it gives me lots of errors.
  • How to reload all the modules in msf to test my module on the fly - every time you modify your code, do reload to test new code
  • The register_options command, is the thing that puts all the options there for your user to set
  • To get any value your module user set - just get everything from datastore, it's something like the state global variable in react, everything your user set will be inserted into datastore

Let's crank it up a notch. I have a blog @ imin.red. I want to make a http request to get the index page.

Remember this article. It gives instructions on http requests.

Go check out the link, the instruction is quite straight forward.

Now the code looks like this. I highlighted the added part.

在这里插入图片描述

在这里插入图片描述

Here is the HttpClient Manual from Rapid7. It has everything you need.

Time to exploit.

在这里插入图片描述

Everything works. It pulls down the index page of my blog.

在这里插入图片描述

Next Steps

Now, it's up to you to explore the possibilities of this technique. Just use your imagination.

Search for answers, the internet is dangerous, but it is also fruitful.



References: