keyboard_arrow_up

title: Welcome in our Harem
date: Apr 20, 2026
tags: hackin harem articles


Harem — la plateforme CTF qu'on a fini par coder nous-mêmes

logo harem

TL;DR

Harem est une plateforme CTF complète qu'on développe depuis fin 2023. Infra as code, container dédié par équipe, anti-cheat natif, flag per-user, leaderboard temps réel, badges, boutique, social engineering, gamification. Elle a fait tourner notre édition Hack'In 2025 et 2026 et elle est utilisée en formation et en event d'entreprise. Voici ce qu'elle fait, pourquoi on l'a construite, et quels sont les enjeux derrière.


Pourquoi coder encore une plateforme CTF ?

Organiser un CTF c'est trois métiers en un : créer des challs, monter l'infra, gérer la communauté. Les plateformes existantes couvrent le premier, font semblant sur le deuxième, et ignorent complètement le troisième.

CTFd est le standard de facto. C'est solide, mais la moitié des features qu'on veut sont derrière le plan entreprise : anti-cheat, container dédié, flag par utilisateur. Et tout se configure via l'UI, donc tu cliques, tu oublies ce que t'as fait, tu refais. Pour un CTF qu'on organise chaque année, c'est ingérable. Dès qu'on veut le rendre plus "automatique", on est obligé d'utiliser plein de plugins.

CTFCafé est plus sympa à utiliser mais n'était pas pensé pour les besoins qu'on a. On l'a forké, on y a branché Swarm, ça tenait une heure de plus. Chaque année on finissait avec une plateforme KO à 2 ou 3h du matin devant 150 participants.

À un moment faut accepter que l'outil qu'on veut n'existe pas. On a commencé à coder Harem fin 2023 / début 2024 avec trois requirements au dos d'une serviette :

requirements.txt:
- as code
- private resource
- easy to manage

Un an plus tard on décide de l'utiliser pour notre event, un an et demi plus tard on la pousse dans ses retranchements en foirant totalement un CTF et deux ans plus tard on a enfin une version stable, presque prête pour l'open source.


Ce que Harem fait — les avantages techniques

1. Infra as code, de bout en bout

Sur Harem, chaque équipe a sa propre VM GCP. Elle est provisionnée via Terraform au moment où l'équipe est créée, rattachée à son owner, et détruite proprement en fin d'event. Toute la topologie GCP (réseau, firewall, instance, labels, SSH keys) est décrite en code, versionnée avec le reste du projet.

Le bénéfice c'est triple :

On a aussi écrit notre propre CLI (haremctl) pour tout automatiser : haremctl deploy, haremctl update --set KEY=VALUE, haremctl destroy. C'est le même niveau de DX que d'appeler docker compose up, sauf que derrière c'est 30 VMs.

2. Challenges as code

Chaque chall est un dossier avec son docker-compose.yml, sa description en markdown, ses flags, ses hints, ses catégories, ses points. Pas de champ à remplir dans une UI. Tu veux ajouter un chall ? Tu push sur le repo, tu scrape, il est là.

La plateforme gère nativement :

Sur CTFd, la plupart de ces features sont payantes ou nécessitent ctfcli. Ici c'est le comportement par défaut.

3. Anti-cheat natif et autoban

Trois détections qui tournent en continu :

Les alertes remontent sur un dashboard admin temps réel avec total / flag sharing / suspicious / unauthorized par catégorie. De là, ban d'IP en un clic, blocage de chall pour une équipe, révoquer un solve.

Sur CTFd, il faut l'entreprise plan pour avoir la détection, et le ban se fait à la main.

De plus on est capable de voir si une équipe se connecte à un challenge d'une autre équipe pour ban.

4. Leaderboard temps réel

WebSocket via Socket.io, pas de polling. Quand une équipe flag, le graph se met à jour sur toutes les pages ouvertes en même temps. Les participants peuvent laisser le leaderboard ouvert sur un second écran pendant qu'ils bossent, ils voient la course en live.

Le backend est derrière un cache Redis avec invalidation ciblée — pas de full rebuild à chaque solve. Sur Hack'In 2026 on avait ~130 utilisateurs actifs en simultané, aucun ralentissement.

Le plus gros event que l'on a fait réunissait 1500 personnes et c'est ici qu'on a vu les limites et qu'on a refait toute l'architecture de 0 en fin 2025.

5. Gamification — le système de badges

Au-delà des points, Harem attribue des badges calculés dynamiquement :

Les badges sont reconfigurables côté admin (seuils, activation, TTL du cache). Les retours des participants sur ce système ont été unanimement positifs, et honnêtement c'est la feature que tout le monde préfère.

On distribue les badges physiques pendant la compétition et ça donne d'autres objectifs pour ceux qui ne visent pas le top 3.

6. Challenges physiques (social engineering)

Harem gère nativement les challs qui ne sont pas des containers : les challs de social engineering, les challs physiques. Chaque équipe a un calendrier dans lequel elle peut réserver des créneaux avec les organisateurs, et le flag est validé à la main par un admin. Pas besoin de hack autour de la plateforme pour ça.

7. Boutique et économie interne

Chaque équipe a un solde de points. Elle peut :

La boutique est elle aussi définie en code côté admin, avec des fixedPrice ou des percentageRate (% des points du chall).

8. Un pre-pull intelligent des images

Un des trucs qui tue les plateformes CTF classiques : le cold start. Un user clique « start container », Docker va pull l'image (plusieurs centaines de MB), le container démarre, le chall est dispo 45 secondes plus tard.

Sur Harem, dès qu'une VM est provisionnée, on peut pré-pull toutes les images de challs depuis l'interface admin. Quand l'event démarre et qu'un user clique « start », le container est up en 2-3 secondes parce que l'image est déjà locale.

9. Data management

Harem est pensé pour ne jamais sauvegarder des données "enrichies". Ça a ÉNORMÉMENT d'avantages mais un désavantage absolument énorme qui est la consommation importante de ressources.

Par exemple on ne stocke jamais le leaderboard en base. Ni combien de points une équipe possède. Ni combien de challenges une équipe a solve. On va juste stocker les challenges résolus par utilisateurs.

Ensuite si on veut le nombre de points pour l'équipe à chaque fois on doit récupérer les challenges résolus pour un utilisateur, aller check le nombre de points, les additionner avec les autres challenges, les compute avec ceux des autres membres de l'équipe.

C'est très lourd, mais l'avantage c'est que à tout moment on peut changer le nombre de points d'un challenge pendant la compétition (ou n'importe quelle autre data) sans bousiller la base de données. On change notre .yaml, on rescrappe les challenges et toutes les données sont à jour.

Sauf que au-dessus de 1000 users ça commence à être beaucoup trop gourmand pour la plateforme. Donc voici comment on gère nos datas :

  1. MongoDB => source de vérité, les données sont en RAW et jamais enrichies
  2. Redis => principalement "event-driven" sans TTL et possède les données enrichies (leaderboard, membres d'équipes, badges obtenus...)

Avec un hit rate au-dessus de 90% on réduit la consommation de ressources de Harem, tout en gardant la flexibilité d'une plateforme as code.

Nos routes mettent juste à jour notre cache, sans l'invalider et on a des fallbacks qui viennent l'enrichir. En cas d'incohérence de donnée, l'interface admin expose un panel de cache management qui permet d'invalider toutes les données et de tout reconstruire à partir de mongoDB qui est source de vérité.


Ce que Harem fait — les avantages organisationnels

La techno c'est une chose, mais un CTF c'est avant tout un event à gérer. Harem a été pensée pour que 3 admins puissent gérer 100+ participants en live sans se noyer.

Notation des challenges

Chaque participant peut noter les challenges directement après les avoir solve. Ça permet d'avoir du feedback sur tous nos challenges selon trois facteurs :

De notre côté ce système nous permet de grandement améliorer nos challenges d'année en année.

Support tickets intégrés

Les participants ouvrent un ticket depuis la plateforme, pas besoin de Discord/Slack/email qui se cross. Les admins voient Total / New / Open / Closed, filtrent par équipe / référence, peuvent répondre en markdown avec pièces jointes.

Activity monitor

Un dashboard qui liste :

Quand un user tape au-dessus du seuil, il passe en « suspicious » et apparaît en haut de la liste. Si c'est un cheater, ban IP en un clic. Si c'est un fuzzer, tu modifies le chall pour l'empêcher de fuzzer plutôt que de ban.

Docker containers management

Liste globale de tous les containers tournant sur l'infra. Par container : équipe, chall, port, deployed at. Actions : clean unassigned (les containers orphelins d'une équipe détruite), delete all (après l'event), kill un container précis.

VM management async

DELETE /api/admin/vm/:vmId est asynchrone. Il retourne 202 immédiatement et lance le terraform destroy en background. Les VMs qui restent coincées en deleting > 10 min sont flippées en error par un recovery service au boot. Ça paraît tout con mais si t'as jamais géré un pool de 30 VMs dont certaines rebootent mal à la fin d'un event, tu sais à quel point c'est sauveur.

Demo seeder

Une commande qui remplit la base avec des users, teams, solves fake pour tester les features sur un environnement réaliste. Utile pour onboarder des speakers, tester une release, montrer le produit à un sponsor sans vider le CTF en cours.

Stats admin

Un dashboard complet à destination des orgas :

C'est ce qui nous a permis d'avoir une note moyenne de 4,53/5 sur l'édition 2025 : on sait quels challs sont perçus comme « guessy », lesquels sont « incomprehensible », et on ajuste avant la prochaine édition.


Ce que Harem permet qu'un CTFd ne permet pas

Au-delà des features comparables, il y a trois cas d'usage qu'aucune plateforme publique ne couvre vraiment :

1. Scaling La plateforme provisionne automatiquement les VMs à la création d'équipe, et permet de répartir les équipes sur des VMs. Nous n'avons plus d'infra à gérer à proprement parler, elle est définie dans des terraforms et il suffit de mettre une CB.

2. As code. C'est franchement ultra agréable, tout est fait as code et c'est pensé pour l'être. Il faut juste prendre le temps de générer les accès sous GCP puis on peut redéployer la plateforme instantanément. Elle est ultra flexible sur la gestion des challenges et comme aucune data enrichie n'est sauvegardée en base on peut juste push une update sur notre repo de challenge et la mise à jour se fait instantanément dans la compétition.

3. Flexibilité. L'autre avantage pour nous, c'est qu'on connaît la plateforme par cœur. On est super confiants pour ajouter des features et globalement faire ce qu'on veut. On a beaucoup d'idées et souvent on ne peut pas tout tester avec CTFd et on est dépendant du système de plugin. Puis on n'a pas envie de maintenir un Fork. Alors c'est sûr, avec CTFd tu n'as globalement jamais de problème car la plateforme est super mature. Mais on préfère largement notre flexibilité instable qu'une stabilité qui nous enferme. Au pire on fixe et on redéploie en prod, on a l'habitude 🤡.


Les enjeux

Tout ça c'est le côté rose. Voilà ce qui est moins confortable.

Les quotas cloud

La première fois qu'on a voulu spawn 30 VMs en même temps sur GCP, voilà ce qu'on a pris dans la gueule, dans l'ordre :

  1. Après la 9ᵉ VM → plus de quota pour les IPs publiques
  2. Après resizing → plus de quota CPU
  3. Après resizing → plus de quota d'instances

Chaque demande de quota chez GCP c'est un ticket à justifier, parfois plusieurs jours de délai. On a appris à pré-demander les quotas des mois avant chaque event.

La soutenabilité financière

Chaque event c'est 500-1500€ de GCP sortis de nos poches. Et on n'a pas une visibilité immense dessus. On fait juste les calculs avec les outils de GCP.

Donc on paie à l'usage, un peu en aveugle mais on n'a pas à acheter des serveurs à 10K pour déployer des VMs etc etc. Là on a toujours des machines qui marchent, 0 hardware à gérer, on paie le prix de la liberté et la flexibilité.

Pour info, les trois premières éditions de Hack'In c'était full infra qu'on hébergait nous-mêmes. Plus jamais jamais jamais par pitié.

L'instabilité

On a 500 idées, on passe notre temps à les tester, toujours des nouvelles options et on n'a pas le temps pour la stabilité. C'est pour ça qu'on n'open pas encore la plateforme. Quand un truc ne marche pas, on fix en prod, on a l'habitude maintenant.

Il y a de l'adrénaline, c'est excitant mais globalement on est assez confiants car la façon dont on gère les données nous permet de faire des erreurs. Il suffit de pousser le bon fix pour remettre la compétition en marche sans repartir de zéro.

Exemple : Pour notre 5e édition on a découvert pendant la compétition que notre système de bounty était instable (on l'avait dev la semaine d'avant). En gros, on pouvait dépasser la limite d'équipes pouvant obtenir un bounty sur un challenge.

Sauf qu'on n'a pas un champ bountyAmount dans notre DB qui permet de savoir combien une équipe a gagné en bounty.

Voici notre flow : On recherche les challenges résolus pour un user -> Est-ce que ce challenge a des bounty ? -> combien de bounty sont dispos (bug) -> est-ce que notre utilisateur est éligible au bounty ? -> On l'additionne à nos bounties calculés -> on met dans notre cache bounty:<team-id>:amount le total de notre bounty.

Donc quand on s'est aperçu du bug on a :

Et la compétition pouvait continuer. On n'a pas eu à aller enlever de la valeur dans la DB et prendre le risque de créer des incohérences.

Avec CTFd on n'aurait jamais pu être aussi confiants sur un fix de ce style pendant la compétition. Sauf qu'avec CTFd on n'a pas besoin de faire de fix de ce style car c'est mature. Mais CTFd ne propose pas de système de bounty et nous on en voulait un. Alors il aurait fallu faire un plugin en sachant qu'on est 0 flexible s'il y a un bug.

Donc encore une fois on préfère notre flexibilité instable qu'une stabilité qui nous enferme mais c'est un choix organisationnel.


Retex Hack'In 2026

Quel est votre niveau de satisfaction global de la plateforme de CTF ? : 4.90/5.

Les retours des participants :

« Franchement y'a juste eu 0 problème technique, assez incroyable (miraculeux ?). Hyper agréable d'avoir une plateforme qui fonctionne et qui est globalement super performante (conteneurs qui se start/stop hyper vite, interface fluide, qui s'update avec les bonnes infos). »

« La plateforme de CTF est vraiment très carrée, deux trois petites inconsistences UI/UX mais on est vraiment sur du détail de ouf. Le concept des badges est vraiment incroyable, trop trop bien, rien d'autre à dire. »

« le système de badge et d'achat de badge est masterclasse. je pense même que ça devrait être développé. (nous on sait très bien qu'on ne se bat pas pour le podium, on n'a pas le niveau et on veut juste se régaler, il y a vraiment un truc à faire à ce niveau-là).»


Accès

Si vous êtes organisateur d'event de CTF vous pouvez nous rejoindre ici : https://discord.gg/dSftTaTyBH

À cause de son instabilité nous n'avons pas encore mis le repo en open mais on vous donne volontiers l'accès si vous en avez besoin pour vos prochains events ! Vous avez juste à me ping :)

Pourquoi Harem ?

La réponse à la question qu'on nous pose le plus :

Le projet s'appelle Harem. Oui, on sait. Non, on ne s'en fout pas.

Un harem est un lieu interdit, un endroit interdit aux hommes. Avec cette plateforme CTF « Harem », vous vous retrouvez vous aussi virtuellement dans un endroit où vous pouvez faire des choses qui sont normalement interdites. Un environnement contrôlé où vous vous entraînez à faire des choses qui sont illégales partout ailleurs. Pénétrer dans des systèmes, exploiter des vulnérabilités, contourner la sécurité — tout cela dans un cadre légal.

Donc non, ce n'est pas ce que vous pensez. Mais on ne va pas faire semblant que ce nom ne m'a pas amusé.