praetorian-inc/wasmforge
GitHub: praetorian-inc/wasmforge
WasmForge 将 Go 和 C# 程序编译为 WASM 沙箱化的原生单文件可执行程序,通过转译和多态输出规避静态检测。
Stars: 32 | Forks: 2
# WasmForge
WasmForge 可将 Go 和 C# 程序编译为 WebAssembly,随后将其打包为单一的原生二进制文件。生成的可执行文件会将客户机代码隔离在 WASM 运行时(基于每次构建单独 fork 的 [wazero](https://github.com/tetratelabs/wazero)) 中运行。在该沙箱内,客户机程序可以透明地访问网络、原始套接字、Win32 API 以及 macOS 框架 API。
你可以使用 `net.Dial`、`net.Listen` 或 `net/http` 编写普通的 Go 程序。你也可以迁移现有的 .NET Framework C# 项目。无论哪种方式,输出的都是一个可在 Windows 或 macOS 上运行的单一二进制文件,而无需用户对客户机源码进行任何修改。

## 我只想和真人交流
稍微浏览一下这个项目,你就会很明显地发现,它的开发过程中*大量*使用了 LLM。其中很大一部分文档也是如此——但本节内容并非如此。我已经尽力去除了这个 README 中的套话,并尽可能使实际使用 WasmForge 的过程变得直观。此外,虽然 LLM 在撰写文档时会对其自身成果大加吹捧,但它对项目局限性的说明却往往不够清晰。
为了设定合理的预期,虽然该工具已经针对 Go 的许多不同功能进行了测试,但它并不能作为所有 Go 程序的完整解决方案。目前仍有相当一部分 Win32 API 无法得到妥善支持(例如需要回调 thunks 的 API)。以 Sliver 为例,虽然它的大部分命令都能正常运行,但它并不是一个功能完全 1:1 对等的移植版本。例如,`ls` 命令显示的路径仍然会带有 `/`,而不是传统的 `C:\` 路径格式,因为 WASM 二进制块并没有被完全“欺骗”从而意识到自己正运行在 Windows 环境中。还有一些其他功能在触发时会直接导致崩溃。**在将你想使用的功能应用于真实目标之前,请务必先进行测试。** 如果发现某些功能无法正常工作,请尝试针对该出现问题的 API 构建一个最基础的复现用例,并提交 issue 或提交 PR。
C# 方面的实现目前更像是一个概念验证而非成熟方案。用于将 C# 编译为 WASM 的流程实在*过于*实验性,这意味着 WasmForge 往往需要对程序本身进行大量重写才能使其运行起来。归根结底,我当初可能在这个功能上钻了太深的牛角尖,本应该直接建议开发者使用 LLM 将 C# 代码重写为 Go 代码。或许那样反而会省事得多。话虽如此,C# -> Wasm -> WasmForge 的通用模式确实可行,并且它也确实能够规避大量针对 C# 的特定检测。
就此而言,WasmForge 主要旨在应对**静态**检测。转译过程能够破坏大多数检测手段(即便是内存扫描),但归根结底,如果你的二进制文件中包含像 `mimikatz` 或 `sliver` 这样非常明显的字符串,一些简单的内存扫描仍然会引发检测。未来很可能会加入自动字符串混淆功能,因为这是一个相对容易实现自动化的特性;但在第一版中,我不希望给构建 pipeline 增加额外的复杂性,以保持调试过程的*相对*简单。
尽管我们已经付出了一些努力来清理和整合该代码库中的源码,但它目前仍然比较杂乱。项目中有几个不同的文件夹,用于存放不同的测试流程。基础单元测试通常位于 `examples/` 和 `test/` 目录中,而一些更复杂、需要在完整实验室环境中运行的测试则位于 `testdata/` 中。此外,`scripts/` 和 `internal/devtools` 文件夹中还有许多专门用于开发和测试的工具。只有当你想要搭建自己的测试环境以进行进一步开发时,才会用到这些内容。通常情况下,借助 LLM 开发如此复杂的项目需要一系列非常明确的测试用例来进行引导,否则最终生成的代码根本无法运行。本项目包含了这些测试套件,以便任何感兴趣的人能够进一步开发工具或为项目做出贡献。
希望社区能觉得这个工具相对易于使用,随着时间推移,我们会持续对其进行改进。也许有一天,C# 的编译能像 Go 的编译一样出色。
## 快速开始(Go 项目)
获取 `wasmforge` 有三种方式:
1. **预编译二进制文件。** 从以下页面获取发布版本:
[Releases 页面](https://github.com/praetorian-inc/wasmforge/releases) —
每个 tag 都附带了针对 Linux、macOS 和 Windows 构建的 CLI。
2. **Docker 镜像。** 对于 C# / .NET 项目,打包好的镜像内置了所有
前置条件(.NET 10 SDK、NativeAOT-LLVM workload、WASI SDK 24.0、
`wasm-ld`、`osslsigncode`)。使用
`make docker-build` 构建一次,然后通过 `make docker-run` 运行——完整的
工作流请参阅
[docs/CSHARP.md](docs/CSHARP.md)。这是针对 C# 的
推荐方案。
3. **从源码构建。**
make build
`make build` 会重新生成内嵌的 `internal/build/build_assets.tar.gz`
然后再编译 CLI。如果你仅仅运行 `go build -o wasmforge
./cmd/wasmforge`,你会得到一个可以运行的二进制文件,但在发布模式下构建时
(当 CLI 在此源码树之外运行时),它将使用过时的内嵌
压缩包。更详细的解释请参阅
[CONTRIBUTING.md](CONTRIBUTING.md)。
`examples/` 目录中包含了一些可以直接构建和运行的 Go 程序。
完整列表请参阅 [examples/README.md](examples/README.md)。
### 针对 Windows 平台
```
GOOS=windows GOARCH=amd64 ./wasmforge build \
--ghost traefik \
-o myapp.exe \
/path/to/your/project
```
只要设置了 `GOOS=windows`,就会自动启用 Win32 API 桥接——在大多数
常见情况下,你不再需要传入 `--win32-apis` 参数。
`--ghost traefik` 会替换内嵌的 `gopclntab` 符号分布,使其看起来像 Traefik 反向代理。在所有内置的配置文件中,该选项产生的 VirusTotal 检出率最低。其他配置文件以及生成自定义配置文件的说明位于 [docs/GHOST-PROFILES.md](docs/GHOST-PROFILES.md) 中。
默认情况下,Windows 目标文件会使用自签名证书进行自动签名。你可以使用 `--sign google.com` 来伪造某个域名的 TLS 证书,或者使用 `--no-sign` 完全禁用签名。
### 针对 macOS 平台
```
# Intel
GOOS=darwin GOARCH=amd64 ./wasmforge build -o myapp /path/to/your/project
# Apple Silicon
GOOS=darwin GOARCH=arm64 ./wasmforge build -o myapp /path/to/your/project
```
无需额外参数。只要设置了 `GOOS=darwin`,就会自动启用 macOS 框架桥接。有关框架桥接、purego/ObjC 支持以及其他 Apple 特定说明,请参阅 [docs/MACOS.md](docs/MACOS.md)。
### 可选参数
```
# 原始 socket 支持(构建时需要 CAP_NET_RAW 或 root)
./wasmforge build --raw-sockets -o myapp ./path/to/project
# 详细输出(适用于首次构建)
GOOS=windows GOARCH=amd64 ./wasmforge build --ghost traefik --win32-apis -v -o tool.exe /path/to/project
# 自定义 PE VERSIONINFO(仅限 Windows)
./wasmforge build --pe-company "Acme Corp" --pe-product "AcmeTool" --pe-file-version "10.0.19041.1" ...
```
### 编译 C# / .NET 项目
C# 项目(`.csproj` 文件)会被自动检测。WasmForge 会通过一条命令运行完整的 NativeAOT-WASI 迁移、修补和构建 pipeline:
```
GOOS=windows GOARCH=amd64 ./wasmforge build --win32-apis -o seatbelt.exe path/to/Seatbelt/Seatbelt/
```
对于 C# 开发,我们强烈建议使用 Docker 构建环境。它内置了所有必需的前置条件(.NET 10 SDK、NativeAOT-LLVM workload、WASI SDK 24.0、`wasm-ld`),因此你无需在宿主机上单独安装它们。完整说明请参阅 [docs/CSHARP.md](docs/CSHARP.md)。
## CLI 摘要
```
wasmforge build [package] Compile Go (or C#) package to a WASM-sandboxed native binary
-o, --output Output binary path
--ghost Ghost profile: traefik, caddy, terraform (see docs/GHOST-PROFILES.md)
--raw-sockets Enable raw socket support
--win32-apis Enable Win32 API bridge (Windows targets)
--sign Sign binary: 'self' or domain name (default: self for Windows)
--no-sign Disable default auto-signing for Windows targets
--tags Go build tags (comma-separated)
--pe-company / --pe-product / --pe-description / --pe-copyright / --pe-file-version
PE VERSIONINFO overrides
-v, --verbose Verbose build output
wasmforge run [package] Build and immediately execute
wasmforge clean Remove cached patched GOROOTs (~/.wasmforge/cache/)
wasmforge version Print version
wasmforge dotnet-migrate Migrate .NET Framework project to .NET 10 NativeAOT-WASI
wasmforge dotnet-patch Apply NativeAOT-WASI C# source patches
```
## 功能
WasmForge 弥合了 WASM 与底层宿主机之间的鸿沟,使得客户机程序无需关心底层细节。
**平台 API。** TCP、UDP、DNS、HTTP、TLS 和原始套接字在 Windows 和 macOS 上均可直接使用,无需修改客户机代码。在 Windows 上,WasmForge 代理了完整的 Win32 接口表面:注册表、文件 I/O、进程、DLL 加载以及支持最多 15 个参数的 `SyscallN`。指针转换会自动完成。COM vtable 链也被完整映射,因此 CLR 和其他重度依赖 COM 的 API 可以实现端到端的运行。在 macOS 上,`dlopen` 和 `dlsym` 可以触及任何框架(Security、CoreGraphics、IOKit 等),并且 `ebitengine/purego` 加上 Objective-C runtime 开箱即用。
**.NET 托管与迁移。** CLR 通过标准链路加载(`CoInitializeEx`、`CLRCreateInstance`、`Load_3`、`Invoke_3`)。AMSI 在启动时已被修补,因此 `Assembly.Load(byte[])` 不会拦截已知工具的运行。另一套独立的 NativeAOT-WASI pipeline 可以接收现有的 .NET Framework 项目,并生成单一的 Windows PE 二进制文件,且目标机器上无需安装 .NET runtime。
**宿主机内存与 shellcode。** 客户机内部可以访问一个由 `VirtualAlloc` 支撑的宿主机内存代理。这使得在不脱离 WASM 沙箱的情况下,运行 COFF/BOF 加载器和执行 shellcode 成为可能。
**协作式让步(yield)。** 阻塞型 Win32 API(如 `Sleep`、`WaitForSingleObject`、`ReadFile` 等)不会冻结 WASM 的 goroutine。宿主机会在后台 goroutine 中分发调用,并向客户机发出信号让其让步,直到结果准备就绪。
**多态输出。** 每次构建都会生成一个结构上独一无二的二进制文件。WASM 操作码会被重新排列,section ID 和 magic 字节会被随机化,所有标识符、PE 导入表、VERSIONINFO 字符串、许可证块以及源代码文件名都会被擦除。内置的 wazero fork 版本也会被重写,以匹配重新排列后的字节码。Ghost 配置功能会重写 `gopclntab` 符号,使其与真实的企业级 Go 二进制文件(如 Traefik、Caddy、Terraform)相匹配。Windows 输出文件默认会进行 Authenticode 签名,既可以自签名,也可以通过 `osslsigncode` 伪造真实域名的 TLS 证书。
## 架构
```
+-------------------- WASM Guest (wasip1) --------------------+
| |
| Your Go Program (net, net/http, os; works transparently) |
| |
+----------- go:wasmimport ABI (custom opcodes) --------------+
|
+----------- Host Runtime (per-build wazero fork) ------------+
| |
| 90+ host functions (networking, OS proxies, platform APIs) |
| Windows: pointer translation, shadow memory, COM mirroring |
| macOS: dlopen/dlsym framework bridge, ABI trampolines |
| |
+----------- wazero (custom VM: permuted opcodes/magic) ------+
|
OS Kernel / Windows APIs / macOS Frameworks
```
构建 pipeline 分为六个阶段运行。
1. **准备修补后的 GOROOT。** 软链接 Go 的标准库,并对 `syscall/` 和 `net/` 进行修补以支持 WASM 网络。缓存在 `~/.wasmforge/cache/` 中。
2. **将 Go 编译为 WASM。** 使用 `GOOS=wasip1 GOARCH=wasm` 并基于修补后的标准库进行构建。自动生成的 stub 会填补平台特定的差异。当检测到包含 `golang.org/x/sys` 和 `ebitengine/purego` 的导入时,会自动注入相应的 sysshim。
3. **重映射 WASM。** 针对每次构建进行操作码重排、section ID 置换、自定义 magic 字节设置以及全负载的字节替换。
4. **生成宿主机二进制文件。** 生成带有随机化标识符的多态 `main.go`,匹配的专属 wazero fork,内嵌的 PE 资源,并应用 `-trimpath`。
5. **PE 后处理(仅限 Windows)。** 导入表扩充、PE 校验和计算,并将 payload 作为命名的 PE section 进行注入。
6. **代码签名(可选)。** 通过 `osslsigncode` 进行 Authenticode 签名。
## 实际场景验证
WasmForge 可以编译并运行未经修改的第三方 Go 项目,包括那些包含复杂平台特定代码的项目。
| 程序 | 平台 | 描述 | 验证情况 |
| ---------------------------------------------------------------- | -------- | -------------------------------------- | ------------------------------------------------------------------------------ |
| **Sliver** | Windows | C2 框架,大量使用 Win32 | HTTPS beacon,`whoami`,`ps`,`netstat`,`execute-assembly`(Rubeus,Seatbelt) |
| **Sliver** | macOS | C2 框架(beacon + session) | `pwd`,`ls`,`download`,`execute`,SOCKS5 代理 |
| **go-clr** | Windows | .NET CLR 托管 + 程序集执行 | CLR 加载链,Rubeus 侦测,Seatbelt 系统扫描 |
| **Chisel** | Windows | 基于 HTTP 并带有 SOCKS5 的 TCP/UDP 隧道 | 隧道连通性,代理转发 |
| **Ligolo-ng** | Windows | 高级隧道和流量转发 | TUN 接口,agent 连通性 |
| **[goffloader](https://github.com/praetorian-inc/goffloader)** | Windows | 使用 `unsafe.Pointer` 的 COFF/BOF 加载器 | VirtualAlloc,shellcode 执行,PE 解析,IAT 解析 |
**.NET NativeAOT-WASI 程序:**
| 程序 | 平台 | 描述 | 验证情况 |
| -------------- | -------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Seatbelt** | Windows | 安全枚举 | 大多数通过测试;少数需要 WMI / Defender 回调派发的命令被如实 stub 处理,等待桥接支持。 |
| **Rubeus** | Windows | Kerberos 工具 | 哈希 + token 操作直接可用;网络动词(`asktgt`,`kerberoast`,`asreproast`)通过 TCP 桥接运行;LSA 查询(`klist`,`logonsession`)与原生基线相匹配。 |
有关 Sliver 的分步操作指南,请参阅 [docs/BUILDING-SLIVER.md](docs/BUILDING-SLIVER.md);有关 C# pipeline 的内容,请参阅 [docs/CSHARP.md](docs/CSHARP.md)。
## 环境要求
WasmForge 可以在 Linux、macOS 或 Windows 构建主机上运行。需要 Go 1.25 或更高版本。
部分功能需要额外的环境设置。原始套接字需要 `CAP_NET_RAW` 或 root 权限。Win32 桥接需要 Windows 目标并传入 `--win32-apis`(其他目标会返回 `ENOSYS`)。macOS 框架桥接需要 macOS 目标,且会在检测到 `GOOS=darwin` 时自动启用。代码签名需要在 `PATH` 中包含 `osslsigncode`。C# 项目需要 .NET 10 SDK、NativeAOT-LLVM workload 和 WASI SDK 24.0。或者,你也可以使用打包好的 Docker 镜像(在 [docs/CSHARP.md](docs/CSHARP.md) 中有介绍),里面预装了所有这些依赖。
一致性测试套件(`test/parity/`)以及 `scripts/lab-setup/` 下的实验室部署脚本还额外假定你搭建了运行 **[GOAD (Game of Active Directory)](https://github.com/Orange-Cyberdefense/GOAD)** 的 **[Ludus](https://gitlab.com/badsectorlabs/ludus)** 活动目录域环境——所有硬编码的 `sevenkingdoms.local` / `kingslanding` / `SEVENKINGDOMS-CA` 默认值均为 GOAD 的默认配置,可通过 `WASMFORGE_PARITY_*` 环境变量进行覆盖(参见 `test/parity/internal/lab/lab.go`)。有关完整的实验室设置,请参阅 [docs/internals/PARITY-HARNESS.md](docs/internals/PARITY-HARNESS.md) 和 [docs/internals/LAB-STABILITY.md](docs/internals/LAB-STABILITY.md)。
## 文档
**从这里开始**
| 主题 | 文档 |
| --- | --- |
| 可运行示例(TCP 扫描器、HTTP 服务器、ICMP ping) | [examples/README.md](examples/README.md) |
| 端到端构建 Sliver(Windows + macOS) | [docs/BUILDING-SLIVER.md](docs/BUILDING-SLIVER.md) |
| C# / .NET 项目编译(Docker 工作流) | [docs/CSHARP.md](docs/CSHARP.md) |
| macOS 目标和框架桥接 | [docs/MACOS.md](docs/MACOS.md) |
| Ghost 配置使用和自定义配置构建 | [docs/GHOST-PROFILES.md](docs/GHOST-PROFILES.md) |
| 构建时环境变量(R80 方案,所有 `WASMFORGE_*` 调节参数) | [docs/ENVIRONMENT.md](docs/ENVIRONMENT.md) |
**深入了解**
| 主题 | 文档 |
| --- | --- |
| 架构 — 宿主机模块、构建 pipeline、设计决策 | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) |
| 贡献指南 — 仓库布局、前置条件、添加宿主机函数 | [CONTRIBUTING.md](CONTRIBUTING.md) |
| 安全策略 + 漏洞披露 | [SECURITY.md](SECURITY.md) |
| 行为准则 | [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) |
**维护者参考**
| 主题 | 文档 |
| --- | --- |
| 宿主机 API 契约 — 注册的导出函数、签名稳定性 | [docs/internals/HOST-API-CONTRACT.md](docs/internals/HOST-API-CONTRACT.md) |
| AST patcher 内部机制 — 字符串替换规则与分发 | [docs/internals/AST-PATCHER.md](docs/internals/AST-PATCHER.md) |
| 一致性测试套件 — 运行 C# 原生与 WASM 差异比对 | [docs/internals/PARITY-HARNESS.md](docs/internals/PARITY-HARNESS.md) |
| 实验室稳定性 — Ludus + GOAD 环境搭建、看门狗脚本 | [docs/internals/LAB-STABILITY.md](docs/internals/LAB-STABILITY.md) |
## 许可证
基于 Apache License, Version 2.0 授权。详情请参阅 [LICENSE](LICENSE) 和
[NOTICE](NOTICE)。
版权所有 (c) 2025-2026 Praetorian Security, Inc.
标签:AI工具, DNS 反向解析, EVTX分析, WebAssembly, 代码混淆, 日志审计, 沙箱环境, 知识库安全, 编译工具, 请求拦截