WasmForge — compila programas Go y C# a ejecutables nativos en un solo binario, con sandbox WASM y salida polimórfica.
WasmForge compila programas en Go y C# a WebAssembly, luego los empaqueta como binarios nativos individuales. Los ejecutables resultantes aíslan el código invitado dentro de un runtime WASM (una bifurcación por compilación de wazero). Desde dentro de esa caja de arena, los invitados obtienen acceso transparente a redes, sockets sin procesar, APIs Win32 y APIs de frameworks de macOS.
Puedes escribir Go normal usando net.Dial, net.Listen o net/http. También puedes migrar un proyecto .NET Framework C# existente. De cualquier manera, el resultado es un solo binario que se ejecuta en Windows o macOS, sin requerir que el usuario realice modificaciones en el código fuente invitado.

Un vistazo rápido a este proyecto dejará bastante claro que se desarrolló con un uso INTENSO de LLMs. Parte de la documentación también lo ha sido, pero esta sección no. He hecho todo lo posible por des-simplificar este README, además de hacer que el proceso para usar WasmForge sea lo más directo posible. También, aunque los LLMs escribirán documentación que halaga en gran medida sus propios logros, las limitaciones no se hacen TAN claras.
Para establecer expectativas adecuadamente, aunque esto se ha probado con muchas características diferentes para Go, NO es una solución completa para todos los programas Go. Todavía hay un porcentaje saludable de la API win32 que no está soportada adecuadamente (como las APIs que requieren thunks de callback). Sliver, por ejemplo, funciona para una buena cantidad de comandos, pero NO es un puerto 1:1 completo con funcionalidad. , por ejemplo, seguirá mostrando rutas con en lugar de la tradicional , ya que el blob WASM no está completamente engañado para darse cuenta de que está dentro de Windows. Hay otras capacidades que simplemente provocarán un bloqueo. Si hay algo que no funciona, intenta construir el ejemplo más básico de la API que está rota y abre un issue / envía un PR.
ls/C:\El lado de C# es, en última instancia, más una prueba de concepto que una implementación. El proceso que se usa para compilar C# a WASM es demasiado experimental y significa que WasmForge a menudo necesita reescribir una parte considerable del programa de todos modos para que funcione. Al final, probablemente profundicé demasiado en esta capacidad y debería haber recomendado que la gente use un LLM para reescribir código C# como código Go. Probablemente sea menos doloroso de manejar. Dicho esto, el patrón general de C# -> Wasm -> WasmForge SÍ funciona y rompe una buena cantidad de detecciones específicas de C#.
En ese sentido, WasmForge está principalmente diseñado para lidiar con detecciones ESTÁTICAS. El proceso de transpilación rompe la mayoría de las detecciones, incluso para el escaneo en memoria, pero en última instancia, si tu binario tiene algunas cadenas muy obvias como mimikatz o sliver, hay algunos escaneos en memoria de bajo esfuerzo que causarán una detección. La ofuscación automática de cadenas probablemente se agregará en el futuro, ya que es una característica bastante fácil de automatizar, pero para la primera versión no quise agregar complejidad adicional al pipeline de compilación para mantener la depuración relativamente sencilla.
Si bien se han realizado algunos esfuerzos para limpiar/consolidar el código fuente en este repositorio, sigue estando bastante desorganizado. Hay varias carpetas diferentes para diferentes procesos de prueba. Las pruebas unitarias básicas tienden a vivir en examples/ y test/, mientras que algunas de las pruebas más complejas destinadas a ejecutarse en un entorno de laboratorio completo viven en testdata/. También hay una serie de herramientas solo para desarrollo/pruebas que viven en las carpetas scripts/ y internal/devtools. Estas solo serán necesarias si intentas configurar tu propio entorno de prueba para realizar más desarrollo. En general, cualquier desarrollo de LLM de algo tan complicado requiere una serie de casos de prueba muy explícitos para guiar la generación; de lo contrario, terminas con algo que no funciona en absoluto. El proyecto incluye estos harnesses para que cualquier persona curiosa pueda continuar su propio desarrollo de herramientas o contribuir al proyecto.
Espero que la comunidad encuentre estas herramientas relativamente fáciles de usar y con el tiempo continuaremos mejorándolas. Quizás algún día la compilación de C# funcione tan bien como la compilación de Go.
Hay tres formas de obtener wasmforge:
Binario precompilado. Descarga una versión de la página de Releases — hay compilaciones del CLI para Linux, macOS y Windows adjuntas a cada tag.
Imagen Docker. Para proyectos C# / .NET, la imagen incluida trae todos los
prerrequisitos (.NET 10 SDK, workload NativeAOT-LLVM, WASI SDK 24.0,
wasm-ld, osslsigncode) preinstalados. Constrúyela una vez con
make docker-build y ejecútala con make docker-run — consulta
docs/CSHARP.md para el flujo de trabajo completo. Esta es la
ruta recomendada para C#.
Compilar desde el código fuente.
make build
make build regenera el archivo internal/build/build_assets.tar.gz incrustado
y luego compila el CLI. Si solo ejecutas go build -o wasmforge ./cmd/wasmforge obtendrás un binario funcional, pero las compilaciones en modo distribución
(cuando el CLI se ejecuta fuera de este árbol de fuentes) usarán un archivo incrustado
obsoleto. Consulta CONTRIBUTING.md para una explicación más detallada.
El directorio examples/ contiene programas Go ejecutables que puedes compilar de inmediato.
Consulta examples/README.md para la lista completa.
GOOS=windows GOARCH=amd64 ./wasmforge build \
--ghost traefik \
-o myapp.exe \
/ruta/a/tu/proyecto
El puente de la API Win32 se activa automáticamente siempre que GOOS=windows — ya no
necesitas pasar --win32-apis para el caso común.
--ghost traefik intercambia la distribución de símbolos gopclntab incrustada para que se parezca al proxy inverso Traefik. De los perfiles incluidos, este produce la tasa de detección más baja en VirusTotal. Otros perfiles e instrucciones para generar los tuyos propios están en docs/GHOST-PROFILES.md.
Los binarios para Windows se firman automáticamente con un certificado autofirmado de forma predeterminada. Usa --sign google.com para suplantar el certificado TLS de un dominio, o --no-sign para deshabilitar la firma por completo.
# Intel
GOOS=darwin GOARCH=amd64 ./wasmforge build -o myapp /ruta/a/tu/proyecto
# Apple Silicon
GOOS=darwin GOARCH=arm64 ./wasmforge build -o myapp /ruta/a/tu/proyecto
No se requieren banderas adicionales. El puente de frameworks de macOS se activa automáticamente siempre que GOOS=darwin. Consulta docs/MACOS.md para el puente de frameworks, soporte de purego/ObjC y otras notas específicas de Apple.
# Soporte de sockets sin procesar (requiere CAP_NET_RAW o root en tiempo de compilación)
./wasmforge build --raw-sockets -o myapp ./ruta/al/proyecto
# Salida verbosa (útil para primeras compilaciones)
GOOS=windows GOARCH=amd64 ./wasmforge build --ghost traefik --win32-apis -v -o tool.exe /ruta/al/proyecto
# VERSIONINFO de PE personalizado (solo Windows)
./wasmforge build --pe-company "Acme Corp" --pe-product "AcmeTool" --pe-file-version "10.0.19041.1" ...
Los proyectos C# (archivos .csproj) se detectan automáticamente. WasmForge ejecuta todo el pipeline de migración, parcheo y compilación NativeAOT-WASI en un solo comando:
GOOS=windows GOARCH=amd64 ./wasmforge build --win32-apis -o seatbelt.exe ruta/a/Seatbelt/Seatbelt/
Para trabajos en C#, recomendamos encarecidamente el entorno de compilación Docker. Incluye todos los prerrequisitos (.NET 10 SDK, workload NativeAOT-LLVM, WASI SDK 24.0, wasm-ld) para que no necesites instalar ninguno de ellos en el host. Las instrucciones completas están en docs/CSHARP.md.
wasmforge build [paquete] Compila un paquete Go (o C#) a un binario nativo con caja de arena WASM
-o, --output <ruta> Ruta del binario de salida
--ghost <nombre> Perfil ghost: traefik, caddy, terraform (ver docs/GHOST-PROFILES.md)
--raw-sockets Habilita soporte de sockets sin procesar
--win32-apis Habilita el puente de la API Win32 (objetivos Windows)
--sign <modo> Firma el binario: 'self' o nombre de dominio (predeterminado: self para Windows)
--no-sign Deshabilita la autofirma predeterminada para objetivos Windows
--tags <tags> Tags de compilación Go (separados por comas)
--pe-company / --pe-product / --pe-description / --pe-copyright / --pe-file-version
Sobrescrituras de VERSIONINFO de PE
-v, --verbose Salida de compilación verbosa
wasmforge run [paquete] Compila y ejecuta inmediatamente
wasmforge clean Elimina GOROOTs parcheados en caché (~/.wasmforge/cache/)
wasmforge version Muestra la versión
wasmforge dotnet-migrate <dir> Migra un proyecto .NET Framework a .NET 10 NativeAOT-WASI
wasmforge dotnet-patch <dir> Aplica parches de código fuente C# para NativeAOT-WASI
WasmForge tiende un puente entre WASM y el host subyacente para que los programas invitados no tengan que hacerlo.
APIs de plataforma. TCP, UDP, DNS, HTTP, TLS y sockets sin procesar funcionan sin cambios en el código invitado tanto en Windows como en macOS. En Windows, WasmForge actúa como proxy de toda la superficie Win32: registro, E/S de archivos, procesos, carga de DLL y SyscallN con hasta 15 argumentos. La traducción de punteros es automática. Las cadenas vtable de COM se reflejan para que el CLR y otras APIs con uso intensivo de COM funcionen de extremo a extremo. En macOS, dlopen y dlsym alcanzan cualquier framework (Security, CoreGraphics, IOKit, etc.), y ebitengine/purego más el runtime de Objective-C funcionan de inmediato.
Hosting y migración de .NET. El CLR se carga a través de la cadena estándar (CoInitializeEx, CLRCreateInstance, Load_3, Invoke_3). AMSI se parchea al inicio para que Assembly.Load(byte[]) no bloquee herramientas conocidas. Un pipeline separado de NativeAOT-WASI toma proyectos .NET Framework existentes y produce binarios PE individuales para Windows sin necesidad de runtime .NET en el objetivo.
Memoria del host y shellcode. Un proxy de memoria del host respaldado por VirtualAlloc es accesible desde el invitado. Esto hace posibles los cargadores COFF/BOF y la ejecución de shellcode sin salir de la caja de arena WASM.
Ceder cooperativamente. Las APIs Win32 bloqueantes (Sleep, WaitForSingleObject, ReadFile y similares) no congelan las goroutines WASM. El host envía la llamada a una goroutine en segundo plano y señala al invitado que ceda hasta que el resultado esté listo.
Salida polimórfica. Cada compilación produce un binario estructuralmente único. Los opcodes WASM se permutan, los IDs de sección y los bytes mágicos se aleatorizan, y se eliminan todos los identificadores, importaciones PE, cadenas VERSIONINFO, bloques de licencia y nombres de archivos fuente. La bifurcación de wazero incluida se reescribe para que coincida con el bytecode permutado. El perfilado ghost reescribe los símbolos gopclntab para que coincidan con binarios Go empresariales reales (Traefik, Caddy, Terraform). Las salidas de Windows se firman con Authenticode de forma predeterminada, ya sea con autofirma o suplantando el certificado TLS de un dominio real mediante osslsigncode.
+-------------------- Invitado WASM (wasip1) --------------------+
| |
| Tu programa Go (net, net/http, os; funciona de forma transparente) |
| |
+----------- ABI go:wasmimport (opcodes personalizados) --------------+
|
+----------- Runtime Host (bifurcación de wazero por compilación) ------------+
| |
| 90+ funciones del host (redes, proxies del SO, APIs de plataforma) |
| Windows: traducción de punteros, memoria sombra, reflejo COM |
| macOS: puente de frameworks dlopen/dlsym, trampolines ABI |
| |
+----------- wazero (VM personalizada: opcodes/magia permutados) ------+
|
Núcleo del SO / APIs de Windows / Frameworks de macOS
El pipeline de compilación se ejecuta en seis etapas.
syscall/ y net/ para redes WASM. Se almacena en caché en ~/.wasmforge/cache/.GOOS=wasip1 GOARCH=wasm contra la stdlib parcheada. Los stubs automáticos cubren las brechas específicas de la plataforma. Se inyectan sysshims para golang.org/x/sys y ebitengine/purego cuando esas importaciones están presentes.main.go polimórfico con identificadores aleatorios, una bifurcación de wazero correspondiente por compilación, recursos PE incrustados y -trimpath.osslsigncode.WasmForge compila y ejecuta proyectos Go de terceros sin modificar, incluidos aquellos con código complejo específico de la plataforma.
| Programa | Plataforma | Descripción | Validado |
|---|---|---|---|
| Sliver | Windows | Framework C2, uso intensivo de Win32 | Beacon HTTPS, whoami, ps, netstat, execute-assembly (Rubeus, Seatbelt) |
| Sliver | macOS | Framework C2 (beacon + sesión) | pwd, ls, download, execute, proxy SOCKS5 |
| go-clr | Windows | Hosting CLR .NET + ejecución de ensamblados | Cadena de carga CLR, triaje de Rubeus, escaneo del sistema con Seatbelt |
| Chisel | Windows | Túnel TCP/UDP sobre HTTP con SOCKS5 | Conectividad de túnel, reenvío de proxy |
| Ligolo-ng | Windows | Tunelización y pivoteo avanzado | Interfaz TUN, conectividad del agente |
| goffloader | Windows | Cargador COFF/BOF usando unsafe.Pointer | VirtualAlloc, ejecución de shellcode, análisis PE, resolución IAT |
Programas .NET NativeAOT-WASI:
| Programa | Plataforma | Descripción | Validado |
|---|---|---|---|
| Seatbelt | Windows | Enumeración de seguridad | La mayoría de los comandos pasan; algunos que requieren despacho de callback WMI / Defender se dejan con stubs honestos pendientes de soporte del puente. |
| Rubeus | Windows | Herramientas Kerberos | Las operaciones de hash + token funcionan directamente; los verbos de red (asktgt, kerberoast, asreproast) pasan por el puente TCP; las consultas LSA (klist, logonsession) coinciden con las líneas base nativas. |
Consulta docs/BUILDING-SLIVER.md para un tutorial paso a paso de Sliver, y docs/CSHARP.md para el pipeline de C#.
WasmForge se ejecuta en hosts de compilación Linux, macOS o Windows. Se requiere Go 1.25 o más reciente.
Algunas características necesitan configuración adicional. Los sockets sin procesar necesitan CAP_NET_RAW o root. El puente Win32 necesita un objetivo Windows con --win32-apis (otros objetivos devuelven ENOSYS). El puente de frameworks de macOS necesita un objetivo macOS y se detecta automáticamente desde GOOS=darwin. La firma de código necesita osslsigncode en el PATH. Los proyectos C# necesitan el SDK de .NET 10, el workload NativeAOT-LLVM y WASI SDK 24.0. Alternativamente, la imagen Docker incluida (cubierta en docs/CSHARP.md) viene con todos ellos preinstalados.
El harness de pruebas de paridad (test/parity/) y los scripts de instalación de laboratorio en scripts/lab-setup/ asumen adicionalmente un rango de Active Directory montado con Ludus ejecutando GOAD (Game of Active Directory) — cada valor predeterminado sevenkingdoms.local / kingslanding / SEVENKINGDOMS-CA es un valor predeterminado de GOAD, que se puede anular mediante las variables de entorno WASMFORGE_PARITY_* (consulta test/parity/internal/lab/lab.go). Consulta docs/internals/PARITY-HARNESS.md y docs/internals/LAB-STABILITY.md para la configuración completa del laboratorio.
Empieza aquí
| Tema | Documento |
|---|---|
| Ejemplos ejecutables (escáner TCP, servidor HTTP, ping ICMP) | examples/README.md |
| Compilación de Sliver de principio a fin (Windows + macOS) | docs/BUILDING-SLIVER.md |
| Compilación de proyectos C# / .NET (flujo de trabajo Docker) | docs/CSHARP.md |
| Objetivos macOS y el puente de frameworks | docs/MACOS.md |
| Uso de perfiles ghost y compilación de perfiles personalizados | docs/GHOST-PROFILES.md |
Variables de entorno en tiempo de compilación (receta R80, todas las opciones WASMFORGE_*) | docs/ENVIRONMENT.md |
Para profundizar
| Tema | Documento |
|---|---|
| Arquitectura — módulo host, pipeline de compilación, decisiones de diseño | docs/ARCHITECTURE.md |
| Contribuciones — estructura del repositorio, prerrequisitos, añadir funciones del host | CONTRIBUTING.md |
| Política de seguridad + divulgación | SECURITY.md |
| Código de conducta | CODE_OF_CONDUCT.md |
Referencias para mantenedores
| Tema | Documento |
|---|---|
| Contrato de la API del host — exportaciones registradas, estabilidad de firmas | docs/internals/HOST-API-CONTRACT.md |
| Internos del parcheador AST — reglas de reemplazo de cadenas y despacho | docs/internals/AST-PATCHER.md |
| Harness de paridad — ejecución de diferencias entre C# nativo y WASM | docs/internals/PARITY-HARNESS.md |
| Estabilidad del laboratorio — configuración de Ludus + GOAD, scripts watchdog | docs/internals/LAB-STABILITY.md |
Copyright (c) 2025-2026 Praetorian Security, Inc.