Skip to content
KitploitKITPLOIT
FerramentasBlog
Log in
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
wix-kickstartx-challenge-writeup — Análise detalhada de um desafio de CTF: engenharia reversa de um SPA em React, parsing de imagens SVG, criação de um solucionador automatizado com correspondência gulosa e obtenção de uma pontuação perfeita. | Kitploit
Ferramentas/GitHubGitHub/d0rb/wix-kickstartx-challenge-writeup
Engenharia ReversaCTFAprendizado e Educação
GitHubd0rb/wix-kickstartx-challenge-writeup

wix-kickstartx-challenge-writeup

Análise detalhada de um desafio de CTF: engenharia reversa de um SPA em React, parsing de imagens SVG, criação de um solucionador automatizado com correspondência gulosa e obtenção de uma pontuação perfeita.

Ver Repositório

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
13há 4 mesesAinda não revisado

Wix KickstartX Challenge 2026 — Write-up Completo

Resultado: 200/200 (100%) — Token: WKX-9245FA70-200 Data: 24 de março de 2026


1. Descoberta e Reconhecimento

O Anúncio do Desafio

Uma publicação no LinkedIn anunciou um desafio especial para o Wix KickstartX — um programa para desenvolvedores juniores. As regras:

  • 30 minutos, apenas uma tentativa
  • As 10 maiores pontuações avançam diretamente para a fase de exame
  • Dois links fornecidos: wix-kickstartx-challenge-2026.base44.app/ e wixkickstart.com

Encontrando o Ponto de Entrada do Desafio

O site principal wixkickstart.com é um site hospedado na Wix (renderizado no servidor pelo mecanismo Thunderbolt da Wix). Um curl padrão retorna apenas o shell JavaScript — sem conteúdo real. Usamos Chromium headless para renderizá-lo:

chromium --headless --disable-gpu --no-sandbox --virtual-time-budget=10000 \
  --dump-dom "https://wixkickstart.com" > /tmp/wix_rendered.html

Do DOM renderizado extraímos um iframe embutido:

Isso acabou sendo uma animação de partículas p5.js (enfeite da seção hero), não o desafio em si. O desafio real está no app Base44.


2. Engenharia Reversa do App do Desafio

Plataforma: Base44

O desafio roda na Base44 — uma plataforma de apps low-code. O app é uma aplicação React de página única com toda a lógica em um único bundle JS:

https://wix-kickstartx-challenge-2026.base44.app/assets/index-oTG160r9.js

Tamanho: 410.809 bytes (React minificado + lógica do app + SDK Base44)

Extraindo a Superfície da API

Ao buscar no bundle JS, mapeamos toda a API:

FunçãoFinalidade
startGameCria uma sessão de jogo, retorna 200 imagens + 200 descrições
scoreGameAceita {matches: {}, sessionId: ""}, retorna {correctCount: N}
generateTokenRecebe sessionId, retorna token de conclusão
getLeaderboardRetorna as maiores pontuações
saveNicknameSalva o nome de exibição para o leaderboard

Entidades: GameSession, Participant

Padrão de URL da API:

POST /api/apps/{appId}/functions/{functionName}

App ID: 69aea07cbcb9a3dd1039a58d

Constantes-chave do Bundle

const or = 1800;   // Time limit: 1800 seconds (30 minutes)
const rm = 200;    // Total items: 200 image-description pairs

Descoberta do Envio em JSON

Uma descoberta crítica — o app tem um modo de envio em massa por JSON. Do código minificado:

function Ik({onSubmit:r, onClose:n}) {
    // ...
    h = JSON.parse(s)  // Parse JSON input
    // Validation: must be object like { "IMG-001": "DESC-042", ... }
    r(h)  // Submit all matches at once
}

Texto de placeholder no modal:

{
  "IMG-001": "DESC-042",
  "IMG-002": "DESC-017",
  ...
}

Isso significa que não precisamos clicar 200 vezes na interface — podemos enviar um mapeamento JSON de todas as 200 correspondências programaticamente.

Fluxo de Autenticação

O SDK Base44 usa autenticação JWT:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

O payload do JWT contém:

{
  "sub": "[email protected]",
  "exp": 1782162460,
  "iat": 1774386460
}

Cabeçalhos necessários para todas as chamadas de API:

Content-Type: application/json
Authorization: Bearer {jwt_token}
X-App-Id: 69aea07cbcb9a3dd1039a58d
Base44-Functions-Version: prod
X-Origin-URL: https://wix-kickstartx-challenge-2026.base44.app/

3. Entendendo os Dados do Jogo

Resposta de startGame

POST /api/apps/69aea07cbcb9a3dd1039a58d/functions/startGame
Status: 200
Transferred: 62.87 kB compressed (2.20 MB decompressed)
Content-Encoding: br (Brotli)

Estrutura da resposta:

{
  "status": "active",
  "sessionId": "69c2fd218e5b26f307c941c9",
  "startedAt": "2026-03-24T21:07:45.101Z",
  "imageOrder": ["IMG-154", "IMG-102", ...],   // 200 items (display order)
  "descOrder": ["DESC-125", "DESC-109", ...],  // 200 items (display order)
  "imagesData": { "IMG-001": "data:image/svg+xml;base64,...", ... },  // 200 SVGs
  "descriptionsData": { "DESC-105": "milky field, overlaid with...", ... }  // 200 texts
}

Formato de Imagem: SVG Inline (codificado em base64)

Cada imagem é um SVG 200x200 contendo:

  1. Um gradiente de fundo (tema claro ou escuro)
  2. Um padrão de overlay opcional (linhas, pontos, anéis, etc.)
  3. Formas geométricas com cores, tamanhos, opacidade, rotação e posição específicos

Exemplo de SVG decodificado (IMG-001):

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200">
  <defs>
    <linearGradient id="bg" ...>
      <stop offset="0%" stop-color="#f5f0eb"/>
      <stop offset="100%" stop-color="#e8e0d5"/>
    </linearGradient>
  </defs>
  <rect width="200" height="200" fill="url(#bg)"/>
  <!-- Optional overlay lines/dots/rings here -->
  <polygon points="..." fill="#E2725B" transform="translate(128.6,185.7) rotate(90)"
           style="opacity:0.5;filter:drop-shadow(...)"/>
  <!-- More shapes... -->
</svg>

Formato de Descrição: Linguagem Natural Estruturada

Cada descrição segue um padrão estrito:

{background} field[, overlaid with {overlay}]. {N} elements total:
{size} {opacity} {color} {shape} ({rotation}, at {position}) ·
{size} {opacity} {color} {shape} ({rotation}, at {position}) · ...

Exemplo:

milky field, overlaid with tilted cross-lines. 10 elements total:
minuscule nearly solid dim gray pike (steeply angled, at center inner-left) ·
substantial solid azure pike (diagonal, at top center) · ...

4. Construindo o Solucionador Automatizado

Passo 1: Mapear Todas as Constantes

Precisávamos mapear propriedades SVG para o vocabulário das descrições. Isso exigiu analisar todas as 200 imagens e todas as 200 descrições para encontrar correspondências exatas.

Mapeamento de Fundo (12 tipos)

Ao contar ocorrências nos dois lados, estabelecemos um mapeamento 1:1:

Cor Inicial do Gradiente SVGContagemPalavra na DescriçãoContagem
#0a162828pitch28
#eef2f720frosted20
#0d0d0d19tenebrous19
#fef9f018pearlescent18
#1e0a2e18nocturnal18
#0a1a0a17midnight17
#1a0a0a15inky15
#f5f0eb14milky14
#f7f3ee14ethereal14
#f0f0f014radiant14
#f0f7f413glowing13
#1a1a2e10somber10

Método: Contar as cores iniciais únicas do gradiente em todos os 200 SVGs, contar a primeira palavra única em todas as 200 descrições e fazer a correspondência pela contagem.

Mapeamento de Overlay (7 tipos)

Os overlays SVG são implementados de forma diferente conforme o tipo:

Padrão SVGMétodo de DetecçãoContagemNome na DescriçãoContagem
Elementos <line> horizontais (dy=0)Verificar x1,y1,x2,y235striped overlay35
Elementos <line> verticais (dx=0)Verificar x1,y1,x2,y234lattice pattern34
<circle> com opacity="0.06" (pontos)Contar círculos de baixa opacidade30stippled layer30
Nenhum elemento de overlaySem linhas, sem formas de fundo28(nenhum)28
Elementos <line> diagonaisVerificar a direção da inclinação27tilted cross-lines27
<polygon>/<path> pequenos com opacity="0.06"Formas com atributo de baixa opacidade25arrow-band texture25
<circle> com fill="none" stroke="#888"Círculos apenas com stroke21ringed pattern21

Insight-chave: Os elementos de padrão de fundo usam opacity como um atributo XML (por exemplo, opacity="0.06"), enquanto as formas em primeiro plano usam opacity dentro do atributo style (por exemplo, style="opacity:0.7"). Essa distinção foi crucial para separar os padrões de fundo das formas reais.

Baixar ferramenta