Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
wix-kickstartx-challenge-writeup — Compte-rendu détaillé d'un challenge CTF : rétro-ingénierie d'une SPA React, analyse d'images SVG, construction d'un solveur automatisé avec appariement glouton, et obtention d'un score parfait. | Kitploit
Outils/GitHubGitHub/d0rb/wix-kickstartx-challenge-writeup
Rétro-ingénierieCTFApprentissage et Éducation
GitHubd0rb/wix-kickstartx-challenge-writeup

wix-kickstartx-challenge-writeup

Compte-rendu détaillé d'un challenge CTF : rétro-ingénierie d'une SPA React, analyse d'images SVG, construction d'un solveur automatisé avec appariement glouton, et obtention d'un score parfait.

Voir le dépôt

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
9il y a 4 moisPas encore vérifié

Wix KickstartX Challenge 2026 — Writeup complet

Résultat : 200/200 (100 %) — Jeton : WKX-9245FA70-200 Date : 24 mars 2026


1. Découverte et reconnaissance

L'annonce du challenge

Une publication LinkedIn annonçait un challenge spécial pour Wix KickstartX — un programme pour développeurs juniors. Les règles :

  • 30 minutes, une seule tentative
  • Les 10 meilleurs scores passent directement à l'étape de l'examen
  • Deux liens fournis : wix-kickstartx-challenge-2026.base44.app/ et wixkickstart.com

Trouver le point d'entrée du challenge

Le site principal wixkickstart.com est un site hébergé par Wix (rendu côté serveur par le moteur Thunderbolt de Wix). Un curl standard ne renvoie que la coquille JavaScript — aucun contenu réel. Nous avons utilisé Chromium headless pour le rendre :

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

À partir du DOM rendu, nous avons extrait un iframe intégré :

Il s'est avéré que c'était une animation de particules p5.js (un artifice visuel de la section hero), et non le challenge lui-même. Le véritable challenge se trouve dans l'application Base44.


2. Ingénierie inverse de l'application du challenge

Plateforme : Base44

Le challenge s'exécute sur Base44 — une plateforme d'applications low-code. L'application est une application React à page unique avec toute la logique dans un seul bundle JS :

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

Taille : 410 809 octets (React minifié + logique applicative + SDK Base44)

Extraction de la surface d'API

En utilisant grep sur le bundle JS, nous avons cartographié l'intégralité de l'API :

FonctionRôle
startGameCrée une session de jeu, renvoie 200 images + 200 descriptions
scoreGameAccepte {matches: {}, sessionId: ""}, renvoie {correctCount: N}
generateTokenPrend sessionId, renvoie le jeton de complétion
getLeaderboardRenvoie les meilleurs scores
saveNicknameEnregistre le nom affiché pour le classement

Entités : GameSession, Participant

Modèle d'URL d'API :

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

ID d'application : 69aea07cbcb9a3dd1039a58d

Constantes clés du bundle

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

Découverte de la soumission JSON

Une découverte critique — l'application dispose d'un mode de soumission groupée JSON. À partir du source minifié :

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
}

Texte d'espace réservé dans la modale :

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

Cela signifie que nous n'avons pas besoin de cliquer 200 fois dans l'interface — nous pouvons soumettre programmatiquement un mapping JSON des 200 correspondances.

Flux d'authentification

Le SDK Base44 utilise l'authentification JWT :

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Le payload JWT contient :

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

En-têtes requis pour tous les appels 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. Comprendre les données du jeu

Réponse de startGame

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

Structure de la réponse :

{
  "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
}

Format d'image : SVG inline (encodé en base64)

Chaque image est un SVG de 200x200 contenant :

  1. Un dégradé d'arrière-plan (thème clair ou sombre)
  2. Un motif de superposition optionnel (lignes, points, anneaux, etc.)
  3. Des formes géométriques avec des couleurs, tailles, opacités, rotations et positions spécifiques

Exemple de SVG décodé (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>

Format des descriptions : langage naturel structuré

Chaque description suit un modèle strict :

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

Exemple :

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. Construction du solveur automatisé

Étape 1 : cartographier toutes les constantes

Nous devions faire correspondre les propriétés SVG au vocabulaire des descriptions. Cela nécessitait d'analyser les 200 images et les 200 descriptions pour trouver des correspondances exactes.

Mapping des arrière-plans (12 types)

En comptant les occurrences des deux côtés, nous avons établi un mapping 1:1 :

Couleur de début de dégradé SVGNombreMot de descriptionNombre
#0a162828pitch28
#eef2f720frosted20
#0d0d0d19tenebrous19
#fef9f018pearlescent18
#1e0a2e18nocturnal18
#0a1a0a17midnight17
#1a0a0a15inky15
#f5f0eb14milky14
#f7f3ee14ethereal14
#f0f0f014radiant14
#f0f7f413glowing13
#1a1a2e10somber10

Méthode : compter les couleurs de début de dégradé uniques dans les 200 SVG, compter les premiers mots uniques dans les 200 descriptions, faire correspondre par nombre.

Mapping des superpositions (7 types)

Les superpositions SVG sont implémentées différemment selon le type :

Motif SVGMéthode de détectionNombreNom de descriptionNombre
Éléments <line> horizontaux (dy=0)Vérifier x1,y1,x2,y235striped overlay35
Éléments <line> verticaux (dx=0)Vérifier x1,y1,x2,y234lattice pattern34
<circle> avec opacity="0.06" (points)Compter les cercles à faible opacité30stippled layer30
Aucun élément de superpositionAucune ligne, aucune forme d'arrière-plan28(aucun)28
Éléments <line> diagonauxVérifier la direction de la pente27tilted cross-lines27
Petits <polygon>/<path> avec opacity="0.06"Formes avec attribut de faible opacité25arrow-band texture25
<circle> avec fill="none" stroke="#888"Cercles avec contour uniquement21ringed pattern21
Télécharger l’outil