Locked Shields 2024
Sommaire
Objectif / Public visé #
Ce post s’adresse notamment à des étudiants en cybersécurité de l’ENSIBS qui seraient susceptibles de travailler à nouveau sur l’événement Locked Shields.
J’essaierai de retracer chronologiquement les différentes étapes, que ce soit côté école ou côté OTAN, tout en donnant mon point de vue sur les événements afin de donner une idée plus précise aux futurs étudiants et de les conseiller au mieux.
Je me concentrerai surtout sur la description organisationnelle et assez peu sur la face technique pour la simple et bonne raison que je ne suis pas autorisé à partager de nombreuses informations (certains équipements, scénarios ou vulnérabilités sont réutilisées chaque année pour l’exercice).
Evidemment, ce post n’est pas seulement réservé aux étudiants de l’ENSIBS, n’importe quelle personne curieuse de connaître l’envers du décor est invitée à continuer sa lecture.
Introduction #
En dernière année d’études d’ingénieur cyberdéfense à l’ENSIBS, tous les élèves doivent réaliser un projet sur le thème de leur choix pendant environ 5 mois.
Certains choisissent de réaliser un travail de recherches, d’autres de développer une solution, il n’est pas surprenant de voir des projets se transformer en start-up après l’obtention du diplôme et pour être honnête c’était l’une de mes idées également.
J’avais envie de faire partie d’un projet plus marquant que le cadre universitaire, mais pour cela il faut d’abord choisir un projet.
2 solutions possibles :
- Proposer soi-même un sujet et le faire valider par des professeurs (le sujet doit forcément avoir un lien avec la cybersécurité)
- Choisir un projet dans la liste proposée par les professeurs, dont voici un extrait :
C’est en partageant cette liste que des professeurs nous annoncèrent un partenariat entre l’ENSIBS et l’Université de Tallinn (Estonie). On nous annonça qu’un groupe aurait la chance de participer à l’organisation de Locked Shields
cette année et que pour obtenir cette place il faudrait se montrer motivé !
C’est quoi Locked Shields ? #
Considéré comme l’exercice de cybersécurité le plus important au monde, Locked Shields est organisé chaque année par le NATO Cooperative Cyber Defence Centre of Excellence (CCDCOE) et l’Université de Tallinn pour entraîner les équipes de l’OTAN.
Il s’agit d’un exercice opposant des Blue Team
contre des Red Team
. Les Red Teams jouent le rôle d’attaquants, leur objectif est de compromettre les infrastructures des Blue Teams. Ces dernières, ont pour mission de défendre les systèmes informatiques en temps réel d’un pays entier fictif simulé par plus de 5000 systèmes. Le nom de ce pays : “Berylia
”
Le but de cet exercice est de renforcer les liens entre les pays membres de l’OTAN et de les entraîner en cas de cyberattaques coordonnées.
Rien de surprenant lorsque l’on sait que le CCDCOE a été créé à la suite d’une cyberattaque russe contre l’Estonie en 2007 : Le Monde
L’équipe (de choc) #
Avant même de sélectionner un projet il faut d’abord former une équipe de 4 à 5 personnes !
Il s’avère que j’ai vite trouvé des camarades motivés pour participer à l’organisation de l’exercice. Après quelques discussions nous avions désormais une équipe :
- Tanguy Pascal
- Benjamin Guillouzo (BenJ)
- Benjamin Reichling (Ben)
- Moi 😎
Plusieurs équipes étaient également intéressées par Locked Shields, les professeurs nous ont alors demandés de choisir un 2ème projet dans le cas où nous ne serions pas sélectionnés.
Nous pensions que les professeurs allaient nous faire passer un petit entretien de motivation et nous étions prêts.
Mais finalement, aucun entretien de motivation n’a été réalisé et je ne crois pas que c’était dans les plans des professeurs. Leur but était plutôt d’attendre que nous réglions ça entre étudiants, pour cela ils fixèrent une date butoir.
Notre stratégie était simple : ne proposer aucune solution de secours et faire l’autruche pour forcer le choix de notre équipe.
Eh bien, croyez le ou non mais toutes les autres équipes ont proposées un 2ème projet et ont fini par se diriger vers celui-ci.
Stratégie efficace → nous la recommandons.
Nous étions désormais officiellement sélectionnés pour participer à l’organisation de Locked Shields (grâce au talent) !
Informations pratiques #
Les plannings #
Tous les projets sont soumis à un planning décidé par l’école, celui-ci est découpé en “jalons”, à la fin de chaque jalon nous devons faire une présentation de notre avancement aux professeurs et leur rendre notre code source.
Rien de surprenant pour un projet universitaire, mais la particularité de ce projet c’est qu’en plus du planning école, nous devons également respecter le planning de l’OTAN.
Voici à quoi ressemblent approximativement les plannings :
Ce qu’il faut retenir de ces plannings :
- Il n’y a qu’une seule réunion d’informations côté OTAN, après celle-ci pour toute question ou demande il faut directement s’adresser à des contacts
- Ceux-ci ne répondent pas très rapidement → il faut donc prévoir à l’avance les demandes / questions
- Il est important de bien écouter lors de cette réunion car beaucoup d’informations sont données oralement
- Il ne faut pas hésiter à solliciter des responsables lors de cette réunion pour connaître précisément le rôle donné à son équipe
- Il y a peu de temps entre la réunion d’informations de l’OTAN et le rendu du premier jalon côté école
- Le Jalon 4 marque la fin du développement côté école, cependant il est toujours possible de continuer quelques semaines côté OTAN, même si c’est peu recommandé car durant cette période beaucoup de travail est demandé aux étudiants côté école
- Un travail incomplet ou qui ne répond pas entièrement au cahier des charges de l’OTAN sera refusé lors de la phase de validation et ne sera pas utilisé durant l’exercice !
Voyages à Tallinn #
Comme vous vous en doutez, il est possible d’assister aux réunions de l’OTAN en visioconférence, mais aussi en présentiel.
L’école ne peut pas envoyer tous les membres du groupe en même temps, dans notre cas un seul membre pouvait partir par réunion. Il y a donc généralement 2 voyages de prévus :
- Le premier pour la réunion d’informations
- Le deuxième pour l’exercice si le projet est retenu
Le premier voyage s’effectue pendant la période école, vous devrez donc vous assurer de ne manquer aucun contrôle ou de pouvoir les rattraper.
L’exercice a lieu pendant la période entreprise, vous devrez donc poser des jours de congés ou vous arranger avec votre employeur.
L’école vous remboursera les trajets mais ne comptez pas sur elle pour vous aider avec la réservation des avions / trains / hôtels, vous devrez trouver tout seul et bien garder les factures.
Début du projet #
Au début du projet nous n’avions aucune information. C’est la première chose qui nous a surpris, ni nous ni nos professeurs n’avions reçu une quelconque indication. Globalement avant la réunion d’informations vous ne savez pas du tout vers où vous dirigez.
Heureusement peu de temps s’écoula avant la première réunion d’informations. Ce fût Ben qui s’envola et nous représenta là-bas ✈️
À son retour, nous apprenions que nous faisions désormais partie de la Green Team (équipe de développement). La mission qui nous a été confiée est de développer un WebSSO
Un WebSSO est une application web permettant aux utilisateurs de s’authentifier une seule fois pour accéder à plusieurs services en ligne. Une fois que l’utilisateur est authentifié, il reçoit un jeton d’authentification (token) qui est utilisé pour accéder aux autres services intégrés dans le système SSO.
Notre WebSSO doit répondre aux exigences suivantes :
- Être configurable et déployable via un playbook Ansible
- Pouvoir s’interconnecter avec un environnement Azure AD via LDAPS
- Supporter le protocole OpenID Connect ou SAML pour faire office d’Identity Provider
- Disposer de plusieurs profils de tests Selenium pour vérifier le bon fonctionnement du WebSSO
- Si le temps nous le permet : rajouter une configuration “vulnérable” dans le playbook ce qui permettrait de déployer à n’importe quel moment la version “sécurisée” ou la version “vulnérable” pour l’exercice
Evidemment il faut rajouter à cela le déploiement du WebSSO dans l’infrastructure mise en place par Locked Shields et l’interconnexion entre les différentes équipes, sans compter les présentations d’avancement récurrentes et tous les autres cours/projets côté école.
Voici comment nous nous sommes répartis le travail :
Ben | BenJ | Tanguy | Moi |
---|---|---|---|
Responsable du côté Tallinn et CCDCOE | Test d’un SSO | Test d’un SSO | Test d’un SSO |
S’occupe du déploiement dans l’infrastructure de l’OTAN | Aide côté playbook et Identity Provider | S’occupe de la partie Identity Provider | S’occupe de la partie playbook Ansible |
S’occupe de la communication | S’occupe des tests Selenium | / | S’occupe de l’interconnexion LDAPS |
Choix de la solution #
La première chose que nous avons fait a été de choisir un SSO, pour cela nous avons testé 3 solutions :
Keycloak | Authelia | LemonLDAP | SSO codé nous-même |
---|---|---|---|
Solution retenue l’année dernière mais n’était pas fonctionnelle | Ne dispose pas de playbook Ansible | Dispose d’un playbook Ansible | Non retenu par manque de temps |
Dispose d’un playbook Ansible mais test non réussi | Test non réussi | Test réussi | / |
Le test consistait à déployer le SSO (sans playbook) et de vérifier l’interconnexion avec un Windows Server 2022 via LDAP. Nous disposions de peu de temps pour réaliser ce test et n’avons réussi qu’avec LemonLDAP, cette solution présentait également un playbook Ansible que nous pouvions prendre comme base c’est pourquoi nous l’avons retenue.
De plus cette solution open-source est française !
Premières difficultés #
Aucun membre de l’équipe n’avait implémenté un WebSSO avant cela et nos connaissances sur Ansible étaient très limitées, nous avons dû apprendre !
Quelques ressources pour en apprendre plus sur les playbooks Ansible :
- Spacelift.io (🇬🇧)
- DigitalOcean (🇬🇧)
- Blog Stéphane Robert (🇫🇷)
- Grafikart (🇫🇷)
Heureusement la documentation de LemonLDAP est assez conséquente. Il est simple de se perdre dans toutes ces pages, alors voici la liste de celles qui nous ont le plus servi :
- Présentation de l’outil et de ses composants (ça reste indispensable)
- LDAP module et MiniHowTo (pour l’interconnexion avec l’AD)
- Identity Provider (en particulier les pages sur SAML / OpenID)
- Des exemples de configuration en CLI
- Liste des variables
Développement du playbook #
Je vais survoler assez rapidement la partie technique et ne parler que du playbook Ansible ainsi que de l’interconnexion en LDAPS, car c’est la partie sur laquelle j’ai travaillée.
Le playbook initial #
LemonLDAP est composé de 3 éléments :
Handler
: Vérifie si l’utilisateur est autorisé à utiliser le SSO, c’est lui qui donne accès ou non au Portal. C’est aussi lui qui est chargé de vérifier les données envoyées par l’utilisateur et de protéger les applications (sanitizer anti XSS, anti injection SQL, …)Portal
: Utilisé pour authentifier les utilisateurs, c’est lui qui permet d’accéder à plusieurs applications depuis un point d’entrée uniqueManager
: Utilisé pour gérer la configuration de LemonLDAP, il est dédié aux administrateurs
Le playbook de base fourni avec LemonLDAP est assez simple :
- name: Install LemonLDAP
hosts: localhost
become: yes
roles:
- role: ansible-lemonldap
lemonldap_domain: mysuper.domain
lemonldap_webserver: "nginx"
hosts
: indique l’IP ou le FQDN des machines sur lesquelles on veut installer LemonLDAPbecome
: indique à Ansible d’utiliser ou non les droits administrateurslemonldap_domain
: indique le nom de domaine qui sera utilisé par l’annuaire LDAPlemonldap_webserver
: indique le serveur web que l’on veut utiliser → il est possible d’utiliser nginx ou apache
Ce playbook permet d’installer l’outil LemonLDAP, un serveur web et de les paramétrer pour un nom de domaine en particulier. En revanche, il manque encore l’interconnexion avec l’annuaire LDAP, c’est ce que nous allons faire.
L’interconnexion LDAP #
Il est nécessaire de préciser au manager certains paramètres, notamment le protocole à utiliser et le compte de service qui va permettre d’authentifier les utilisateurs.
Le problème c’est que ces paramètres doivent être renseignés sur une page d’administration web qui gère le manager, or nous voulons contrôler le déploiement et la configuration de LemonLDAP directement depuis le playbook Ansible.
Pour contourner ce soucis, notre playbook va directement configurer le manager depuis la CLI de LemonLDAP et renseigner ces paramètres avec des variables Ansible.
Voici à quoi ressemble notre playbook désormais :
- name: Install LemonLDAP
hosts: localhost
become: yes
roles:
- role: ansible-lemonldap
lemonldap_domain: mysuper.domain
lemonldap_webserver: "apache"
vars:
- ldap_server_ip: "ldap://192.168.1.2"
- ldap_port: 389
- ldap_verification: "none"
- ldap_timeout: 120
- ldap_base: "dc=mysuper,dc=domain"
- ldap_account: "cn=websso,cn=users,dc=mysuper,dc=domain"
- ldap_password: "SuperP@ssw0rd!"
Une fois le serveur relié au domaine, il suffit de renseigner les bonnes informations dans le playbook et n’importe quel utilisateur de l’AD peut maintenant s’authentifier sur LemonLDAP !
Il est maintenant temps de passer en LDAPS, pour cela il suffit d’installer un certificat TLS sur l’AD. Si celui est autosigné alors le paramètre ldap_verification
du playbook doit être à false (car il ne sera pas en mesure de vérifier l’autorité de certification).
En changeant le paramètre ldap_port
à 636 et ldap_ip
à ldaps://[ip], tout est prêt pour la connexion LDAPS.
Nous avons maintenant un playbook Ansible opérationnel pour déployer automatiquement LemonLDAP sur un serveur Linux et réaliser l’interconnexion LDAPS avec l’AD.
(Cela paraît simple mais ça nous a pris plusieurs mois avant d’arriver à ce résultat !)
Améliorations #
En soit, j’aurai pu m’arrêter à ce stade, mais je trouvais dommage que la page d’accueil ne soit pas aux couleurs de Locked Shields.
C’est pourquoi j’ai rajouté la possibilité de changer le fond d’écran, le logo et le favicon de l’application via des variables du playbook. Voici un exemple :
Enfin vous avez dû remarquer que le mot de passe du compte de service est renseigné en clair dans le playbook, comme il n’est pas possible de passer par un gMSA (compte de service géré par l’AD), nous avons dû trouver une solution pour effacer toutes les traces des identifiants de ce compte.
La solution choisie fût de ne générer aucun logs et de supprimer tous les fichiers du playbook Ansible une fois les autres tâches effectuées. Cette action est contrôlée par la variable delete_files
.
Voici un exemple de playbook avec toutes les variables intégrées :
- name: Install LemonLDAP
hosts: localhost
become: yes
no_log: True
roles:
- role: ansible-lemonldap
lemonldap_domain: mysuper.domain
lemonldap_webserver: "apache"
vars:
- ldap_server_ip: "ldaps://192.168.1.2"
- ldap_port: 636
- ldap_verification: "none"
- ldap_timeout: 120
- ldap_base: "dc=mysuper,dc=domain"
- ldap_account: "cn=websso,cn=users,dc=mysuper,dc=domain"
- ldap_password: "SuperP@ssw0rd!"
- main_logo: "logo.png"
- favicon: "favicon.ico"
- background: "background.png"
- activate_SAML: "yes"
- delete_files: "yes"
Architectures #
Nous pouvons représenter ce playbook sous les architectures logiques suivantes :
- L’utilisateur tente d’accéder à une application web mais il ne possède pas de cookie de session
- Le serveur web de l’application le redirige vers le serveur LemonLDAP (cela peut-être le même serveur), le handler vérifie que l’utilisateur peut utiliser le SSO, si c’est le cas l’utilisateur est redirigé vers le portail
- L’utilisateur s’authentifie sur le portail, le compte de service requête le serveur LDAP
- L’annuaire LDAP vérifie les identifiants de l’utilisateur et renvoi la réponse au portail
- Si l’authentification échoue, l’utilisateur doit rééssayer, si elle réussit le portail fourni un cookie de session à l’utilisateur
- L’utilisateur peut accéder à l’application avec ce cookie de session
Dépôts GitHub #
Evidemment ce playbook seul ne permet que l’authentification des utilisateurs sur le WebSSO, pour leur donner accès à des applications tierces il faut paramétrer ce serveur en tant qu’Identity Provider. C’est le rôle du playbook réalisé par Tanguy. Vous pouvez retrouver nos playbooks sur les dépôts GitHub suivants.
Validation du projet #
Ceci marque la fin du développement du projet, à ce stade côté école nous devions préparer la présentation finale. Celle-ci est particulière car :
- 1 seule diapositive est autorisée
- 1 minute par étudiant est accordée
Nous avions donc 4 minutes, pour présenter ce projet, c’est un exercice très intéressant qui nous force à vulgariser énormément et à remonter uniquement les points les plus importants.
Côté OTAN, nous avons rendu le code source et la documentation, nous n’avions plus qu’à attendre la décision du CCDCOE. C’est une attente assez longue et stressante lorsque l’on connaît le temps passé pour réaliser ce travail qui ne sera potentiellement pas du tout utilisé lors de l’exercice.
Après quelques semaines, nous apprenions que notre projet a été retenu et que notre WebSSO sera bel et bien utilisé !
Très heureux de la nouvelle, il fallait maintenant décider lequel d’entre nous se rendrait sur place pour l’exercice, nous avons décidé que Ben prendrait à nouveau ce rôle ✈️
L’exercice se déroula sans problèmes et voici le classement final :
- 🥇 Lettonie avec une équipe composée d’entités de l’OTAN
- 🥈 Finlande-Pologne
- 🥉 Estonie-France
Conclusion #
Participer à l’organisation de Locked Shields a été une belle expérience !
J’ai pu approfondir mes connaissances sur de nombreux domaines, notamment Ansible, l’Active Directory et les Identity Provider.
Cependant, au-delà des aspects techniques, ce projet m’a surtout enseigné l’importance de l’organisation et de la collaboration. Travailler avec des équipes internationales a mis en lumière l’importance de la communication et de la coordination pour atteindre des objectifs communs. Ces compétences sont essentielles pour réussir dans des projets de grande envergure comme celui-ci et constituent la leçon la plus précieuse de cette expérience.
Je souhaite sincèrement que cette collaboration entre l’ENSIBS, l’Université de Tallinn et le CCDCOE perdure, offrant à d’autres étudiants cette magnifique opportunité.
J’espère également que vous avez apprécié ce post et qu’il aura pu répondre à toutes vos questions, en tout cas j’ai pris beaucoup de plaisir à l’écrire !