Let’s look at the makeup of an auxiliary module in a fun little example not currently in the Metasploit repository (because it does not pertain to penetration testing). This example will demonstrate how easy it is to off-load a great deal of programming to the Framework, allowing us to focus on the specifics of a module.
Chris Gates wrote an auxiliary module for the Framework that gave his Twitter followers the impression that he had somehow invented a device that allowed him to travel at the speed of light. It makes a great example of the code reuse available in Metasploit. (You can access the source of the script at http://carnal0wnage.googlecode.com/.)
root@bt:/opt/framework3/msf3#
cd modules/auxiliary/admin/
root@bt:/opt/framework3/msf3/modules/auxiliary/admin# wgethttp://carnal0wnage.googlecode .com/svn/trunk/
msf3/modules/auxiliary/admin/random/foursquare.rb
We’ve placed the module in our auxiliary directory so that it will be available for use by Metasploit. But before we use this module, let’s look at the actual script and break down the components so we can see exactly what the module contains.
require 'msf/core'class Metasploit3 < Msf::Auxiliary # Exploit mixins should be called first
include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report
The module begins with the first two lines importing the auxiliary class . Next it makes the HTTP client functions available for use
within the script.
def initialize super(
'Name' => 'Foursquare Location Poster', 'Version => '$Revision:$', 'Description' => 'F*ck with Foursquare, be anywhere you want to be by venue id', 'Author' => ['CG'], 'License' => MSF_LICENSE, 'References' => [ [ 'URL', 'http://groups.google.com/group/foursquare-api' ], [ 'URL', 'http://www.mikekey.com/im-a-foursquare-cheater/'], ] ) #todo pass in geocoords instead of venueid, create a venueid, other tom foolery register_options( [
Opt::RHOST('api.foursquare.com'), OptString.new('VENUEID', [ true, 'foursquare venueid', '185675']), #Louvre Paris France OptString.new('USERNAME', [ true, 'foursquare username', 'username']), OptString.new('PASSWORD', [ true, 'foursquare password', 'password']), ], self.class) end
Within the initialization constructor we define much of the information
that is reported back when issuing the
info
command in msfconsole. We can see where the various options are defined and whether they are required. So far, all are pretty direct and their purposes are clear. Still, we have yet to see any actual logic being performed. That comes next.
def run beginuser = datastore['USERNAME'] pass = datastore['PASSWORD'] venid = datastore['VENUEID'] user_pass = Rex::Text.encode_base64(user + ":" + pass) decode = Rex::Text.decode_base64(user_pass) postrequest = "twitter=1\n" #add facebook=1 if you want facebook print_status("Base64 Encoded User/Pass: #{user_pass}") #debug print_status("Base64 Decoded User/Pass: #{decode}") #debug
res = send_request_cgi({ 'uri' => "/v1/checkin?vid=#{venid}", 'version' => "1.1", 'method' => 'POST', 'data' => postrequest, 'headers' => { 'Authorization' => "Basic #{user_pass}", 'Proxy-Connection' => "Keep-Alive", } }, 25)
Now we reach the actual logic of the script—what happens when run
is called within the module. Initially the provided options are set to local variable names along with defining various other objects. An object is then created by calling the send_request_cgi method
imported into the script from lib/msf/core/exploit/http.rb and defined as “Connects to the server, creates a request, sends the request, reads the response.” This method takes various parameters that make up the call to the actual server, as shown here.
print_status("#{res}") #this outputs the entire response. We could probably do #without this but it's nice to see what's going on. end
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout rescue ::Timeout::Error, ::Errno::EPIPE =>e puts e.message end end
After this object is created, the results are printed . If anything goes wrong, logic exists for catching any errors
and reporting them to the user. All of this logic is simple and is just a matter of plugging various parameters into existing functions of the Framework. This is a great example of the power of the Framework, because it allows us to concentrate only on the information needed to address our goal. There is no reason to reproduce any of the standard functions such as error handling, connection management, and so on.
Let’s see this module in action. If you don’t remember the full path to the module within the Metasploit directory structure, search for it like so.
msf >
search foursquare
[*] Searching loaded modules for pattern 'foursquare'... Auxiliary ========= Name Rank Description ---- ---- ----------- admin/foursquare normal Foursquare Location Postermsf > use admin/foursquare
msf auxiliary(foursquare) > info Name: Foursquare Location Poster Version: $Revision:$ License: Metasploit Framework License (BSD) Rank: Normal Provided by: CG <cg@carnal0wnage.com> Basic options: Name Current Setting Required Description ---- --------------- -------- ----------- PASSWORD password yes foursquare password Proxies no Use a proxy chain RHOST api.foursquare.com yes The target address RPORT 80 yes The target port USERNAME username yes foursquare username VENUEID 185675 yes foursquare venueid VHOST no HTTP server virtual host Description: F*ck with Foursquare, be anywhere you want to be by venue id References: http://groups.google.com/group/foursquare-api http://www.mikekey.com/im-a-foursquare-cheater/
In the prior example, we search for “foursquare” , issue the
use
command to select the auxiliary module, and display the information
for the selected module. Based on the options presented above, we need to configure a few of them first.
msf auxiliary(foursquare) >
set VENUEID 2584421
VENUEID => 2584421 msf auxiliary(foursquare) >set USERNAME msf@elwood.net
USERNAME => metasploit msf auxiliary(foursquare) >set PASSWORD ilovemetasploit
PASSWORD => ilovemetasploitmsf auxiliary(foursquare) >
run
[*] Base64 Encoded User/Pass: bXNmQGVsd29vZC5uZXQ6aWxvdmVtZXRhc3Bsb2l0 [*] Base64 Decoded User/Pass: msf@elwood.net:ilovemetasploit [*] HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Date: Sat, 08 May 2010 07:42:09 GMT Content-Length: 1400 Server: nginx/0.7.64 Connection: keep-alive <?xml version="1.0" encoding="UTF-8"?> <checkin><id>40299544</id><created>Sat, 08 May 10 07:42:09 +0000</created><message>OK! We've got you @ Washington DC Union Station. This is your 1st checkin here!</message> <venue><id>2584421</id><name>Washington DC Union Station</name><primary category><id>79283</ id><fullpathname>Travel:Train Station</ fullpathname><nodename>Train Station</nodename> <iconurl>http://foursquare.com/img/categories/travel/ trainstation.png</iconurl></primary category><address>Union Station</address><city>Washington</city><state>DC</ state><geolat> 38.89777986957695</geolat><geolong>-77.0060920715332 </geolong></venue><mayor><type>nochange </type><checkins>4</checkins><user><id>685446</id><firstname> Ron</firstname><photo>http:// playfoursquare.s3.amazonaws.com/userpix_thumbs/ELOW44Q HXJFB4PWZ.jpg</photo><gender>male</ gender></user><message>Ron is The Mayor of Washington DC Union Station.</message></mayor> <badges><badge><id>1</id><name>Newbie</name><icon>http:// foursquare.com/img/badge/newbie .png</icon><description>Congrats on your first check-in!</description></badge></badges> <scoring><score><points>1</ points><icon>http://foursquare.com/img/scoring/2.png</icon> <message>First stop tonight</message></score> <score><points>5</points><icon>http:// foursquare.com/img/scoring/1.png</icon> <message>First time @ Washington DC Union Station!</ message></score></scoring></checkin>
In order to run this module successfully, we need a valid set of Foursquare credentials to do the check-in. We first define the VenueID that we find online with a bit of Googling , and then we set our Foursquare credentials
and run the module. We get a successful result with the Foursquare service confirming our check-in and giving us five points
.
In this case, we have submitted a request to “check in” at Union Station in Washington, DC, on the Foursquare service (see Figure 9-1).
When we check the Foursquare website, we see a successful result. Modules like these demonstrate that Metasploit allows us to implement nearly anything we can programmatically imagine.