Sploitus

Exploit for shockwave-poc

githubexploit · 2026-08-28

Exploit Code

README167 lines
## https://sploitus.com/exploit?id=2E03DFDA-D902-5B1E-98E4-75EC5243C83B
# Shockwave POC

# Shockwave POC — Comparação DirPlayer vs LibreShockwave (WASM, Shockwave/Director no Browser)

    6 de junho de 2026

  Proof of Concept técnica para avaliar viabilidade de rodar jogos **Shockwave/Director (.dcr)** legados no navegador moderno via **WebAssembly**. Comparação lado a lado de 2 runners independentes: **DirPlayer v0.5.1** (Ruffle fork Rust→WASM para Director) e **LibreShockwave Nightly 06062026** (Java→TeaVM→WASM). Backend PHP minimal (router MIME fix, upload/asset/manifest/cleanup APIs), frontend 2 páginas idênticas com console de debug unificado, upload ZIP/.dcr com extração automática e manifesto JSON. Assets de teste reais: **Phosphor Beta 2.043** (jogo 3D FPS Shockwave completo). Zero framework, zero composer, zero DB, zero build, totalmente offline.

## Arquitetura: POC Isolada — 2 Runners WASM + PHP API Minimal

```
0-POC/Shockwave_POC/
├── router.php                    # Built-in server router: .wasm → application/wasm
├── shockwave-poc-dirplayer.php   # Página DirPlayer v0.5.1
├── shockwave-poc-libreshockwave.php # Página LibreShockwave Nightly
├── poc.css                       # Dark theme, canvas full-size, console log color-coded
├── poc.js                        # Console interceptor, upload handler, result panel
├── api/
│   ├── upload.php                # POST multipart .dcr/.zip → extrai + manifesto JSON
│   ├── asset.php                 # GET asset com path traversal protection + CORP headers
│   ├── manifest.php              # GET manifesto .mp_shockwave.json
│   └── cleanup.php               # POST limpeza uploads >1h
├── assets/vendor/
│   ├── bootstrap/                # Bootstrap 5.3.3 local (CSS + Bundle JS)
│   └── jquery/                   # jQuery 3.7.1 local
├── runners/
│   ├── dirplayer/                # DirPlayer v0.5.1: dirplayer-polyfill.js + ruffle/ + .wasm
│   └── libreshockwave/           # LibreShockwave: libreshockwave.js + player-wasm.wasm (~33MB) + runtime.js
└── uploads/                      # 4 uploads de teste Phosphor Beta 2.043 pré-carregados
```

  Fluxo: usuário abre página → seleciona .dcr ou .zip → upload via AJAX → backend extrai ZIP se necessário → gera manifesto JSON com entrypoints → frontend popula seletor entrypoint → usuário clica "Carregar" → runner WASM carrega jogo no `` → console unificado loga tudo.

## DirPlayer v0.5.1: Ruffle Fork para Director (Rust→WASM)

    - **Origem:** `github.com/igorlira/dirplayer-rs` — fork do Ruffle focado em Director/Shockwave

    - **Stack:** Rust → WASM via `wasm-pack`

    - **Arquivos:** `dirplayer-polyfill.js` (IIFE) + `ruffle/dirplayer_ruffle.js` + `c04588933f7297820bf4.wasm`

    - **API:** `window.DirPlayer = {init, configureFlash}`, `window.dirplayer_RufflePlayer.newest().createPlayer().load(url)`

    - **Correção documentada:** `player.load()` direto (não `player.ruffle().load()`)

    - **Status:** "A testar" (README)

## LibreShockwave Nightly: Java → TeaVM → WASM

    - **Origem:** `github.com/Quackster/LibreShockwave` — reimplementação Java do player Shockwave

    - **Stack:** Java (LibreShockwave) → **TeaVM** → WASM

    - **Arquivos:** `libreshockwave.js` + `player-wasm.wasm` (~33 MB) + `player-wasm.wasm-runtime.js`

    - **API:** `LibreShockwave.create('stage', {autoplay, onLoad, onError, onFrame}).load(url)`

    - **Threading:** **SharedArrayBuffer** — requer `COOP/COEP` headers

    - **Correção documentada:** `ImageData` SharedArrayBuffer fix (cópia antes de `new ImageData`)

## Backend PHP: API Minimal + Router MIME Fix

### router.php — Built-in Server WASM MIME Fix

```
// Fix: PHP built-in server não serve .wasm com MIME correto
if (preg_match('/\.wasm$/', $_SERVER['REQUEST_URI'])) {
  header('Content-Type: application/wasm');
  readfile(__DIR__ . $_SERVER['REQUEST_URI']);
  exit;
}
// Demais arquivos servidos normalmente
```

  Resolve `WebAssembly.instantiateStreaming` warning no console.

### api/upload.php — Upload + Extração ZIP + Manifesto

    - Valida extensão: `.dcr, .dir, .dxr, .zip` (blocklist: .php, .phar, .exe, .sh)

    - Tamanho máx: 100MB

    - Se ZIP: `ZipArchive` extrai preservando estrutura → detecta `.dcr` raiz como entrypoints

    - Gera `uploads/{id}/.mp_shockwave.json` manifesto

    - Retorna JSON: `{success, upload_id, entrypoints[]}`

### api/asset.php — Serving Seguro

    - `realpath()` + prefix check → **path traversal protection**

    - Extension blocklist novamente

    - MIME correto (inclui `application/wasm`)

    - Headers: `Cross-Origin-Resource-Policy: cross-origin`, `Cache-Control`

### COOP/COEP Headers (LibreShockwave)

```
// shockwave-poc-libreshockwave.php (TOP, antes de qualquer output)
header('Cross-Origin-Opener-Policy: same-origin');
header('Cross-Origin-Embedder-Policy: require-corp');
```

  Obrigatório para `SharedArrayBuffer` (threading TeaVM).

## Frontend: Console Debug Unificado (poc.js)

    - Intercepta: `console.log/info/warn/error` + `unhandledrejection` + `window.onerror`

    - Wrapper `fetch` + `XHR` → loga request/response com timestamps

    - Tags coloridas no painel: `[log]` cinza, `[info]` azul, `[warn]` amarelo, `[error]` vermelho, `[fetch]` ciano, `[xhr]` magenta

    - Stack trace capturado em erros

    - Upload handler: `FormData`, progress, popula seletor entrypoint do manifesto

    - Painel resultado manual: radio Aprovado/Parcial/Reprovado + observação + copy JSON

## Assets de Teste: Phosphor Beta 2.043

    - Jogo Shockwave 3D FPS completo (`www.rasterwerks.com/game/phosphor/`)

    - Entrypoint `.dcr` + assets `.dat/.cct/.ini`

    - 4 uploads de teste pré-carregados em `uploads/`

    - Teste real de carga 3D, texturas, física, input

## Deploy

    1. PHP 8.x + `fileinfo` + `json` (extensão `zip` opcional para .zip)

    2. `php -S localhost:8080 router.php` (dev)

    3. Produção: Apache/Nginx com `COOP/COEP` headers configurados + `.wasm` MIME

    4. Abrir `shockwave-poc-dirplayer.php` ou `shockwave-poc-libreshockwave.php`

## Limitações Conhecidas

    - **LibreShockwave ~33 MB WASM** — carregamento lento primeira vez (cache browser ajuda)

    - **DirPlayer integração "A testar"** — API pode mudar, compatibilidade incerta

    - **COOP/COEP quebra** se servido via proxy/reverse proxy sem repassar headers

    - **PHP built-in server apenas dev** — produção precisa Apache/Nginx

    - **Zero persistência resultados** — apenas painel manual (JSON export)

    - **Sem testes automatizados**

    - **Zero TypeScript, zero build tool**

    - **SharedArrayBuffer** não funciona em contextos cross-origin sem COOP/COEP

    - **TeaVM runtime** single-threaded fallback se SAB indisponível (mais lento)

  POC técnica valiosa para preservação digital de conteúdo Shockwave/Director. Para versão robusta: indexação automática de assets .dcr web (commoncrawl/wayback), fallback Ruffle nativo (SWF), wrapper Electron/Tauri para desktop (bypassa COOP/COEP), streaming WASM (instantiation streaming), testes automatizados com Playwright + fixtures .dcr conhecidos, CI/CD, documentação API runners.

    Autor: Keven Castilho (kevencastilho.github.io). Jun/2026. PHP 8.x + Vanilla JS ES6+ (poc.js console interceptor, upload handler) + DirPlayer v0.5.1 (Rust→WASM via Ruffle fork) + LibreShockwave Nightly (Java→TeaVM→WASM ~33MB) + Bootstrap 5.3.3/jQuery 3.7.1 local. Zero framework, zero composer, zero DB, zero build. Offline-first.