Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
wasm2c-tableflip — Escape de sandbox de wasm2c. Un módulo WebAssembly no confiable escapa de la sandbox C generada y ejecuta un comando shell arbitrario en el host. | Kitploit
Herramientas/GitHubGitHub/trustsig-eu/wasm2c-tableflip
Análisis de VulnerabilidadesExplotaciónVirtualización de SeguridadExplotación de Binarios
GitHubtrustsig-eu/wasm2c-tableflip

wasm2c-tableflip

Escape de sandbox de wasm2c. Un módulo WebAssembly no confiable escapa de la sandbox C generada y ejecuta un comando shell arbitrario en el host.

Ver Repositorio
414hace 1 díaAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Escapada de sandbox wasm2c: el módulo invitado ejecuta un comando de shell en el host

Lee el blog: trustsig.eu/blog

wasm_rt_allocate_funcref_table() en wasm2c/wasm-rt-impl-tableops.inc establece table->size a partir del número de elementos declarado por el módulo y luego ignora el resultado de calloc(). Cuando la asignación falla, la tabla queda con data == NULL y el size declarado completo, por lo que todas las comprobaciones de límites siguen pasando y table->data[i] se convierte en la dirección absoluta i * sizeof(wasm_rt_funcref_t).

El número de elementos proviene del invitado, por lo que el invitado elige el tamaño de la asignación y puede forzar el fallo.

Reproducir

root@kitploit:~
git clone https://github.com/trustsig-eu/wasm2c-tableflip.git
cd wasm2c-tableflip
root@kitploit:~
docker build -t wabt-w2c-poc .
docker run --rm wabt-w2c-poc

La imagen clona wabt en la etiqueta 1.0.41 desde el upstream, compila wat2wasm y wasm2c, compila el módulo invitado y un embedder simple, y lo ejecuta.

Salida esperada:

root@kitploit:~
running guest
guest returned 0
--- file on host ---
goodbye sandbox

La última línea es el contenido de /tmp/pwned.txt, un archivo que no existía antes de que el módulo en sandbox se ejecutara.

Verificado en linux/arm64 y linux/amd64. Nada en el módulo es específico de la arquitectura: la dirección de la instancia, la ranura GOT y el desplazamiento de libc se resuelven en tiempo de compilación a partir del binario recién construido y de la libc de esa imagen.

Sin Docker

En Linux, con clang, cmake, ninja y binutils instalados:

root@kitploit:~
git clone --depth 1 --branch 1.0.41 --recurse-submodules --shallow-submodules \
  https://github.com/WebAssembly/wabt ~/wabt
cmake -S ~/wabt -B ~/wabt/out -G Ninja -DCMAKE_BUILD_TYPE=Release \
  -DBUILD_TESTS=OFF -DBUILD_LIBWASM=OFF -DWITH_WASI=OFF
ninja -C ~/wabt/out wat2wasm wasm2c

python3 tableflip_poc.py --wabt-src ~/wabt --wat2wasm ~/wabt/out/wat2wasm \
  --wasm2c ~/wabt/out/wasm2c --run
cat /tmp/pwned.txt

macOS no es un objetivo compatible para este PoC. Darwin no hace cumplir RLIMIT_AS, por lo que el calloc de tamaño excesivo tiene éxito y el fallo nunca se dispara; las compilaciones de macOS en arm64 siempre son independientes de la posición, y Mach-O no tiene GOT ELF para el paso de fuga. El defecto en sí es independiente de la plataforma; solo esta cadena de explotación es específica de Linux.

Otras versiones y comandos:

root@kitploit:~
docker build --build-arg WABT_REF=main -t wabt-w2c-poc .
docker run --rm wabt-w2c-poc bash -c \
  "python3 tableflip_poc.py --run --command 'id > /tmp/pwned.txt' && cat /tmp/pwned.txt"

Qué hace el invitado

  1. Declara (table $t 2147483648 funcref). El calloc de 68 GB falla, data es NULL, size permanece en 2147483648, y los índices de la tabla se convierten en direcciones absolutas.
  2. table.get en got_slot/32 lee el GOT del embedder a través de la tabla rota y table.set almacena el resultado en los propios globales del módulo, donde el código wasm puede leerlo como un entero. Eso filtra la dirección de malloc de libc, y system se deduce a partir de una distancia fija en la libc del objetivo.
  3. Construye un wasm_rt_funcref_t en cuatro globales consecutivos: func_type apuntando a una copia del hash de tipo del sitio de llamada (func_types_eq_slowpath lo compara con , por lo que los bytes controlados por el invitado pasan la comprobación), = , y = la cadena de comando, también mantenida en globales.

El único dato de diseño incrustado en el módulo es la dirección de la instancia del módulo, que es un global y, por tanto, fija en un embedder no PIE. ASLR permanece habilitado; la dirección de libc se filtra en tiempo de ejecución.

Condición de disparo

La asignación de la tabla tiene que fallar. El PoC usa ulimit -v 1000000, un límite de espacio de direcciones del tipo que un host que ejecuta código no confiable establecería. También falla en hosts de 32 bits, donde la asignación no se puede satisfacer en absoluto, con vm.overcommit_memory=2, o bajo suficiente presión de memoria.

En Linux de 64 bits estándar con la heurística de overcommit predeterminada, la asignación tiene éxito y nunca se toca, por lo que el fallo sobrevive a las pruebas normales.

Afectados

Cada lanzamiento que incluye tablas de wasm2c. El calloc sin comprobar data de la confirmación ab9e0b55 (#813). Verificado contra el lanzamiento 1.0.41 y el main actual.

El asignador de memoria en el mismo runtime maneja este caso:

root@kitploit:~
  memory->data = (MEMORY_CELL_TYPE)calloc(byte_length, 1);
  if (byte_length != 0 && !memory->data) {
    abort();
  }

El asignador de tablas necesita la misma comprobación.

Archivos

  • Dockerfile compila wabt y ejecuta el PoC.
  • tableflip_poc.py genera el módulo invitado, compila el embedder, resuelve las tres constantes a partir del binario compilado y de la libc del objetivo con nm y readelf, y lo ejecuta. El embedder que emite no contiene código de soporte de explotación.
Descargar herramienta
memcmp
func
system
module_instance
  • call_indirect en globals_addr/32. wasm2c emite ((t)entry.func)(entry.module_instance, ...), por lo que esto llama a system(command).