WasmForge — compila programas Go e C# para executáveis nativos de binário único, isolados em sandbox WASM, com saída polimórfica.
O WasmForge compila programas Go e C# para WebAssembly e os empacota como binários nativos únicos. Os executáveis resultantes isolam o código convidado dentro de um runtime WASM (um fork por build do wazero). De dentro dessa sandbox, os convidados têm acesso transparente a redes, sockets brutos, APIs Win32 e APIs de frameworks macOS.
Você pode escrever Go normal usando net.Dial, net.Listen ou net/http. Você também pode migrar um projeto C# existente do .NET Framework. De qualquer forma, a saída é um único binário que roda no Windows ou macOS, sem exigir que o usuário faça modificações no código fonte convidado.

Uma rápida olhada neste projeto deixará bastante óbvio que ele foi desenvolvido com um uso INTENSO de LLMs. Uma parte da documentação também foi — mas esta seção não. Fiz o meu melhor para descomplicar este README e tornar o processo de usar o WasmForge o mais direto possível. Além disso, embora os LLMs escrevam documentação que elogia fortemente suas próprias realizações, as limitações não são tão claras.
Para definir as expectativas corretamente: embora tenha sido testado com muitos recursos diferentes para Go, NÃO é uma solução completa para todos os programas Go. Ainda há uma porcentagem significativa da API win32 que não é suportada adequadamente (como APIs que exigem thunks de callback). O Sliver, por exemplo, funciona para um bom número de comandos, mas NÃO é uma porta 1:1 completa com funcionalidade. , por exemplo, ainda mostrará caminhos com em vez do tradicional , pois o blob WASM não é totalmente enganado para perceber que está dentro do Windows. Existem outras funcionalidades que apenas causarão uma falha. Se algo não funcionar, tente criar o exemplo mais básico da API que está quebrada e abra uma issue / envie um PR.
ls/C:\O lado C# é mais uma prova de conceito do que uma implementação. O processo usado para compilar C# para WASM é muito experimental, e isso significa que o WasmForge muitas vezes precisa reescrever uma boa parte do programa de qualquer maneira para fazê-lo funcionar. No final, provavelmente investi demais nessa funcionalidade e deveria ter recomendado que as pessoas usassem um LLM para reescrever código C# como código Go. Provavelmente é menos doloroso de lidar. Dito isso, o padrão geral C# -> Wasm -> WasmForge FUNCIONA e quebra um bom número de detecções específicas do C#.
Nessa nota — o WasmForge é destinado principalmente a lidar com detecções ESTÁTICAS. O processo de transpilação quebra a maioria das detecções, até mesmo para varredura em memória, mas, no final, se o seu binário tiver strings muito óbvias como mimikatz ou sliver, existem algumas varreduras de baixo esforço em memória que causarão uma detecção. A ofuscação automática de strings provavelmente será adicionada no futuro, pois é um recurso bastante fácil de automatizar, mas para a primeira versão, não quis adicionar complexidade extra ao pipeline de build para manter a depuração relativamente direta.
Embora tenha havido alguns esforços para limpar/consolidar o código fonte neste repositório, ele ainda está bastante desorganizado. Existem várias pastas diferentes para diferentes processos de teste. Testes unitários básicos tendem a ficar em examples/ e test/, enquanto alguns testes mais complexos destinados a serem executados em um ambiente de laboratório completo ficam em testdata/. Há também várias ferramentas de desenvolvimento/teste apenas nos diretórios scripts/ e internal/devtools. Essas só serão necessárias se você estiver tentando configurar seu próprio ambiente de teste para fazer desenvolvimento adicional. Em geral, qualquer desenvolvimento de LLM de algo tão complexo requer um número de casos de teste muito explícitos para orientar a geração, caso contrário, você acaba com algo que não funciona. O projeto inclui esses harnesses para que qualquer pessoa curiosa possa desenvolver suas próprias ferramentas ou contribuir com o projeto.
Espero que a comunidade considere essas ferramentas relativamente fáceis de usar e, com o tempo, continuaremos a melhorá-las. Talvez um dia a compilação C# funcione tão bem quanto a compilação Go.
Existem três maneiras de obter o wasmforge:
Binário pré-compilado. Baixe uma versão na página de Releases — builds do CLI para Linux, macOS e Windows estão anexados a cada tag.
Imagem Docker. Para projetos C# / .NET, a imagem fornecida já vem com todos
os pré-requisitos (.NET 10 SDK, workload NativeAOT-LLVM, WASI SDK 24.0,
wasm-ld, osslsigncode) pré-instalados. Compile-a uma vez com make docker-builde execute-a commake docker-run` — veja
docs/CSHARP.md para o fluxo completo. Este é o caminho
recomendado para C#.
Compilar a partir do código fonte.
make build
make build regenera o arquivo internal/build/build_assets.tar.gz embutido
e então compila o CLI. Se você apenas executar go build -o wasmforge ./cmd/wasmforge, obterá um binário funcional, mas os builds em modo de distribuição
(quando o CLI é executado fora desta árvore de código fonte) usarão um arquivo
embutido desatualizado. Veja CONTRIBUTING.md para uma explicação mais detalhada.
O diretório examples/ contém programas Go executáveis que você pode compilar
imediatamente. Veja examples/README.md para o menu completo.
GOOS=windows GOARCH=amd64 ./wasmforge build \
--ghost traefik \
-o myapp.exe \
/caminho/para/seu/projeto
A ponte da API Win32 é ativada automaticamente sempre que GOOS=windows — você não
precisa mais passar --win32-apis para o caso comum.
--ghost traefik substitui a distribuição de símbolos gopclntab embutida para se parecer com o proxy reverso Traefik. Dos perfis incluídos, este produz a menor taxa de detecção no VirusTotal. Outros perfis e instruções para gerar o seu próprio estão em docs/GHOST-PROFILES.md.
Os alvos Windows são autoassinados com um certificado autoassinado por padrão. Use --sign google.com para falsificar o certificado TLS de um domínio, ou --no-sign para desabilitar a assinatura completamente.
# Intel
GOOS=darwin GOARCH=amd64 ./wasmforge build -o myapp /caminho/para/seu/projeto
# Apple Silicon
GOOS=darwin GOARCH=arm64 ./wasmforge build -o myapp /caminho/para/seu/projeto
Nenhuma flag extra é necessária. A ponte de frameworks do macOS é ativada automaticamente sempre que GOOS=darwin. Veja docs/MACOS.md para a ponte de frameworks, suporte purego/ObjC e outras notas específicas da Apple.
# Suporte a sockets brutos (requer CAP_NET_RAW ou root no momento da compilação)
./wasmforge build --raw-sockets -o myapp ./caminho/para/projeto
# Saída verbosa (útil para primeiros builds)
GOOS=windows GOARCH=amd64 ./wasmforge build --ghost traefik --win32-apis -v -o tool.exe /caminho/para/projeto
# VERSIONINFO PE personalizado (apenas Windows)
./wasmforge build --pe-company "Acme Corp" --pe-product "AcmeTool" --pe-file-version "10.0.19041.1" ...
Projetos C# (arquivos .csproj) são detectados automaticamente. O WasmForge executa todo o pipeline de migração, patch e compilação NativeAOT-WASI em um comando:
GOOS=windows GOARCH=amd64 ./wasmforge build --win32-apis -o seatbelt.exe caminho/para/Seatbelt/Seatbelt/
Para trabalhos com C#, recomendamos fortemente o ambiente de build Docker. Ele fornece todos os pré-requisitos (.NET 10 SDK, workload NativeAOT-LLVM, WASI SDK 24.0, wasm-ld) para que você não precise instalá-los no host. Instruções completas estão em docs/CSHARP.md.
wasmforge build [package] Compilar pacote Go (ou C#) para binário nativo com sandbox WASM
-o, --output <caminho> Caminho do binário de saída
--ghost <nome> Perfil Ghost: traefik, caddy, terraform (veja docs/GHOST-PROFILES.md)
--raw-sockets Habilitar suporte a sockets brutos
--win32-apis Habilitar ponte da API Win32 (alvos Windows)
--sign <modo> Assinar binário: 'self' ou nome de domínio (padrão: self para Windows)
--no-sign Desabilitar auto-assinatura padrão para alvos Windows
--tags <tags> Tags de build Go (separadas por vírgula)
--pe-company / --pe-product / --pe-description / --pe-copyright / --pe-file-version
Substituições de VERSIONINFO do PE
-v, --verbose Saída de build verbosa
wasmforge run [package] Compilar e executar imediatamente
wasmforge clean Remover GOROOTs com patch em cache (~/.wasmforge/cache/)
wasmforge version Imprimir versão
wasmforge dotnet-migrate <dir> Migrar projeto .NET Framework para .NET 10 NativeAOT-WASI
wasmforge dotnet-patch <dir> Aplicar patches de código fonte C# NativeAOT-WASI
O WasmForge preenche a lacuna entre WASM e o host subjacente para que os programas convidados não precisem fazer isso.
APIs de plataforma. TCP, UDP, DNS, HTTP, TLS e sockets brutos funcionam sem alterações no código convidado tanto no Windows quanto no macOS. No Windows, o WasmForge faz a ponte de toda a superfície Win32: registro, E/S de arquivos, processos, carregamento de DLL e SyscallN com até 15 argumentos. A tradução de ponteiros é automática. As cadeias de vtables COM são espelhadas para que o CLR e outras APIs pesadas de COM funcionem de ponta a ponta. No macOS, dlopen e dlsym alcançam qualquer framework (Security, CoreGraphics, IOKit, etc.), e ebitengine/purego mais o runtime Objective-C funcionam imediatamente.
Hospedagem e migração .NET. O CLR é carregado através da cadeia padrão (CoInitializeEx, CLRCreateInstance, Load_3, Invoke_3). AMSI é corrigido na inicialização para que Assembly.Load(byte[]) não bloqueie ferramentas conhecidas. Um pipeline separado NativeAOT-WASI pega projetos .NET Framework existentes e produz binários PE únicos para Windows, sem exigir runtime .NET no alvo.
Memória do host e shellcode. Um proxy de memória do host baseado em VirtualAlloc é acessível de dentro do convidado. Isso torna possível usar carregadores COFF/BOF e executar shellcode sem escapar da sandbox WASM.
Yield cooperativo. APIs Win32 bloqueantes (Sleep, WaitForSingleObject, ReadFile e similares) não congelam as goroutines WASM. O host despacha a chamada em uma goroutine de fundo e sinaliza o convidado para ceder até que o resultado esteja pronto.
Saída polimórfica. Cada build produz um binário estruturalmente único. Opcodes WASM são permutados, IDs de seção e bytes mágicos são randomizados, e todos os identificadores, imports PE, strings VERSIONINFO, blocos de licença e nomes de arquivos fonte são eliminados. O fork do wazero incluído é reescrito para corresponder ao bytecode permutado. A criação de perfis Ghost reescreve os símbolos gopclntab para corresponder a binários Go reais de empresas (Traefik, Caddy, Terraform). As saídas para Windows são assinadas com Authenticode por padrão, seja autoassinadas ou falsificando o certificado TLS de um domínio real via osslsigncode.
+-------------------- Convidado WASM (wasip1) --------------------+
| |
| Seu Programa Go (net, net/http, os; funciona transparentemente)|
| |
+----------- ABI go:wasmimport (opcodes personalizados) ----------+
|
+----------- Runtime do Host (fork do wazero por build) ----------+
| |
| 90+ funções do host (redes, proxies de SO, APIs de plataforma) |
| Windows: tradução de ponteiros, memória sombra, espelhamento COM|
| macOS: ponte de frameworks dlopen/dlsym, trampolins ABI |
| |
+----------- wazero (VM personalizada: opcodes/bytes mágicos permutados) ------+
|
Kernel do SO / APIs Windows / Frameworks do macOS
O pipeline de build executa em seis estágios.
syscall/ e net/ para rede WASM. Armazenado em cache em ~/.wasmforge/cache/.GOOS=wasip1 GOARCH=wasm contra a stdlib modificada. Stubs automáticos cobrem lacunas específicas da plataforma. Os shims de sistema para golang.org/x/sys e ebitengine/purego são injetados quando esses imports estão presentes.main.go polimórfico com identificadores randomizados, um fork do wazero correspondente por build, recursos PE embutidos e -trimpath.osslsigncode.O WasmForge compila e executa projetos Go de terceiros não modificados, incluindo aqueles com código complexo específico de plataforma.
| Programa | Plataforma | Descrição | Validado |
|---|---|---|---|
| Sliver | Windows | Framework C2, uso intenso de Win32 | Beacon HTTPS, whoami, ps, netstat, execute-assembly (Rubeus, Seatbelt) |
| Sliver | macOS | Framework C2 (beacon + sessão) | pwd, ls, download, execute, proxy SOCKS5 |
| go-clr | Windows | Hospedagem do CLR .NET + execução de assembly | Cadeia de carregamento CLR, triagem Rubeus, varredura de sistema Seatbelt |
| Chisel | Windows | Túnel TCP/UDP sobre HTTP com SOCKS5 | Conectividade de túnel, encaminhamento de proxy |
| Ligolo-ng | Windows | Tunelamento avançado e pivoting | Interface TUN, conectividade de agente |
| goffloader | Windows | Carregador COFF/BOF usando unsafe.Pointer | VirtualAlloc, execução de shellcode, parsing PE, resolução IAT |
Programas .NET NativeAOT-WASI:
| Programa | Plataforma | Descrição | Validado |
|---|---|---|---|
| Seatbelt | Windows | Enumeração de segurança | A maioria dos comandos passa; alguns que exigem dispatch de callback WMI/Defender são stubs honestos pendentes de suporte da ponte. |
| Rubeus | Windows | Ferramentas Kerberos | Operações de hash + token funcionam diretamente; verbos de rede (asktgt, kerberoast, asreproast) passam pela ponte TCP; consultas LSA (klist, logonsession) correspondem às linhas de base nativas. |
Veja docs/BUILDING-SLIVER.md para um passo a passo do Sliver, e docs/CSHARP.md para o pipeline C#.
O WasmForge é executado em hosts de build Linux, macOS ou Windows. É necessário Go 1.25 ou mais recente.
Alguns recursos exigem configuração extra. Sockets brutos precisam de CAP_NET_RAW ou root. A ponte Win32 precisa de um alvo Windows com --win32-apis (outros alvos retornam ENOSYS). A ponte de frameworks macOS precisa de um alvo macOS e é detectada automaticamente a partir de GOOS=darwin. A assinatura de código precisa de osslsigncode no PATH. Projetos C# precisam do .NET 10 SDK, do workload NativeAOT-LLVM e do WASI SDK 24.0. Alternativamente, a imagem Docker fornecida (abordada em docs/CSHARP.md) já vem com todos eles pré-instalados.
O harness de teste de paridade (test/parity/) e os scripts de configuração de laboratório em scripts/lab-setup/ também assumem um domínio Active Directory montado com Ludus rodando GOAD (Game of Active Directory) — todos os padrões sevenkingdoms.local / kingslanding / SEVENKINGDOMS-CA são padrões do GOAD, substituíveis via variáveis de ambiente WASMFORGE_PARITY_* (veja test/parity/internal/lab/lab.go). Veja docs/internals/PARITY-HARNESS.md e docs/internals/LAB-STABILITY.md para a configuração completa do laboratório.
Comece aqui
| Tópico | Documento |
|---|---|
| Exemplos executáveis (scanner TCP, servidor HTTP, ping ICMP) | examples/README.md |
| Construindo o Sliver de ponta a ponta (Windows + macOS) | docs/BUILDING-SLIVER.md |
| Compilação de projetos C# / .NET (fluxo Docker) | docs/CSHARP.md |
| Alvos macOS e a ponte de frameworks | docs/MACOS.md |
| Uso de perfis Ghost e builds de perfil personalizado | docs/GHOST-PROFILES.md |
Variáveis de ambiente de tempo de build (receita R80, todos os parâmetros WASMFORGE_*) | docs/ENVIRONMENT.md |
Aprofundando
| Tópico | Documento |
|---|---|
| Arquitetura — módulo host, pipeline de build, decisões de design | docs/ARCHITECTURE.md |
| Contribuindo — organização do repositório, pré-requisitos, adicionando funções de host | CONTRIBUTING.md |
| Política de segurança + divulgação | SECURITY.md |
| Código de conduta | CODE_OF_CONDUCT.md |
Referências para mantenedores
| Tópico | Documento |
|---|---|
| Contrato da API do host — exports registrados, estabilidade de assinatura | docs/internals/HOST-API-CONTRACT.md |
| Internals do patcher AST — regras de substituição de string e despacho | docs/internals/AST-PATCHER.md |
| Harness de paridade — executando diffs entre C# nativo e WASM | docs/internals/PARITY-HARNESS.md |
| Estabilidade do laboratório — configuração Ludus + GOAD, scripts watchdog | docs/internals/LAB-STABILITY.md |
Copyright (c) 2025-2026 Praetorian Security, Inc.