Фреймворк генерации позиционно-независимого шеллкода для загрузки .NET-сборок, EXE, DLL и VBS-файлов.
Инструмент для извлечения паролей, хешей, PIN-кодов и Kerberos-тикетов из памяти Windows. Поддерживает Pass-the-Hash, Pass-the-Ticket, Golden/Silver Ticket, …
Кросс-платформенный инструмент для извлечения сохранённых паролей из десятков приложений: браузеры, почтовые клиенты, SSH-клиенты, мессенджеры, БД, VPN, …
Современный C2-фреймворк (Command & Control) с поддержкой кастомных имплантов (Demon), reflective loading, sleep obfuscation, OPSEC-режимов и …
Постэксплуатационный фреймворк BC Security (форк оригинального PowerShell Empire). Поддерживает PowerShell, Python и C# агентов. Включает 300+ …
git clone http://github.com/thewover/donut.git nmake -f Makefile.msvc
Текущая версия: v1.1
Donut является позиционно-независимым кодом, который позволяет выполнять в памяти VBScript, JScript, EXE, DLL-файлы и сборки .NET. Модуль, созданный с помощью Donut, может быть либо развернут с HTTP-сервера, либо непосредственно внедрён в загрузчик. Модуль может быть опционально зашифрован с использованием блочного шифра Chaskey и случайно сгенерированного 128-битного ключа. После загрузки и выполнения файла в памяти оригинальная ссылка стирается, чтобы помешать работу сканеров памяти. Генератор и загрузчик поддерживают следующие возможности:
Существуют динамические и статические библиотеки для Linux и Windows, которые можно интегрировать в ваши собственные проекты. Также существует модуль Python, подробнее о котором можно прочитать в Сборка и использование расширения Python.
Donut содержит индивидуальные загрузчики для каждого поддерживаемого типа файла. Для сборок EXE/DLL .NET Donut использует неуправляемый API размещения CLR для загрузки среды выполнения общего языка. После загрузки CLR в процесс-хост создаётся новый домен приложений, позволяющий выполнять сборки в временных доменах приложений. Когда домен приложений готов, сборка .NET загружается с помощью метода AppDomain.Load_3. Наконец, точка входа для EXE или публичный метод для DLL, указанный пользователем, вызывается с любыми дополнительными параметрами. Обратитесь к MSDN за документацией по Неуправляемый API размещения CLR. Для автономного примера узла CLR см. код здесь.
Файлы VBScript и JScript выполняются с использованием интерфейса IActiveScript. Также имеется минимальная поддержка некоторых методов, предоставляемых Windows Script Host (wscript/cscript). Для автономного примера см. код здесь. Для более подробного описания см.: Выполнение JavaScript, VBScript, JScript и XSL в памяти
Неуправляемые или нативные EXE/DLL файлы выполняются с помощью собственного загрузчика PE с поддержкой отложенного импорта, TLS и патчинга командной строки. Поддерживаются только файлы с информацией о перемещениях. Подробнее читайте в Выполнение DLL в памяти.
Загрузчик может отключать AMSI и WLDP, чтобы помочь обойти обнаружение вредоносных файлов, выполняемых в памяти. Для получения дополнительной информации читайте: Как команды Red Team обходят AMSI и WLDP для динамического кода .NET. Он также поддерживает распаковку файлов в памяти с использованием aPLib или API RtlDecompressBuffer. Подробнее о сжатии данных читайте в Сжатие данных.
Начиная с версии v1.0, ETW также обходится. Как и в случае с AMSI/WLDP, это модульная система, позволяющая заменить стандартный обход на собственный. Стандартный обход основан на исследованиях XPN. Читать Скрытие вашего .NET - ETW для получения дополнительной информации.
По умолчанию загрузчик перезаписывает заголовки PE неуправляемых PE (от базового адреса до IMAGE_OPTIONAL_HEADER.SizeOfHeaders). Если не используется decoy-модуль (перегрузка модуля), то заголовки PE обнуляются. Если используется decoy-модуль, заголовки PE этого decoy-модуля используются для перезаписи заголовков PE полезного модуля. Это делается для препятствования обнаружению путем сравнения заголовков PE модулей в памяти с файлом, поддерживающим их на диске. Пользователь может запросить сохранение всех заголовков PE в их исходном состоянии. Это полезно в сценариях, когда полезный модуль должен получить доступ к своим заголовкам PE, например, при поиске встроенных ресурсов PE.
Для подробного пошагового руководства по использованию генератора и того, как Donut влияет на торговые приемы, прочтите Donut - внедрение .NET-сборок в виде шеллкода. Для получения дополнительной информации о загрузчике прочтите Загрузка .NET-сборок из памяти.
Те, кто хочет узнать больше о внутренностях, должны обратиться к Заметкам разработчика.
Существует два типа сборки. Если вы хотите отлаживать Donut, пожалуйста, обратитесь к документации здесь. Если нет, продолжайте чтение для релизной сборки.
Из командной строки Windows или терминала Linux выполните клонирование репозитория.
git clone http://github.com/thewover/donut.git
Следующий шаг зависит от вашей операционной системы и выбранного компилятора. В настоящее время генератор и шаблон загрузчика для Donut можно успешно скомпилировать как с помощью Microsoft Visual Studio 2019, так и с MingGW-64. Чтобы использовать библиотеки в собственном проекте на C/C++, пожалуйста, обратитесь к примерам, предоставленным здесь.
Для генерации шаблона загрузчика, динамической библиотеки donut.dll, статической библиотеки donut.lib и генератора donut.exe запустите x64-командную строку разработчика Microsoft Visual Studio, перейдите в каталог, где вы клонировали репозиторий Donut, и выполните следующее:
nmake -f Makefile.msvc
Для выполнения той же операции, но с использованием MinGW-64 в Windows или Linux, перейдите в каталог, где вы клонировали репозиторий Donut, и выполните следующее:
make -f Makefile.mingw
Для генерации динамической библиотеки donut.so, статической библиотеки donut.a и генератора donut перейдите в каталог, где вы клонировали репозиторий Donut, и просто выполните make.
Donut можно установить и использовать как Python-модуль. Для установки из исходников требуется pip для Python3. Сначала убедитесь, что более старые версии donut-shellcode не установлены, выполнив следующую команду в терминале Linux или командной строке Microsoft Visual Studio.
pip3 uninstall donut-shellcode
После подтверждения, что более старые версии больше не установлены, выполните следующую команду.
pip3 install .
Вы также можете установить Donut как Python-модуль, получив его из репозитория PyPi.
pip3 install donut-shellcode
Для получения дополнительной информации обратитесь к Сборке и использованию расширения Python.
Сборка контейнера Docker.
docker build -t donut .
Запуск Donut.
docker run -it --rm -v "${PWD}:/workdir" donut -h
Donut включает несколько других исполняемых файлов, которые могут быть собраны отдельно. В их число входят «hash.exe», «encrypt.exe», «inject.exe» и «inject_local.exe». Первые два используются при генерации шеллкода. Последние два предоставлены для помощи в тестировании шеллкода Donut. «inject.exe» внедряет исполняемый двоичный файл (loader.bin) в процесс по его PID или имени процесса. «inject_local.exe» внедряет исполняемый двоичный файл в собственный процесс.
Для отдельной сборки этих вспомогательных исполняемых файлов можно воспользоваться makefile MSVC. Например, чтобы собрать «inject_local.exe» для тестирования вашего шеллкода Donut, выполните.
nmake inject_local -f Makefile.msvc
Для каждой версии релиза Donut предоставлены теги, содержащие скомпилированные исполняемые файлы.
В настоящее время доступны два других генератора.
В следующей таблице перечислены переключатели, поддерживаемые командной строкой версии генератора.
| Переключатель | Аргумент | Описание |
|---|---|---|
| -a | arch | Целевая архитектура загрузчика : 1=x86, 2=amd64, 3=x86+amd64(по умолчанию). |
| -b | level | Поведение при обходе AMSI/WLDP : 1=Нет, 2=Прерывать при сбое, 3=Продолжать при сбое.(по умолчанию) |
| -k | headers | Сохранять заголовки PE. 1=Перезаписать (по умолчанию), 2=Оставить все |
| -j | decoy | Необязательный путь к модулю-приманке для перегрузки модулей. |
| -c | class | Необязательное имя класса. (требуется для DLL .NET) Также можно указать пространство имён: например namespace.class |
| -d | name | Имя домена приложения для создания в .NET. Если включена энтропия, будет сгенерировано случайным образом. |
| -e | level | Уровень энтропии. 1=Нет, 2=Генерировать случайные имена, 3=Генерировать случайные имена + использовать симметричное шифрование (по умолчанию) |
| -f | format | Формат вывода загрузчика, сохраняемого в файл. 1=Двоичный (по умолчанию), 2=Base64, 3=C, 4=Ruby, 5=Python, 6=PowerShell, 7=C#, 8=Шестнадцатеричный |
| -m | name | Необязательный метод или функция для DLL. (для DLL .NET требуется метод) |
| -n | name | Имя модуля для HTTP-промежуточного хранения. Если включена энтропия, оно будет сгенерировано случайным образом. |
| -o | path | Указывает, где Donut должен сохранить загрузчик. По умолчанию — «loader.bin» в текущем каталоге. |
| -p | parameters | Необязательные параметры/командная строка внутри кавычек для метода/функции DLL или EXE. |
| -r | version | Версия среды выполнения CLR. По умолчанию используется MetaHeader, либо v4.0.30319, если он недоступен. |
| -s | server | URL HTTP-сервера, который будет размещать модуль Donut. Учетные данные могут быть указаны в следующем формате: https://username:password@192.168.0.1/ |
| -t | Запустить точку входа неизменяемого/нативного EXE в виде потока и дождаться его завершения. | |
| -w | Командная строка передаётся в функцию неуправляемой DLL в формате UNICODE. (по умолчанию используется ANSI) | |
| -x | option | Определяет, как загрузчик должен завершать работу. 1=выход из потока (по умолчанию), 2=выход из процесса, 3=Не завершать и не очищать, блокировать бесконечно |
| -y | addr | Создаёт новый поток для загрузчика и продолжает выполнение по адресу, который представляет собой смещение относительно исполняемого файла хост-процесса. Предоставленное значение является смещением. Эта опция поддерживает загрузчики, которым необходимо возобновить выполнение хост-процесса после завершения работы donut. |
| -z | engine | Упаковать/Сжать входной файл. 1=Без сжатия, 2=aPLib, 3=LZNT1, 4=Xpress, 5=Xpress Huffman. В настоящее время последние три поддерживаются только в Windows. |
| Tool | Description |
|---|---|
| DemoCreateProcess | Пример .NET сборки для использования в тестировании. Принимает два параметра командной строки, каждый из которых указывает программу для выполнения. |
| DonutTest | Простой инжектор шеллкода на C# для тестирования donut. Шеллкод должен быть закодирован в base64 и вставлен как строка. |
| ModuleMonitor | Инструмент proof-of-concept, который обнаруживает внедрение CLR, выполняемое такими инструментами, как Donut и Cobalt Strike's execute-assembly. |
| ProcessManager | Инструмент обнаружения процессов, который атакующие операторы могут использовать для определения, во что внедрять, а защитные операторы могут использовать для определения того, что запущено, какие свойства имеют эти процессы и загружен ли в них CLR. |