Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
WEASEL — Имплант скрытого канала DNS для Red Teams. | Kitploit
Инструменты/GitHubGitHub/facebookarchive/weasel
Инструменты шифрования/дешифрованияМеханизмы персистентностиПост-эксплуатацияТестирование на ПроникновениеКомандование и УправлениеRed TeamingРазработка Полезной НагрузкиАнализ DNSArchived
GitHubfacebookarchive/weasel

WEASEL

Имплант скрытого канала DNS для Red Teams.

731666 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий

WEASEL: Стелс-маяк DNS

WEASEL — это небольшой имплант, работающий в памяти, на Python 3 без зависимостей. Клиент-маяк отправляет небольшой объём идентифицирующей информации о своём хосте на DNS-зону, которую вы контролируете. Сервер WEASEL может давать клиентам команды на выполнение предварительно подготовленных или произвольных команд.

WEASEL — это нагрузка первого этапа, предназначенная для того, чтобы её было трудно обнаружить, и полезная для восстановления доступа, когда ваши шумные полнофункциональные этапы перехвачены.

Статус

  • Успешно использовалась в операции и избежала обнаружения.
  • Клиент может инициализировать сессию с сервером и установить двунаправленную связь.
  • Сервер имеет полностью рабочий CLI.
  • Клиент поддерживает ряд функций, которые может назначать сервер.
  • Размер клиента составляет 5,2 КБ после минификации и обфускации.
  • Автоматическая обфускация отсутствует и требует ручной доработки (см. Ограничения в README клиента).
  • Сервер не поддерживает режим нескольких игроков (одновременную работу нескольких операторов).

Примеры

Инструкции по использованию см. в README клиента и README сервера.

Для запуска сервера или клиента выполняйте скрипты напрямую или передавайте их интерпретатору Python.

Убедитесь, что для каждого C2-домена установлена NS-запись с IP-адресом хоста, на котором выполняется server.py.

Требования

WEASEL требует Python версии 3.6+.

Клиент является самодостаточным и использует только стандартные библиотеки, поэтому может работать на macOS, Linux и т.д.

У сервера есть несколько зависимостей из pip, включённых в requirements.txt сервера. Сервер должен запускаться на Linux, но нет никаких препятствий для работы на macOS или других *nix.

Тестирование / Запуск в режиме разработки

В этом случае нет необходимости обфусцировать и минимизировать маяк. Операторы print сохраняются. Как и в разделе «Использование» выше, убедитесь, что NS-записи для домена(ов) в servers в beacon.py указывают на IP-адрес server.py.

На хосте сервера:

sudo python3 server.py

На хосте жертвы (может быть тем же, что и сервер):

python3 beacon.py

Архитектура

Вам не нужно понимать всё это, чтобы использовать WEASEL.

Маяк общается по DNS с помощью AAAA-запросов и ответов. Он не использует TXT-записи, так как известно, что они используются DNS-вредоносным ПО и туннелями. Синие команды часто имеют детекции DNS-туннелирования, которые срабатывают на большие TXT-запросы.

Клиентская сторона не требует прав root, не использует raw-сокеты и не создаёт некорректные DNS-пакеты. Она использует обычные системные и языковые интерфейсы для выполнения DNS-запросов. Информация кодируется и шифруется в самих записях.

  • Одна A-запись (IPv4-адрес) может содержать 4 байта информации.
  • Одна AAAA-запись (IPv6-адрес) может содержать 16 байт информации.
  • CNAME-записи и имена хостов, используемые в запросах, могут содержать до 64 байт на поддомен и не должны превышать 255 байт в сумме согласно RFC. Однако рекомендации SANS по обнаружению DNS говорят, что поддомены длиннее 52 символов вызывают подозрения. По этой причине мы ограничиваем поддомены 52 символами (настраивается в коде) и стараемся использовать не больше поддоменов и запросов, чем необходимо.
  • Ответ может содержать несколько записей, вплоть до ограничения размера UDP-дейтаграммы (65 507 байт).

Этот маяк предназначен для работы в медленном и тихом режиме, с малой пропускной способностью. Он должен сообщать нам, на каких хостах он находится, и давать возможность запускать дальнейшие этапы по мере необходимости, и не более. Хотя он поддерживает выполнение произвольных команд, он не предназначен для использования в качестве обычного интерактивного шелла или канала связи.

WEASEL — это первый этап, который вы оставляете работающим, обеспечивая постоянный доступ, когда ваши полнофункциональные (и, следовательно, более шумные) этапы перехватываются.

Постоянство

WEASEL изначально был нацелен на серверы с высоким временем безотказной работы, где у нас был надёжный вектор доступа/эксплуатации. Обход криминалистики был приоритетом. В результате он не имеет собственных механизмов постоянства.

Вы можете сделать его постоянным, добавив его выполнение в вашу любимую технику обеспечения постоянства — это оставлено в качестве упражнения для читателя :)

Протокол и формат сообщений

Запрос клиента

Запрос (от клиента) — это одиночный AAAA-запрос для имени, отформатированного как:

<preamble><data>.<stream>.<session>.domain.tld

Преамбула занимает 2 байта. Преймбул[0] — порядковый номер этого пакета. Преймбул[1] — общее количество пакетов в этом потоке.

Данные ограничены 50 байтами (настраивается) и содержат полезную нагрузку. Полезная нагрузка кодируется в base32 с использованием пользовательского алфавита.

Кодирование полезной нагрузки

Сначала все символы 'w' заменяются на '-'.

Затем символ заполнения заменяется с '=' на 'w' для соответствия набору символов DNS: [a-z0-9] и [-].

Мы не заменяем '=' на '-' напрямую, потому что заполнение всегда будет в конце строки, а завершение имени хоста на '---' подозрительно и противоречит DNS RFC. Таким образом, когда строка имеет заполнение, она будет заканчиваться на 'www', что менее подозрительно и соответствует RFC.

Ответ сервера

Ответ (от сервера) состоит из одного или нескольких AAAA-ответов.

Каждый AAAA-ответ представляет собой 16-байтовую зашифрованную полезную нагрузку, представленную как IPv6-адрес с помощью socket.inet_ntop. Ответы в DNS-ответе не сохраняют свой порядок при передаче, поэтому они упорядочиваются и собираются заново, как и запросы клиента.

Транспортная полезная нагрузка — это строка элементов данных, разделённых символом ^.

Транспортный формат

Запросы и ответы следуют этому формату:

<type>|<data>

Сессии

Сессии долгоживущие: клиент инициирует сессию при первом запуске маяка, и эта сессия должна длиться всё время работы маяка на этом клиенте. Обратите внимание, что поскольку маяк работает в памяти и не является постоянным, данные сессии хранятся в памяти этого процесса Python. Любой новый запуск маяка инициирует новую сессию.

Инициирование сессии включает создание клиентом сообщения с уникально идентифицирующей преамбулой, не содержащей данных (чтобы сигнализировать серверу, что это новая сессия): конкатенация 32-байтового открытого ключа Диффи-Хеллмана и 16-байтового случайного AES IV.

Сервер принимает это и отвечает своим собственным 32-байтовым открытым ключом. На этом этапе клиент и сервер устанавливают общий ключ сессии, который будет использоваться в течение всей жизни этой сессии для шифрования полезных нагрузок данных с помощью AES-128 в режиме CTR. Обмен эфемерными ключами Диффи-Хеллмана гарантирует, что каждое соединение клиент-сервер использует уникальный ключ сессии с прямой секретностью.

Плохая криптография

Криптография намеренно плохая по ряду причин:

  • Мы имитируем реальных злоумышленников, которые обычно мало понимают в создании надёжных криптосистем и любят изобретать свои собственные.
  • Пропускная способность маяка максимально низкая, поэтому наш обмен DHE должен быть очень маленьким.
  • Важна неатрибутируемость — мы не аутентифицируем сервер.
  • Обороняющимся будет менее интересно, если мы используем современную криптографию, которую они не смогут взломать.

Вот некоторые известные проблемы криптосхемы:

  1. Модуль Диффи-Хеллмана p — это RFC 3526 Группа 5, усечённая до первых 32 байт. Это не только ограничивает открытые и закрытые ключи 32 байтами, но и Группа 5 уже устарела и не рекомендуется. Я называю это плохое решение «Группой 1».
  2. Мы используем random.randint() для показателя степени a вместо CSPRNG.
  3. Мы используем небольшой объём данных из os.urandom() для генерации идентификатора сессии и идентификатора потока вместо UUID, что означает, что коллизии вероятны. Мы учитываем это, повторяя попытки, пока не получим идентификатор, который не используется.
  4. Шифр AES-CTR повторно инициализируется с тем же IV (который долгоживуч, как и ключ сессии) для каждого потока. Это означает, что один и тот же открытый текст в одной и той же позиции в разных потоках даст один и тот же шифротекст.
  5. В AES-CTR IV правильно называется nonce, но в нашей реализации мы не используем число один раз, поэтому было бы некорректно так его называть.

Потоки

Каждое сообщение, отправляемое между клиентом и сервером, должно быть разбито на пакеты максимум по 50 байт, чтобы оставаться под лимитом в 52 байта для обычных детекций скрытых каналов DNS. Все пакеты конкретного сообщения являются частью одного потока. Сообщение == Поток.

Потоки идентифицируются 2-байтовым случайным hex-числом. Напомним, формат запроса клиента: <preamble><data>.<stream>.<session>.domain.tld

2-байтовая преамбула каждого пакета в потоке содержит порядковый номер и общее количество пакетов в потоке. Это позволяет серверу узнать, когда всё прибыло.

Поскольку это DNS, всё происходит поверх UDP, который не даёт никаких гарантий относительно порядка прибытия дейтаграмм. Вот почему WEASEL должен учитывать упорядочивание, сборку и отслеживание нескольких потоков от многих маяков.

Каждый поток повторно инициализирует глобально общий шифр AES-128-CTR для шифрования/дешифрования полезных нагрузок.

Полезную нагрузку можно расшифровать только после завершения потока (прибытия всех пакетов). Если бы не base32, мы могли бы расшифровать то, что у нас есть от сообщения, даже если бы отсутствовали пакеты (потому что AES-CTR — поточный шифр), но мы не можем декодировать base32 для частичных потоков. Ну что ж. Из-за природы DNS-клиентов запросы выполняются несколько раз (обычно 2 или 4 раза), пока не будет получен ответ, поэтому у нас есть хорошая вероятность получить все пакеты потока, так как каждый пакет должен быть отправлен клиентом как минимум дважды. Если мы потеряем пакеты или потоки, это не страшно — маяк проверит связь позже и, вероятно, ему больше повезёт.

Присоединяйтесь к сообществу WEASEL

См. файл CONTRIBUTING о том, как помочь.

Лицензия

WEASEL лицензирован по лицензии MIT, как указано в файле LICENSE.

Скачать инструмент
ТипЗначение (отправитель)Также известен какДанные
0ПодтверждениеACKСлучайный hex
1Проверка связи (клиент)PINGСлучайный hex
2Завершить себя (сервер), завершаю себя (клиент)FIN
3Инициализационное сообщение (клиент)SYNversion|hostname|kernel
4Переподключение (сервер)RST
5Установить интервал обратного вызова (сервер)секунды
6Получить данные о сетевом интерфейсеeth0 1.2.3.4/24\neth1 fe80:::/64\n...
8Выполнить произвольный код Python3 размером до 666 байт (сервер), вернуть первые 400 байт вывода (клиент)EVALскрипт python3 в одну строку
9Выполнить произвольную команду размером до 666 байт (сервер), вернуть первые 400 байт вывода (клиент)EXECbash-команда