Un plan de crise qui n’a jamais été joué est une hypothèse. Il dit qui prévient qui, qui décide, quoi dire à la presse : mais personne ne sait encore si l’annuaire est à jour, si la direction et l’équipe sécurité se comprennent, ni ce qu’on fait quand tous les outils de messagerie sont tombés. Un exercice de crise sert à le découvrir un après-midi choisi, plutôt qu’un matin où des écrans affichent une demande de rançon.

Cet article suit la méthode du guide « Organiser un exercice de gestion de crise cyber », publié par l’ANSSI avec le Club de la continuité d’activité (CCA) (ANSSI). Nous avons lu sa version PDF de 128 pages : les chapitres de méthode, les fiches sur les objectifs, les formats, les rôles, le chronogramme, les écueils, les biais et le retour d’expérience. Nous reprenons ses chiffres tels qu’ils y figurent. Quand nous ajoutons un avis, une proposition ou un exemple de notre cru, c’est dit. L’article se termine par un outil que nous avons écrit et testé : il contrôle qu’un scénario d’exercice est cohérent, produit la fiche d’animation et mesure les délais de décision. Deux sections expliquent la différence entre la cellule de crise décisionnelle (CCD) et la cellule opérationnelle (CCO), laquelle un exercice entraîne, comment elles communiquent et comment tenir la main courante.
Ce qu’est un exercice de crise, et ce qu’il n’est pas
Le guide définit un exercice de gestion de crise comme « un enchaînement d’événements fictifs proposant une mise en situation de crise réaliste mais non réelle », sur une durée limitée, qui repose sur l’organisation de gestion de crise en place au moment où il est joué. Deux règles fondatrices : un exercice ne doit jamais avoir d’impact réel (si le scénario parle de machines à l’arrêt, elles ne s’arrêtent pas : un employé téléphone pour dire qu’elles le sont) et il ne vise ni à surprendre ni à piéger les participants, mais à les entraîner dans un cadre aux objectifs annoncés.
Le guide s’adresse au niveau décisionnel : la cellule de crise, c’est-à-dire la direction et les métiers concernés, qui prennent des décisions. Il précise qu’il ne vise pas les exercices purement techniques qui simulent un système d’information avec des machines virtuelles (un « cyber range ») : la cellule opérationnelle y est simulée, nous y revenons plus bas. C’est la première source de confusion, car plusieurs choses portent le nom de « test » ou d’« exercice » en sécurité :
| Ce que c’est | Ce que ça éprouve | Qui joue |
|---|---|---|
| Exercice de crise (ce guide) | Décisions, coordination, communication, obligations : le dispositif de gestion de crise | Direction, métiers, RSSI, communication, juridique |
| Test de restauration | Que les sauvegardes se restaurent vraiment, en combien de temps (voir notre article sur les sauvegardes) | Équipe technique |
| Scan de vulnérabilités, test d’intrusion | Les failles du système d’information, ou la possibilité d’y entrer | Équipe sécurité, prestataire |
| Exercice technique (cyber range) | Les compétences d’investigation et de réponse sur des systèmes simulés | Analystes, administrateurs |
| Exercice d’évacuation, de repli, de continuité | Un autre scénario de crise (incendie, site inaccessible) | Tout le personnel |
Ces approches ne se remplacent pas. Un exercice de crise peut révéler qu’on ne sait pas si les sauvegardes sont saines, mais il ne dira pas si elles le sont : c’est le test de restauration qui répond.
Pourquoi la crise cyber se prépare à part
Le guide commence par ce qui distingue une crise d’origine cyber d’une autre crise. Il la place parmi les événements rares et à fort impact, loin des anomalies courantes et des incidents mineurs. Ses caractéristiques, telles que listées par l’ANSSI :
- Fulgurance et ubiquité des impacts : l’organisation peut être touchée à plusieurs endroits à la fois.
- Incertitude durable : les impacts sont difficiles à estimer et l’objectif de l’attaquant pas toujours identifiable.
- Évolutivité : l’attaquant peut réagir aux mesures prises, par exemple en effaçant ses traces par des actions destructrices.
- Technicité : les experts techniques sont au cœur de la gestion de crise ; l’enjeu est qu’ils et les acteurs habituels de la crise se comprennent.
- Propagation potentiellement mondiale : le guide cite WannaCry, plus de 250 000 postes touchés dans 150 pays en une seule nuit.
- Élasticité du temps : l’attaquant peut recommencer avec le même mode opératoire ; WannaCry a contaminé des victimes pendant plus d’un an.
- Sortie de crise longue : plusieurs mois pour la réponse technique, l’investigation et le rétablissement ; d’où l’importance du plan de continuité d’activité.
- Attribution difficile : il est aisé de dissimuler sa véritable identité.
Les impacts sont aussi multiples : juridiques, réglementaires, métiers, RH, financiers, réputationnels, techniques, avec une possible pression médiatique. Gérer cela suppose de coordonner des équipes aux logiques opposées : isoler un système pour arrêter l’attaque (logique de sécurité) contre le garder en marche pour livrer (logique de continuité). Ce choix se prend vite, sans savoir exactement ce qui est touché. C’est précisément ce qu’on peut s’entraîner à faire.
Les deux cellules : décisionnelle (CCD) et opérationnelle (CCO)
Une crise cyber mobilise deux cellules distinctes, et c’est le point où un exercice se joue ou se rate. Le guide les nomme « cellule de crise décisionnelle » et « cellule de crise opérationnelle » sans les abréger ; nous utilisons les sigles courants en France, CCD et CCO.
| CCD : cellule de crise décisionnelle | CCO : cellule de crise opérationnelle | |
|---|---|---|
| Mission (guide) | Assure le suivi et le pilotage de la crise et prend les décisions | Analyse la situation technique et propose des actions pour rétablir l’activité |
| Composition | Membres de la direction et des métiers impliqués ; la DSI ou le RSSI y est intégré pour donner aux décideurs « une vision éclairée du déroulement de l’attaque » | Équipes sécurité et informatique, éventuellement des prestataires de réponse à incident |
| Questions typiques | Isole-t-on ou continue-t-on à produire ? Que dit-on aux clients et à la presse ? Déclare-t-on à la CNIL ? Paie-t-on ou non ? Quels impacts financiers, métiers, réputationnels ? | Quel est le chemin d’attaque ? Qu’est-ce qui est touché ? Les sauvegardes sont-elles saines ? Combien de temps pour rétablir ? |
| Travail technique associé | Aucun : la mise en œuvre technique se décide dans les équipes opérationnelles | Investigation, remédiation (éjecter l’attaquant, restaurer), stabilisation (sécurité à plus long terme) |
| Ce que le guide entraîne | Oui : c’est l’objet des exercices du guide (niveau décisionnel) | Non : elle est simulée par la cellule d’animation et ne fait pas l’objet de la méthode |
Les deux cellules travaillent en parallèle et échangent : la CCO remonte l’état technique (ce qui est touché, ce qui est certain, les délais) et la CCD redescend des décisions et des priorités. Le RSSI est la charnière : il siège en CCD et relaie la CCO. Il doit traduire le technique en langage de décideur ; le guide en fait une capacité attendue des joueurs (« vulgariser »).
Encart : et le RSO, responsable de la sécurité opérationnelle ?
Le titre de RSO n’apparaît pas dans les guides de l’ANSSI : ce qui suit est une correspondance d’usage, pas une définition officielle. Adaptez-la à vos intitulés de poste.
Le guide ANSSI/CDSE place à la tête du volet opérationnel un « responsable cyber/IT » chargé de la « définition, orientation et coordination des opérations IT/cyber ». Dans l’usage courant, c’est le RSO : là où le RSSI s’occupe de la gouvernance (politique, risques, conformité), le RSO s’occupe de la sécurité au quotidien (détection, réponse à incident, durcissement).
En crise, il dirige la CCO. Il qualifie l’alerte (incident informatique ou attaque ?), propose les mesures d’endiguement, conduit l’investigation avec le prestataire, pilote la remédiation et le durcissement, tient l’image technique (ce qui est confirmé, ce qui est supposé) et la fait remonter à la CCD sous forme de points de situation. Les coupures qui touchent l’activité sont proposées, jamais décidées seul.
Où est-il ? Dans la CCO, devant les journaux. Le RSSI, lui, siège en CCD et relaie. Dans un exercice du guide, le RSO ne joue pas : la CCO est simulée par l’animation.
Dans une petite organisation, une seule personne cumule souvent les deux postes : nommez un adjoint technique avant la crise, car on ne peut pas être à la fois dans la salle de décision et dans les journaux (notre avis).
Ce que cela change pour l’exercice
- Les joueurs sont la CCD. Dans un exercice du guide, les décideurs jouent ; les techniciens ne jouent pas, et leurs réponses (« la sauvegarde est atteinte », « le prestataire estime cinq jours ») viennent des animateurs.
- La qualité de la CCO simulée dépend donc des animateurs. Le guide demande des animateurs « aptes à répondre aux questions et familiers des problématiques » des joueurs ; un animateur qui ne connaît pas la technique rend l’exercice irréaliste.
- Dans notre scénario d’exemple, quatre messages (I03, I04, I06 et I14) viennent de l’équipe technique simulée : c’est la CCO qui parle à la CCD, par l’intermédiaire du RSSI.
- Plusieurs cellules peuvent jouer : le guide prévoit des simulations où une CCD et la cellule de crise d’un second site jouent ensemble (c’est le cas de son exercice RANSOM20). L’animation simule alors les interactions sans interférer avec les échanges entre joueurs.
Le point de friction le plus fréquent
Quatre des cinq écueils du guide (plus bas) décrivent des dérapages dans la relation entre les deux cellules : la CCD qui se met à débattre de détails techniques et devient une CCO, la CCD qui sur-sollicite la CCO pour avoir une vision instantanée, l’incompréhension entre ce que la CCD décide et ce que la CCO peut faire, le manque de langage commun. La règle du guide est simple : la CCD débat des solutions possibles et de leurs impacts ; la manière technique de les mettre en œuvre se décide dans les équipes opérationnelles.
Et l’entraînement de la CCO ?
Il demande un autre type d’exercice : technique, sur des systèmes simulés (un « cyber range »), que le guide exclut de son périmètre. Une CCO peut aussi s’entraîner par des tests précis : restauration des sauvegardes (voir notre article sur les sauvegardes), analyse de journaux, isolement d’une machine. Une progression logique, que nous proposons (le guide recommande une montée en compétence progressive sans la détailler ainsi) : exercice sur table avec la seule CCD, puis simulation avec CCD et CCO jouant ensemble.
Dans une petite organisation, les deux cellules peuvent être les mêmes personnes : le dirigeant décide, l’informaticien ou le prestataire investigue. Notre conseil : même si ce sont les mêmes têtes, séparez les deux rôles pendant l’exercice (qui décide, qui analyse) et notez qui parle à qui. C’est précisément ce qui se brouille quand la crise est réelle.
Comment les deux cellules se parlent
Dans la réalité, une crise cyber se gagne ou se perd dans la liaison entre les deux cellules : une décision prise sans savoir ce qui est touché, ou une analyse technique qui n’arrive jamais à ceux qui doivent trancher. Pour cette partie, nous nous appuyons sur un second guide, « Crise d’origine cyber : les clés d’une gestion opérationnelle et stratégique », publié par l’ANSSI avec le CDSE (le club des directeurs de sécurité et de sûreté des entreprises), en version 1.0 de décembre 2021, avec ses 18 fiches (PDF). Il décrit la crise telle qu’elle se vit, pas telle qu’elle se simule. Nous avons lu les fiches sur l’organisation, la mobilisation, le pilotage, la communication, la sortie de crise et la boîte à outils.

Une organisation, un pilote
Selon le guide, la cellule stratégique (ou décisionnelle) « décide et oriente » ; la cellule opérationnelle cyber et IT est en charge de l’investigation, du durcissement et de la reconstruction ; d’autres cellules peuvent s’ajouter selon les impacts : métiers, communication, ressources humaines, logistique, juridique. Le schéma du guide les montre en train de se coordonner et de s’informer mutuellement. Le guide donne la raison de ce pilotage : chaque cellule planifie des actions, et mal coordonnées, elles peuvent être contre-productives (arrêt de systèmes essentiels, stratégie de communication inadaptée). La cellule stratégique endosse donc le rôle de pilote.
Ce qui remonte, ce qui descend
| Sens | Ce qui circule (d’après le guide) | Ce que ça exige |
|---|---|---|
| CCO → CCD (remonte) | L’état de la situation et l’étendue des impacts ; le niveau de confiance dans l’utilisation des données et des systèmes ; les mesures proposées pour endiguer ; les besoins en ressources et en renforts | Distinguer ce qui est confirmé de ce qui est supposé ; dire clairement ce qu’on ignore |
| CCD → CCO (descend) | Les orientations et les décisions ; les priorités (par exemple les services à réintégrer en premier) ; les enjeux des parties prenantes, formalisés et partagés aux cellules opérationnelles | Décider sans attendre la certitude, puis le dire de façon exploitable |
| Validation obligatoire | Les mesures d’endiguement qui ont des conséquences sur la continuité (isolement, déconnexion d’applicatifs ou de serveurs, blocage des accès Internet) sont validées par la cellule stratégique | Un circuit de décision rapide pour les coupures |
| Vers l’extérieur | Un canal sortant unique pour répondre aux sollicitations techniques des clients, partenaires et autorités ; un point de contact unique pour la presse ; des éléments de langage validés par la communication et le juridique | Un seul porte-voix par sujet, sinon les versions divergent |
Le guide insiste sur la mesure : il faut « un équilibre en termes de fréquence et de formalisation dans la remontée et la descente des orientations et décisions, afin de laisser le temps aux équipes opérationnelles de traiter les actions demandées ». Une CCD qui réclame un point toutes les cinq minutes empêche la CCO de travailler ; une CCD qui ne demande rien décide à l’aveugle. C’est exactement l’écueil de « sur-sollicitation des équipes techniques » que décrit le guide d’exercice.
Qui donne l’information à la CCD ?
La CCD ne doit pas recevoir l’information de dix personnes qui l’appellent en même temps. Le guide prévoit pour cela une fonction de management de l’information au sein de la cellule stratégique (« main courante, partage des informations montantes et descendantes »), et fait des fonctions cyber et IT les pilotes de la partie opérationnelle, qui « s’assurent d’échanger avec la cellule stratégique ». Concrètement, l’information arrive par des canaux identifiés, un par sujet :
| D’où vient l’information | Ce qu’elle apporte à la CCD | Qui la donne | Base |
|---|---|---|---|
| La cellule opérationnelle (technique) | Ce qui est touché, ce qui est certain, les mesures proposées, les délais, les besoins en renfort | Le RSO (responsable cyber/IT) produit le point de situation ; le RSSI, en CCD, le présente et l’explicite aux non-spécialistes | Guide ANSSI/CDSE ; guide d’exercice (fiche d’observation : « explicitées par le RSSI ») |
| Les métiers | Impact sur la production, les clients, les contrats ; ce qui peut tourner en mode dégradé | Les représentants des métiers, présents en CCD ou relayés par une cellule métier | Guide ANSSI/CDSE (volet stratégique, cellules métiers) |
| Le juridique et la protection des données | Les obligations : déclaration à la CNIL, plainte, clauses de contrats ; validation des éléments de langage | Le juriste ou le délégué à la protection des données | Guide ANSSI/CDSE ; guide d’exercice (déclaration CNIL à simuler) |
| La communication | Ce que disent la presse et les réseaux sociaux, qui demande quoi ; les messages à valider | La cellule ou la personne de veille médiatique, point de contact unique de la presse | Guide ANSSI/CDSE (veille médiatique, point de contact unique) |
| L’assureur, le prestataire, les autorités | Les exigences, les délais, les renforts disponibles | Une personne désignée qui centralise ces contacts ; réponses par un canal sortant unique | Guide ANSSI/CDSE (demandes de renfort centralisées, suivi centralisé des sollicitations) |
Notre proposition, pour que cela tienne en pratique (ce n’est pas dans les guides) :
- Un gestionnaire de l’information en CCD : il reçoit tous les points de situation, les consigne dans la main courante, et fait redescendre les décisions. Ce n’est ni le directeur de crise ni le RSSI.
- Un seul visage pour la technique : le RSO (ou son adjoint) vient présenter le point de situation à heure fixe, sur place ou en visioconférence, puis retourne en CCO. Le RSSI traduit en impacts.
- Pas de couloir parallèle : le technicien qui appelle directement le directeur général court-circuite le circuit et fait diverger les versions. S’il a une information urgente, elle passe par le RSO.
- Toute information porte son niveau de certitude (confirmé, probable, à vérifier) et sa source, comme dans le format de point de situation proposé plus bas.
- Si deux sources se contredisent, la CCD demande lequel des deux niveaux de confiance est le plus élevé avant de décider, et le consigne.
Dès le déclenchement
Le guide recommande, à la mobilisation de la cellule : établir un contact permanent avec les équipes opérationnelles, faire un premier état des lieux, mettre en place un premier « rythme de bataille » avec des points de situation réguliers, et ouvrir une main courante pour informer les équipes des actions en cours. Le guide ne fixe pas de fréquence. Notre suggestion, à adapter : un point de situation toutes les 30 à 60 minutes au début, espacé ensuite, avec une heure du prochain point annoncée à chaque fois.
Quand la messagerie est tombée
Le guide part d’un constat : « l’indisponibilité partielle ou totale des services et des outils numériques rend difficile toute communication entre les différentes entités de l’organisation ». Les cellules doivent donc disposer d’outils de secours « pour assurer, au minimum, le fonctionnement du dispositif de crise ». Ce qu’il recommande :
- Des procédures de crise stockées hors ligne, et un annuaire de crise hors ligne (contacts hiérarchiques, géographiques, infogérants, fournisseurs, autorités).
- Des outils numériques dédiés à la cellule, accessibles hors ligne et maintenus en conditions opérationnelles ; un ordinateur hors réseau figure dans sa boîte à outils.
- Des moyens de communication alternatifs, internes et externes, identifiés et testés : adresses de messagerie génériques, tchat, visioconférence, téléphones fixes ou mobiles.
Le guide d’exercice va dans le même sens : utiliser pendant l’exercice les moyens que les joueurs utiliseraient en crise réelle, en tenant compte des conséquences de l’attaque (par exemple une messagerie indisponible), et compléter un appel qui transmet un message important par un récapitulatif sur un autre canal. C’est une bonne habitude à garder en vraie crise (notre lecture). Le guide d’exercice prévoit aussi, pour les animateurs, un message facultatif : si le directeur de crise n’organise pas de point de situation, une autorité demande ce qui se passe.
Notre proposition de format de message
Pour éviter les échanges flous, un point de situation de la CCO vers la CCD tient en cinq rubriques. Le format est de notre cru ; il reprend les notions du guide (confiance, impacts, mesures qui exigent une décision) :
POINT DE SITUATION n° 3 — CCO vers CCD — 10 h 45 — prochain point à 11 h 30
Faits confirmés : 2 serveurs de fichiers chiffrés ; messagerie hors service
Hypothèses (confiance) : exfiltration de données (probable) ; copie de nuit atteinte (à vérifier)
Impacts connus / inconnus : atelier arrêté ; périmètre des postes inconnu
Mesures prises : 2 serveurs isolés
Décision CCD requise : couper l'accès VPN (arrête le télétravail de 40 personnes) : oui / non avant 11 h 00
Ce que les observateurs regardent
La fiche d’observation du guide d’exercice liste les questions sur cette liaison : comment circulent les messages entre les membres de la cellule, et entre les différentes cellules ? Les messages sont-ils compris par les destinataires ? Quelle est la fréquence des points de situation, comment sont-ils organisés, sont-ils précis, concis, compréhensibles par tous ? Les informations reçues et les décisions prises redescendent-elles régulièrement aux services et aux autres cellules ? Les informations issues de la cellule opérationnelle (simulée par l’animation) sont-elles bien transmises à la cellule décisionnelle, explicitées par le RSSI et comprises par des joueurs non spécialistes ?
La main courante : la mémoire de la crise
Une crise cyber dure des jours ou des semaines, les équipes se relaient, les informations changent, et chacun croit se rappeler ce qui a été décidé. La main courante est le journal chronologique et partagé qui sert de mémoire commune : ce qui s’est passé, ce qui a été décidé, qui doit faire quoi. C’est un outil de pilotage avant d’être une trace.

Ce que dit le guide
- Le management de l’information, c’est-à-dire « main courante, partage des informations montantes et descendantes », fait partie des fonctions de la cellule stratégique.
- À la mobilisation, « une main courante est ouverte pour informer les équipes des actions en cours », côté stratégique comme côté opérationnel.
- Elle est « utilisée pour le suivi et la centralisation des actions et des frais liés à la gestion de la crise » : elle sert donc aussi pour l’assurance cyber, dont l’activation se décide en cellule stratégique.
- Les décisions prises « font l’objet d’un suivi » et permettent de valider les critères de sortie de crise.
- Un outil de main courante et un outil de suivi des actions figurent dans la boîte à outils à prévoir avant tout incident.
Ce qu’on y écrit : notre proposition de colonnes
Le guide ne dicte pas de format. Voici celui que nous recommandons, car il force à distinguer ce qu’on sait de ce qu’on suppose :
| Colonne | Contenu | Pourquoi |
|---|---|---|
| Heure | Date et heure de l’événement, avec le fuseau | Reconstituer la chronologie et mesurer les délais |
| Source | Qui a fourni l’information | Savoir à qui demander des précisions |
| Type | Fait, hypothèse, décision ou action | Ne pas confondre une supposition avec un fait établi |
| Contenu | Une phrase claire | Lisible par quelqu’un qui arrive en relève |
| Certitude | Confirmé, probable, à vérifier | Reprend la notion de « niveau de confiance » du guide |
| Responsable | Un nom, pas une équipe | Une action sans responsable ne se fait pas |
| État | Ouvert, en cours, fait, échéance | Voir d’un coup d’œil ce qui reste ouvert |
Règles de tenue (nos recommandations, à adapter)
- Un scribe par cellule, qui n’est ni le décideur ni l’analyste principal : celui qui tranche ne peut pas écrire en même temps. Prévoir une relève.
- On n’efface jamais une ligne : on corrige par une nouvelle ligne qui renvoie à la précédente. C’est ce qui permet de reconstituer ce qui était su à tel moment.
- Séparer faits, hypothèses, décisions et actions ; une hypothèse ne devient fait que par une ligne qui le dit.
- Hors du système d’information touché : un tableur sur le serveur de fichiers chiffré est inaccessible au moment où on en a besoin. Un outil hors ligne, une copie imprimée ou un support autonome convient (le guide demande des outils dédiés accessibles hors ligne).
- Accessible à tous les membres de la cellule, et en lecture à l’autre cellule : c’est le support des points de situation.
- Pas de secrets dedans : ni mots de passe, ni clés ; la main courante circule, et sert à l’assureur et au retour d’expérience.
- Enregistrer les décisions avec leur motif, surtout celles qui sont difficiles (payer ou non, couper ou non) : c’est ce qui sera relu pendant le retour d’expérience.
Dans un exercice : trois main courantes
- Celle des joueurs : le guide d’exercice demande qu’au minimum une main courante soit tenue par l’un des joueurs en cellule de crise. Elle est utilisée pour le rapport de retour d’expérience, avec les mails échangés, les notes des observateurs et le compte rendu du retour d’expérience à chaud.
- Celle de l’animation : le secrétaire de la cellule d’animation suit le chronogramme ; le guide indique qu’une main courante peut y être utilisée pour garantir la cohérence de l’exercice, et que les observateurs peuvent y avoir accès (facultatif).
- L’observation de la tenue elle-même : la fiche d’observation demande si la main courante est régulièrement renseignée et accessible à tous, et, sinon, pourquoi. La façon dont la cellule tient sa mémoire est donc elle-même un résultat de l’exercice.
La commande courante de notre outil
Pour la main courante de l’animation, nous avons ajouté la commande courante à crise_exercice.py. À partir du scénario et du journal des animateurs, elle produit une ligne par événement : envoi d’un message, réponse d’un joueur avec son délai, ou échéance dépassée quand aucune réponse n’est venue dans le délai maximal. Le résultat est trié par heure, en tableau ou en CSV (--csv) pour un tableur.
$ python3 crise_exercice.py courante scenario-exemple.json journal-exemple-fictif.json
| T+0h20 | envoi | I01 | Chef d'atelier → Production | EXERCICE - Les postes de l'atelier affichent un message exigeant une rançon... |
| T+0h24 | réponse | I01 | Production | (décision non consignée) | 4 min | dans les temps |
| T+0h58 | réponse | I04 | RSSI | (décision non consignée) | 26 min | en retard |
| T+1h25 | échéance dépassée | I07 | COM | aucune réponse enregistrée : valider une réponse écrite et un porte-parole unique | - | sans réponse |
Deux précisions. Le journal peut contenir un champ decision (le texte de la décision prise) ; à défaut l’outil écrit « (décision non consignée) » plutôt que d’inventer la décision à partir de ce qui était attendu. Et cette commande ne produit que le journal de l’animation : la main courante des joueurs, elle, se tient à la main, comme dans une vraie crise, puisque c’est elle qu’on veut observer.
Les pièges classiques
- La remplir après coup : les heures deviennent approximatives et les décisions reconstruites.
- Tout y mettre, ou presque rien : trop détaillée, personne ne la relit ; trop pauvre, elle ne sert à rien.
- Un seul document pour deux cellules sans règle d’écriture : les lignes se mélangent ; mieux vaut une main courante par cellule et un point de synchronisation à chaque point de situation.
- La confier à celui qui décide : il décide ou il écrit, pas les deux.
- L’héberger sur le système attaqué : inaccessible le jour où elle sert.
Ce que ça apporte
D’après le guide, un exercice permet de sensibiliser, d’entraîner, et de tester le dispositif. Concrètement, il fait émerger :
- L’annuaire de crise à jour ou non : contacts internes et externes (prestataire de réponse à incident, assurance, autorité de tutelle). Le guide en fait un des éléments à valider.
- Les chaînes d’alerte et d’escalade : toutes les personnes utiles ont-elles été sollicitées, et au bon moment ?
- Les modes de secours : autre messagerie, autre réseau téléphonique, modes opératoires dégradés pour les activités critiques.
- La communication de crise : les éléments de langage sont-ils transmis aux bonnes personnes, en interne et en externe ?
- Les arbitrages entre plans d’endiguement, de contournement et de remédiation, qui ont chacun des conséquences sur l’activité.
- Le langage commun entre l’équipe sécurité et la direction (le guide cite le premier exercice comme l’occasion de les faire travailler ensemble).
- Une preuve de démarche : le guide note qu’un exercice peut servir à montrer à des organismes d’État, à des assureurs ou à des clients que des entraînements sont conduits, et que son rapport peut servir de pièce de contrôle.
Le cadre réglementaire
La directive européenne NIS 2 demande aux entités concernées des mesures de gestion des risques qui incluent, selon l’article 21, paragraphe 2, point c, « business continuity, such as backup management and disaster recovery, and crisis management », en clair : la continuité d’activité, la gestion des sauvegardes, la reprise après sinistre et la gestion des crises (directive (UE) 2022/2555). Le texte n’impose pas la forme d’un exercice ; il demande une gestion de crise, et un exercice est le moyen d’en montrer l’existence.
Pour le secteur financier, le règlement DORA impose un programme de tests de résilience opérationnelle numérique (article 24), avec des tests au moins annuels des systèmes qui soutiennent des fonctions critiques ou importantes, et, pour les entités concernées, un test d’intrusion fondé sur la menace (TLPT) au moins tous les trois ans (article 26) (règlement (UE) 2022/2554). Ce sont des tests techniques : ils ne remplacent pas un exercice de cellule de crise, qui est un autre objet.
Côté données personnelles, le guide demande que le scénario prévoie les déclarations légales : en cas d’indisponibilité ou d’exfiltration de données, il faut simuler la déclaration à la CNIL. Nous avons traduit cette consigne en règle de notre outil (plus bas).
Note de méthode : le site EUR-Lex refuse nos requêtes automatiques ; nous avons lu ces deux articles dans des copies du texte officiel et renvoyons ici vers l’adresse officielle. Vérifiez la formulation exacte sur EUR-Lex avant de la citer dans un document de conformité.
Ce que nous ne chiffrons pas
On lit souvent qu’un plan de réponse testé réduit le coût d’un incident, en citant le rapport « Cost of a Data Breach » d’IBM (IBM). Les trois sources secondaires que nous avons consultées donnent des économies différentes, de 295 000 dollars à 2,66 millions, selon l’édition et la manière de présenter le chiffre. Faute de pouvoir lire la ligne exacte dans le rapport lui-même, nous n’en retenons aucune. L’argument du coût existe sans doute, mais il ne tient pas à un chiffre que nous n’avons pas vérifié.
Les formats : sur table ou simulation
Le guide en propose deux, et recommande de commencer par le plus léger : pour un premier exercice de crise cyber, l’exercice sur table planifié. Les exercices impromptus sont réservés aux organisations déjà rodées, avec des astreintes, et déconseillés quand on veut convier des décideurs.
| Exercice sur table | Simulation | |
|---|---|---|
| Principe | Les participants autour d’une table ; un animateur expose la situation ; ils discutent des actions à mener | Une cellule de crise (les joueurs) et une cellule d’animation qui simule les événements et tous les interlocuteurs |
| Durée | 2 à 3 heures, briefing et débriefing compris (1 à 2 heures possible) | Une demi-journée à deux journées, briefing et débriefing compris ; idéal : une journée (environ 6 h) |
| Préparation | Environ six semaines | Deux à six mois |
| Intérêt | Familiariser des personnes qui ont peu de temps (direction), pistes pour construire le dispositif | Immersion, interactions entre cellules, points forts et axes d’amélioration de tout le dispositif |
| Limite citée | Ne permet pas de tester le dispositif de crise de l’organisation | Plus de participants = plus de coordination et de temps |
Hors du cadre de l’ANSSI, deux repères existent. Le guide NIST SP 800-84 (septembre 2006) décrit la conception, la conduite et l’évaluation d’exercices pour les plans informatiques, dont les exercices sur table (NIST). La CISA américaine publie plus de 100 paquets d’exercices sur table prêts à l’emploi, avec objectifs, scénarios et questions de discussion ; on y trouve rançongiciel, menace interne ou hameçonnage (CISA). Ils sont conçus pour un public américain : le droit, les interlocuteurs et les délais (CNIL, ANSSI) sont à remplacer.
Une durée à retenir : le guide estime qu’environ trois heures est la durée minimale recommandée pour un exercice de crise cyber, tout en admettant des exercices sur table plus courts (une à deux heures). Il note aussi qu’un exercice de niveau décisionnel dépasse rarement deux jours : au-delà, la mobilisation des participants devient difficile et le désengagement guette.
Qui doit participer
Le guide distingue six rôles, qu’il faut séparer nettement :
| Rôle | Ce qu’il fait | Points d’attention du guide |
|---|---|---|
| Directeur de l’exercice (DIREX) | Pilote la conception ; le jour J, peut devenir directeur d’animation (DIRANIM) | En pratique le responsable sécurité ou la personne qui gère habituellement les exercices ou la continuité |
| Planificateurs | Cadrent, écrivent le scénario et le chronogramme, animent, font le retour d’expérience | Au moins un expert sécurité, une personne de la continuité d’activité, un communicant (éventuellement) |
| Experts | Apportent le réalisme : experts métier (1 à 3) et technique/sécurité | Peuvent être joueurs s’ils ne connaissent pas tout le scénario |
| Animateurs | Envoient les messages (mails, appels, échanges en personne), répondent aux questions, s’adaptent | Au minimum un animateur principal, un secrétaire qui suit le chronogramme, et un à quatre animateurs pour les appels et les mails |
| Observateurs | Regardent sans intervenir, relèvent les points positifs et les axes d’amélioration, alertent en cas de blocage | Pas plus de deux par salle ; éviter les supérieurs directs des joueurs |
| Joueurs | Font face à la crise fictive, avec les outils et les procédures habituels | Ne connaissent pas le scénario ; ce sont les personnes qui seraient mobilisées si l’événement était réel |
Pour un exercice de niveau décisionnel, il faut des profils de haut niveau, un décideur cyber ou la personne chargée de la sécurité, et, plus généralement, tous ceux qui seraient mobilisés pour de vrai : direction, continuité, communication, juridique, ressources humaines, métiers touchés. Le jour J, ils doivent savoir évaluer les impacts, planifier avec des délais réalistes, anticiper les évolutions de la crise et vulgariser pour les non-techniciens.
Les règles de séparation
- Les concepteurs du scénario ne jouent pas : ils le connaissent, ils fausseraient les réactions.
- Pas de supérieur direct en observateur d’un joueur : l’exercice risque d’être perçu comme un contrôle ou une évaluation.
- Une personne réfractaire peut commencer par observer : cela dédramatise et montre qu’on peut se tromper.
Les autres acteurs, simulés
Les interlocuteurs extérieurs sont joués par la cellule d’animation : le guide cite l’autorité de tutelle, la préfecture, la plateforme Cybermalveillance.gouv.fr, les filiales, fournisseurs, prestataires, assureurs, ainsi que les journalistes, clients et salariés. Pour une petite organisation, notre suggestion (ce n’est pas dans le guide) est de cumuler : une même personne anime et prend les notes, une autre observe, et le dirigeant joue son propre rôle.
Comment ça se déroule
Le guide découpe un exercice en quatre étapes, chacune avec ses livrables.
Étape 1 : concevoir
- Cadrer : un groupe projet, des objectifs, un format, un thème, une durée, la logistique, un calendrier. Le livrable est un cahier des charges.
- Des objectifs, trois à quatre par exercice, déclinés par fonction. Le guide propose de demander aux joueurs d’y réfléchir eux-mêmes en amont. Exemples : s’assurer que toutes les personnes nécessaires sont sollicitées ; tester la communication de crise ; s’entraîner à gérer une crise en mode dégradé.
- Un thème tiré de l’analyse de risques, de la menace du secteur ou d’incidents passés : défiguration de site, déni de service, exfiltration de données, chiffrement ou destruction des données, destruction de services (par exemple l’annuaire Active Directory).
- Un nom peu explicite (le guide donne RANSOM20) pour faciliter les échanges sans alarmer les salariés non joueurs.
- Un calendrier avec une date connue plusieurs mois à l’avance, une date de repli, et des réunions de retour d’expérience fixées d’avance.
Étape 2 : préparer
On rédige le scénario (l’attaque qui marque le début, les impacts métiers qui évoluent, les détails techniques adaptés aux joueurs, le contexte médiatique, la résolution) puis le chronogramme : un tableau qui décrit, ligne par ligne, tout le déroulement du début (DEBEX) à la fin (FINEX), avec les messages à envoyer (stimuli), qui les envoie, à qui, et la réaction attendue. Le guide fournit un exemple complet, RANSOM20, et un modèle de chronogramme à télécharger (fiche 6, format tableur). Il faut aussi un dossier de mise en situation et des grilles pour les observateurs, ainsi que des briefings : un ou deux pour les joueurs (celui du jour J est indispensable) et deux pour les animateurs et observateurs.
Sur le rythme, le guide donne un exemple concret : au début d’une attaque, des messages « toutes les trois minutes » font ressentir l’ampleur ; pendant l’investigation, 10 à 15 minutes de silence font ressentir l’attente. Le rythme n’est donc pas constant, et le temps est accéléré par rapport à la réalité : une investigation prend en vrai des jours ou des semaines, ce qu’il faut rappeler aux joueurs avant et après.
Pour la pression médiatique, il faut des faux appels de journalistes, des faux articles, de faux messages sur les réseaux sociaux, tous marqués comme exercice (le guide suggère de commencer les appels par « exercice – exercice – exercice »). Les questions qui reviennent (qui, quoi, comment, quand) resteront largement sans réponse pendant l’exercice : c’est réaliste.
Étape 3 : dérouler
Les animateurs suivent le chronogramme, mais s’adaptent aux joueurs, car les réactions diffèrent souvent de celles prévues. Les conséquences sont concrétisées : affichages « machine indisponible », appels d’employés, documents. Le guide consacre deux fiches aux pièges (voir plus bas).
Étape 4 : tirer les enseignements
- Retour d’expérience à chaud, juste après la fin : environ une heure pour un exercice d’une demi-journée à une journée, tour de table où les joueurs parlent en premier, en insistant sur les points positifs, surtout pour un premier exercice. On y explique l’attaque dans son ensemble et ce qui différait de la réalité (investigation raccourcie, par exemple).
- Retour d’expérience à froid, deux semaines à un mois après : environ une heure, avec un questionnaire d’auto-évaluation et éventuellement des entretiens individuels.
- Rapport écrit : points forts, points à améliorer, éléments factuels, plan d’action avec une personne responsable par action, publié au plus tard deux mois après l’exercice.
Un exemple d’emploi du temps d’un exercice sur table de trois heures
L’emploi du temps ci-dessous est notre proposition, cohérente avec les durées du guide (2 à 3 heures, briefing et débriefing compris). Nous réduisons le retour d’expérience à chaud à 30 minutes, contre environ une heure pour un exercice plus long.
| Moment | Durée | Contenu |
|---|---|---|
| T+0h00 | 20 min | Briefing des joueurs : objectifs, règles (aucune action réelle, tout message commence par « EXERCICE »), temps accéléré, droit de se tromper |
| T+0h20 à 2h30 | 2 h 10 | Jeu : 14 messages dans le scénario d’exemple, dont 12 attendent une décision |
| T+2h30 | 30 min | Retour d’expérience à chaud : les joueurs d’abord, puis les observateurs ; écarts avec la réalité |
| Dans le mois | 1 h | Retour d’expérience à froid, puis rapport avec le plan d’action nominatif |

Ce qui se passe mal : écueils et biais
Le guide consacre deux fiches pratiques à ce qui dérape, à partir de l’observation de nombreux exercices. Les cinq écueils les plus fréquents :
| Écueil | Ce qui se passe | Ce que l’animation peut faire |
|---|---|---|
| La cellule décisionnelle devient opérationnelle | On débat de détails techniques en cellule de direction, au détriment du recul nécessaire | Demander un point de situation orienté métier ; solliciter la personne qui alimente le débat ; l’inviter à quitter la salle avec une raison |
| Incompréhension entre décisionnel et opérationnel | Les décisions prises ne tiennent pas compte des contraintes de mise en œuvre | Ajouter des messages qui expriment ces difficultés sous forme de questions |
| Décision contraire aux objectifs | Par exemple, fermer toute l’organisation alors qu’on veut tester un compromis avec la continuité | Refuser la mesure par une personne simulée ou une convention d’exercice |
| Sur-sollicitation des équipes techniques | La cellule veut une vision permanente et instantanée, au détriment de la gestion des impacts métiers | Interdire certains canaux ou passer par une personne « relais » ; rappeler que l’investigation prend du temps |
| Manque de vulgarisation | Confusion faute de langage commun | Provoquer des points de situation ad hoc entre le responsable sécurité et le directeur de crise |
Le guide décrit aussi des biais de comportement, par défaut ou par excès : le désencrage (« ce n’est pas la vraie vie »), la défausse, le surinvestissement et le besoin excessif de contrôle, le retard (« on a tout notre temps »), le retrait du décideur qui ne tranche pas, l’hyperactivité sous stress, et la tyrannie du directeur de crise qui coupe la parole. Chacun a sa parade, souvent par un message ciblé de l’animation. Le point commun : les observateurs aident à repérer ces comportements.
Deux recommandations de fond sont à retenir. D’abord, éviter un scénario trop catastrophique : trop d’événements graves saturent les joueurs et les dégoûtent de recommencer ; on peut limiter le périmètre de l’attaque à une partie du système d’information. Ensuite, se méfier du syndrome « notre système n’a aucune faille » : le guide suggère d’inventer un vecteur crédible, comme une faille récemment publiée et non corrigée, ou une attaque indirecte par un prestataire.
Ce que ça couvre, et ce que ça ne couvre pas

Ce qu’il éprouve
- Les décisions et arbitrages, sous pression et avec des informations incomplètes.
- Les chaînes d’alerte et l’annuaire : qui est prévenu, quand, par quel moyen.
- La coordination entre la sécurité, les métiers et la direction, voire entre plusieurs sites.
- La communication de crise interne, vers les clients, vers la presse.
- Les obligations légales, jouées : on décide de déclarer à la CNIL ou à l’assureur, on ne déclare pas pour de vrai.
- Les rôles : qui décide, qui valide un message, qui parle à l’extérieur.
Ce qu’il ne couvre pas
- Les outils de détection : un exercice de direction ne dit pas si votre supervision aurait vu l’attaque (voir notre mesure du délai d’alerte).
- La restauration réelle : on décide de restaurer, on ne restaure pas. Seul un test de restauration prouve qu’elle fonctionne.
- Les failles techniques : les vulnérabilités se trouvent par des scans et des tests d’intrusion ; le scénario peut en inventer une, il n’en découvre pas.
- La cellule opérationnelle et les compétences d’investigation : la CCO est simulée par l’animation, et le guide exclut explicitement les exercices techniques ; pour s’entraîner à investiguer, il faut un exercice technique ou une plateforme dédiée.
- La durée réelle d’une crise : le temps est accéléré, l’investigation raccourcie, la sortie de crise (plusieurs mois en réalité) à peine effleurée.
- L’évaluation des personnes : ce n’est pas un examen ; le présenter ainsi détruit l’adhésion, et le guide le déconseille.
- La preuve que le plan « fonctionne » : l’exercice sur table, dit le guide, ne permet pas de tester le dispositif de crise ; il fait apparaître des pistes d’amélioration. Notre remarque : un plan qui se déroule bien sur le papier peut échouer devant une panne réelle des moyens de communication.
Un outil pour préparer et mesurer : crise_exercice.py
Écrire un chronogramme à la main, c’est facile d’oublier une chose : un rôle jamais sollicité, un objectif que rien ne teste, un message qui oublie de dire qu’il s’agit d’un exercice. Nous avons écrit crise_exercice.py (bibliothèque standard de Python, environ 420 lignes) pour contrôler la forme d’un scénario, produire la fiche d’animation, mesurer les délais après l’exercice et tenir la main courante de l’animation. Il ne juge ni la qualité du scénario ni le comportement des joueurs : cela reste le travail des animateurs et des observateurs.
Les principales règles contrôlées et leur source
| Code | Contrôle | Source dans le guide |
|---|---|---|
| E02, W02 | Des objectifs, trois à quatre de préférence | Fiche 1 : « sélectionner trois à quatre objectifs par exercice » |
| E10 | Chaque objectif est testé par au moins un message | Les objectifs structurent le chronogramme (étape 2) |
| E11 | Chaque rôle de joueur est sollicité au moins une fois | Objectif de l’exercice RANSOM20 : « s’assurer que l’ensemble des personnes nécessaires ont été sollicitées » |
| E06 | Tout message commence par « EXERCICE » | Simulation de la pression médiatique : éviter toute confusion avec une information réelle |
| E07 | Aucune action réelle | « Un exercice ne doit en aucun cas avoir un impact réel » |
| E12 | Si des données personnelles sont en jeu, un message simule la déclaration à la CNIL | Saisir les opportunités de l’exercice : déclarations légales à prévoir |
| E13 | Un planificateur n’est pas joueur | Phase 2 de l’étape 1 : concepteurs ≠ joueurs |
| W03, W04 | Au plus deux observateurs par salle ; pas de supérieur direct d’un joueur | Fiche des observateurs ; recommandation sur les supérieurs hiérarchiques |
| W05, W06 | Simulation : animateur principal et secrétaire | Fiche des animateurs : « au minimum » |
| E08 | Un message qui attend une décision dit laquelle et en combien de temps | Notre ajout : sans cela, rien ne se mesure ensuite |
| W01, W07 | Durée dans la plage du format ; silence supérieur à 20 minutes signalé | Durées par format ; 10 à 15 min de silence pendant l’investigation (le seuil de 20 min est le nôtre) |
Le scénario d’exemple
Le fichier scenario-exemple.json (reproduit en fin d’article) est un scénario fictif : une PME industrielle d’une centaine de personnes, un rançongiciel avec fuite de données, un exercice sur table de 3 heures, 4 objectifs (alerter, arbitrer entre continuité et sécurité, communiquer, respecter les obligations), 6 rôles de joueurs, 14 messages dont 12 attendent une décision. Aucune entreprise réelle n’est visée ; le vecteur d’entrée (un compte VPN sans double authentification) est volontairement banal, comme le recommande le guide.
$ python3 crise_exercice.py verifier scenario-exemple.json
0 erreur(s), 0 avertissement(s) sur 14 injects.
Pour voir ce que l’outil attrape, nous avons ensuite cassé le scénario en trois endroits (retiré le message de déclaration à la CNIL, supprimé la balise « EXERCICE » du message du journaliste, redirigé le seul message destiné aux RH), ajouté un troisième observateur qui est le supérieur direct d’un joueur, et repoussé un message de 30 minutes. Le code de sortie passe à 1 :
$ python3 crise_exercice.py verifier scenario-casse.json
ERREUR E06 I07 : le texte doit commencer par « EXERCICE » (éviter de confondre avec un vrai incident)
ERREUR E11 le rôle « RH » n'est sollicité par aucun inject (objectif : que toutes les personnes utiles soient mobilisées)
ERREUR E12 des données personnelles sont en jeu mais aucun inject ne simule la déclaration à la CNIL
AVERTISSEMENT W03 3 observateurs dans la salle « cellule » : pas plus de deux
AVERTISSEMENT W04 l'observateur Inès2 est le supérieur direct du joueur Sophie (l'exercice risque d'être vécu comme une évaluation)
AVERTISSEMENT W07 silence de 45 min entre T+130 et T+175 (le guide cite 10 à 15 min de silence pendant l'investigation)
3 erreur(s), 3 avertissement(s) sur 14 injects.
La fiche d’animation et le rapport
La commande animer produit un tableau chronologique : instant, canal, expéditeur et destinataire, texte exact à dire ou à envoyer, réaction attendue et délai maximal. Les animateurs notent ensuite, pour chaque message, l’heure de livraison et l’heure de la réponse dans un journal. La commande rapport calcule le délai de chaque décision, la classe (dans les temps, en retard, sans réponse, non jouée), la rapporte à chaque objectif, repère les rôles qui n’ont produit aucune décision et prépare le squelette du retour d’expérience avec le plan d’action nominatif.
Le journal que nous avons utilisé pour l’exemple est fictif : nous n’avons pas fait jouer ce scénario à des personnes. Il sert à montrer la forme du rapport et à tester le calcul. Résultat sur ce journal :
$ python3 crise_exercice.py rapport scenario-exemple.json journal-exemple-fictif.json
Décisions attendues : 12 · dans les temps : 9 · en retard : 1 · sans réponse : 2 · non jouées : 0
- O1 (alerter) : 2/2 décision(s) dans les temps
- O2 (arbitrer continuité / sécurité) : 4/5 décision(s) dans les temps
- O3 (communication de crise) : 1/3 décision(s) dans les temps
- O4 (obligations : CNIL, assureur, plainte) : 4/4 décision(s) dans les temps
| I04 | RSSI | 26 min | 15 min | en retard |
| I07 | COM | - | 20 min | sans réponse |
| I10 | RH | - | 25 min | sans réponse |
Rôles qui n'ont produit aucune décision mesurée : RH, COM (à expliquer en RETEX : rôle mal sollicité, ou absent ?)
Sur ce journal inventé, la lecture serait : l’alerte et les obligations tiennent, la communication de crise est le point faible (deux décisions sur trois manquées, dont celle de la presse), et il faudra comprendre en retour d’expérience pourquoi la RH et la communication n’ont rien tranché. L’outil donne des faits mesurés ; l’interprétation reste humaine.
Comment nous l’avons testé
L’outil embarque 29 tests (python3 crise_exercice.py --test) : un scénario valide ne doit produire aucun message, et chaque règle a un test qui l’enfreint. Pour vérifier que les tests ne sont pas décoratifs, nous avons cassé le code à onze endroits : six dans le contrôle, le calcul et la fiche (opérateur « inférieur ou égal » devenu « inférieur » dans le calcul du délai, règle des objectifs supprimée, règle CNIL désactivée, contrôle de la balise « EXERCICE » désactivé, tri de la fiche d’animation inversé, liste des rôles absents vidée) : les six modifications sont détectées, par un à deux tests chacune. Cinq autres touchent la main courante (échéance calculée sans le délai maximal, tri chronologique supprimé, décision inventée à partir de ce qui était attendu, message inconnu non ignoré, comparaison du délai limite). Une survivait : la comparaison du délai limite n’était testée que pour le calcul du rapport, pas pour la main courante ; nous avons ajouté le test, et la modification est maintenant détectée. Le délai égal au maximum est compté « dans les temps » ; c’est un choix, couvert par un test.
Votre premier exercice, semaine par semaine
Le guide chiffre la préparation d’un exercice sur table à environ six semaines. Voici un découpage de notre cru, fondé sur ses quatre étapes, pour une organisation qui n’a jamais joué.
| Semaine | Quoi | Livrable |
|---|---|---|
| 1 | Choisir un sponsor dans la direction ; constituer le groupe projet (un responsable, un expert sécurité, une personne de la continuité) ; fixer la date | Cahier des charges : objectifs (3 à 4), format (sur table), thème, joueurs, date |
| 2 | Choisir le thème dans l’analyse de risques ou la menace du secteur ; interroger un expert métier et un expert technique | Notes d’entretien, trame du scénario |
| 3 – 4 | Écrire le scénario et le chronogramme (autour de 12 à 15 messages) ; remplir le fichier JSON de l’outil ; lancer la vérification | Chronogramme validé, fiche d’animation |
| 5 | Briefer animateurs et observateurs ; envoyer l’invitation aux joueurs avec les objectifs (sans révéler le scénario) ; tester les outils de communication et préparer la main courante des joueurs (hors du système d’information) | Invitations, grilles d’observation, modèle de main courante |
| 6 | Jour J : briefing, jeu, retour d’expérience à chaud ; sauvegarder les main courantes (joueurs et animation) et les mails | Main courantes, journal des délais |
| + 2 à 4 semaines | Retour d’expérience à froid ; rapport avec plan d’action nominatif | Rapport (au plus deux mois après) |
Des questions à poser, même sans exercice formel
Si vous n’avez pas encore de temps ou de budget, une conversation d’une heure autour de six questions donne déjà des résultats. Elles sont de notre cru :
- Qui décide d’isoler le réseau, et sait-il qu’il peut le faire sans demander l’autorisation à plusieurs personnes ?
- Où est l’annuaire de crise, et est-il disponible quand la messagerie est tombée ?
- Par quel moyen prévient-on les gens si la messagerie et le téléphone d’entreprise sont indisponibles ?
- Qui parle à la presse et aux clients, et qui valide ce qu’il dit ?
- Qui décide de la déclaration à la CNIL et dans quel délai ?
- Qui sait à quelle date a été testée la dernière restauration, et de quoi ?
Mesurer le progrès
Un exercice isolé est instructif ; une série devient un programme. Le guide recommande d’inscrire les exercices dans une démarche d’apprentissage progressive, généralement pluriannuelle, avec des paliers. Voici des indicateurs que nous suggérons de suivre d’un exercice à l’autre (ils ne figurent pas dans le guide) : le délai entre le premier message et la réunion de la cellule, le délai jusqu’à la première décision d’isolement, le nombre de rôles qui n’ont produit aucune décision, la part des actions du plan d’action clôturées dans les deux mois, et le nombre d’éléments de l’annuaire corrigés.
Limites de cet article
- Sources : la méthode d’exercice vient du guide de l’ANSSI et du CCA (version 1.0, 2020, 128 pages) ; l’organisation des cellules, la liaison entre elles et la main courante viennent du guide ANSSI et CDSE (version 1.0, décembre 2021, 80 pages) ; NIS 2 et DORA sont lus sur des copies, EUR-Lex bloquant les requêtes automatiques.
- Pas d’exercice réel : le scénario d’exemple et son journal sont fictifs ; nous n’avons pas fait jouer d’exercice à des participants, donc aucun retour de terrain n’est présenté.
- Le guide a six ans : les exemples de réglementation (Bâle 3, Solvency 2, NIS) datent de 2020 ; NIS 2 a depuis remplacé NIS.
- Les propositions de notre cru (emploi du temps de trois heures, plan de six semaines, questions, indicateurs, seuil de 20 minutes de silence, fréquence des points de situation, format du point de situation, colonnes et règles de tenue de la main courante) sont signalées comme telles et ne sont pas des recommandations officielles.
- L’outil contrôle la forme : il ne juge pas la crédibilité d’un scénario, ni la façon dont un exercice sera mené.
- Le niveau décisionnel seulement : nous ne traitons pas les exercices techniques de type cyber range.
Transparence : la recherche, la rédaction et, lorsqu’il y en a, les tests de cet article ont été réalisés avec l’aide d’un assistant IA (Claude) ; l’éditeur du site relit et valide chaque article avant publication. L’exemple est fictif : aucune organisation réelle n’est décrite.
Les fichiers complets
crise_exercice.py
#!/usr/bin/env python3
"""crise_exercice.py : préparer et mesurer un exercice de crise (bibliothèque standard seulement).
python3 crise_exercice.py verifier scenario.json # contrôle de cohérence (code 1 si erreur)
python3 crise_exercice.py animer scenario.json # fiche d'animation chronologique (Markdown)
python3 crise_exercice.py rapport scenario.json journal.json # mesures + squelette de RETEX (Markdown)
python3 crise_exercice.py --test # tests intégrés
Les règles viennent du guide ANSSI « Organiser un exercice de gestion de crise cyber » (v1.0, 2020) ; chaque règle cite sa source.
Le script contrôle la FORME d'un exercice (couverture des objectifs, rôles sollicités, balises « EXERCICE »…) : il ne dit rien
de la qualité du scénario ni du comportement des joueurs, qui restent l'affaire des animateurs et des observateurs."""
import json
import sys
import unittest
FORMATS = {"table": (60, 180), "simulation": (180, 2880)} # minutes : table 1-3 h, simulation 3 h à 2 jours (rarement plus)
CANAUX = {"mail", "tel", "oral", "media", "reseau"}
def charger(chemin):
with open(chemin, encoding="utf-8") as f:
return json.load(f)
def verifier(sc):
"""Renvoie une liste de (niveau, code, message) ; niveau = 'ERREUR' ou 'AVERTISSEMENT'."""
r = []
err = lambda c, m: r.append(("ERREUR", c, m))
warn = lambda c, m: r.append(("AVERTISSEMENT", c, m))
duree = sc.get("duree_min", 0)
fmt = sc.get("format")
if fmt not in FORMATS:
err("E01", f"format inconnu : {fmt!r} (attendu : table ou simulation)")
elif not FORMATS[fmt][0] <= duree <= FORMATS[fmt][1]:
warn("W01", f"durée {duree} min hors de la plage usuelle du format « {fmt} » ({FORMATS[fmt][0]}-{FORMATS[fmt][1]} min)")
objectifs = sc.get("objectifs", {})
if not objectifs:
err("E02", "aucun objectif défini")
elif not 3 <= len(objectifs) <= 4:
warn("W02", f"{len(objectifs)} objectif(s) : le guide conseille trois à quatre par exercice")
injects = sc.get("injects", [])
ids = [i.get("id") for i in injects]
for d in {x for x in ids if ids.count(x) > 1}:
err("E03", f"identifiant d'inject en double : {d}")
for i in injects:
t = i.get("t")
if not isinstance(t, int) or not 0 <= t <= duree:
err("E04", f"{i.get('id')} : instant {t!r} hors de l'exercice (0 à {duree} min)")
if i.get("canal") not in CANAUX:
err("E05", f"{i.get('id')} : canal inconnu {i.get('canal')!r}")
if not str(i.get("texte", "")).strip().upper().startswith("EXERCICE"):
err("E06", f"{i.get('id')} : le texte doit commencer par « EXERCICE » (éviter de confondre avec un vrai incident)")
if i.get("action_reelle"):
err("E07", f"{i.get('id')} : un exercice ne doit avoir aucun impact réel (action_reelle = vrai)")
if i.get("decision") and (not str(i.get("attendu", "")).strip() or not i.get("delai_max_min", 0) > 0):
err("E08", f"{i.get('id')} : un inject qui attend une décision doit dire ce qui est attendu et le délai maximal")
for o in i.get("objectifs", []):
if o not in objectifs:
err("E09", f"{i.get('id')} : objectif inconnu {o}")
for o in objectifs:
if not any(o in i.get("objectifs", []) for i in injects):
err("E10", f"l'objectif {o} n'est testé par aucun inject")
sollicites = {i.get("vers") for i in injects}
for role in sc.get("roles_joueurs", []):
if role not in sollicites:
err("E11", f"le rôle « {role} » n'est sollicité par aucun inject (objectif : que toutes les personnes utiles soient mobilisées)")
if sc.get("donnees_personnelles") and not any(i.get("sujet") == "cnil" for i in injects):
err("E12", "des données personnelles sont en jeu mais aucun inject ne simule la déclaration à la CNIL")
# personnes et rôles
pers = sc.get("personnes", [])
joueurs = {p["nom"] for p in pers if p.get("role") == "joueur"}
for p in pers:
if p.get("role") == "planificateur" and p["nom"] in joueurs:
err("E13", f"{p['nom']} est à la fois planificateur et joueur (il connaît le scénario)")
par_salle = {}
for p in pers:
if p.get("role") == "observateur":
par_salle.setdefault(p.get("salle", "?"), []).append(p)
for salle, obs in par_salle.items():
if len(obs) > 2:
warn("W03", f"{len(obs)} observateurs dans la salle « {salle} » : pas plus de deux")
for o in obs:
for sup in o.get("superieur_de", []):
if sup in joueurs:
warn("W04", f"l'observateur {o['nom']} est le supérieur direct du joueur {sup} (l'exercice risque d'être vécu comme une évaluation)")
if fmt == "simulation":
if not any(p.get("fonction") == "animateur-principal" for p in pers):
warn("W05", "simulation sans animateur principal (DIRANIM)")
if not any(p.get("fonction") == "secretaire" for p in pers):
warn("W06", "simulation sans secrétaire chargé de suivre le chronogramme")
# rythme (indicatif)
ts = sorted(i["t"] for i in injects if isinstance(i.get("t"), int))
for a, b in zip(ts, ts[1:]):
if b - a > 20:
warn("W07", f"silence de {b - a} min entre T+{a} et T+{b} (le guide cite 10 à 15 min de silence pendant l'investigation)")
return r
def _hm(m):
return f"T+{m // 60:d}h{m % 60:02d}"
def animer(sc):
"""Fiche d'animation : tout ce que la cellule d'animation doit envoyer, dans l'ordre."""
ligne = [f"# Fiche d'animation : {sc.get('nom', '?')}", "",
f"Format : {sc.get('format')} · durée prévue : {sc.get('duree_min')} min · objectifs : "
+ " ; ".join(f"{k} = {v}" for k, v in sc.get("objectifs", {}).items()), "",
"| Instant | Canal | De → vers | Message (à dire ou envoyer tel quel) | Réaction attendue | Délai max |", "|---|---|---|---|---|---|"]
for i in sorted(sc.get("injects", []), key=lambda x: (x["t"], x["id"])):
att = i.get("attendu", "") if i.get("decision") else "(information)"
dm = f"{i['delai_max_min']} min" if i.get("decision") else "-"
ligne.append(f"| {_hm(i['t'])} | {i['canal']} | {i['de']} → {i['vers']} | {i['texte']} | {att} | {dm} |")
ligne += ["", "Rappels : aucune action réelle sur les systèmes · tout message commence par « EXERCICE » · noter l'heure réelle de chaque envoi et de chaque réponse (journal)."]
return "\n".join(ligne)
def rapport(sc, journal):
"""Mesures à partir du journal des animateurs ; le jugement reste humain (RETEX)."""
par_id = {e["inject"]: e for e in journal}
res, roles = [], {}
for i in sorted(sc.get("injects", []), key=lambda x: x["t"]):
if not i.get("decision"):
continue
e = par_id.get(i["id"], {})
reponse, livre = e.get("reponse_min"), e.get("livre_min")
if livre is None:
statut, delai = "non joué", None
elif reponse is None:
statut, delai = "sans réponse", None
else:
delai = reponse - livre
statut = "dans les temps" if delai <= i["delai_max_min"] else "en retard"
roles[i["vers"]] = roles.get(i["vers"], 0) + 1
res.append({"inject": i["id"], "role": i["vers"], "objectifs": i.get("objectifs", []), "delai": delai,
"max": i["delai_max_min"], "statut": statut, "attendu": i["attendu"]})
objectifs = {}
for r_ in res:
for o in r_["objectifs"]:
ok, tot = objectifs.get(o, (0, 0))
objectifs[o] = (ok + (r_["statut"] == "dans les temps"), tot + 1)
return {"decisions": res, "objectifs": objectifs, "roles_actifs": roles,
"roles_absents": [x for x in sc.get("roles_joueurs", []) if x not in roles]}
def rapport_md(sc, journal):
m = rapport(sc, journal)
n = len(m["decisions"])
ok = sum(d["statut"] == "dans les temps" for d in m["decisions"])
l = [f"# Squelette de RETEX : {sc.get('nom', '?')}", "",
f"Décisions attendues : {n} · dans les temps : {ok} · en retard : {sum(d['statut'] == 'en retard' for d in m['decisions'])}"
f" · sans réponse : {sum(d['statut'] == 'sans réponse' for d in m['decisions'])} · non jouées : {sum(d['statut'] == 'non joué' for d in m['decisions'])}", "",
"## Mesures par objectif", ""]
for o, (a, t) in sorted(m["objectifs"].items()):
l.append(f"- {o} ({sc['objectifs'].get(o, '?')}) : {a}/{t} décision(s) dans les temps")
l += ["", "## Décisions", "", "| Inject | Rôle | Délai mesuré | Délai max | Statut |", "|---|---|---|---|---|"]
for d in m["decisions"]:
l.append(f"| {d['inject']} | {d['role']} | {'-' if d['delai'] is None else str(d['delai']) + ' min'} | {d['max']} min | {d['statut']} |")
if m["roles_absents"]:
l += ["", "Rôles qui n'ont produit aucune décision mesurée : " + ", ".join(m["roles_absents"]) + " (à expliquer en RETEX : rôle mal sollicité, ou absent ?)"]
l += ["", "## À compléter à la main (ne se calcule pas)", "",
"- Points forts observés, avec preuves (mains courantes, mails)", "- Axes d'amélioration", "- Écarts avec la réalité (temps accéléré, investigations raccourcies)",
"", "## Plan d'action", "", "| Action | Responsable | Échéance |", "|---|---|---|", "| à compléter | nommé | RETEX à froid dans le mois ; rapport écrit sous 2 mois |"]
return "\n".join(l)
def courante(sc, journal):
"""Main courante de l'animation : un événement par ligne (envoi, réponse, échéance dépassée), triés par heure.
Les heures sont des minutes écoulées depuis le début de l'exercice."""
par_id = {i["id"]: i for i in sc.get("injects", [])}
lignes = []
for e in journal:
i = par_id.get(e["inject"])
if i is None or e.get("livre_min") is None:
continue
liv, rep = e["livre_min"], e.get("reponse_min")
lignes.append({"t": liv, "type": "envoi", "inject": i["id"], "canal": i["canal"], "de": i["de"], "vers": i["vers"], "contenu": i["texte"], "delai": "", "statut": ""})
if not i.get("decision"):
continue
if rep is None:
lignes.append({"t": liv + i["delai_max_min"], "type": "échéance dépassée", "inject": i["id"], "canal": "", "de": "", "vers": i["vers"],
"contenu": "aucune réponse enregistrée : " + i["attendu"], "delai": "", "statut": "sans réponse"})
else:
d = rep - liv
lignes.append({"t": rep, "type": "réponse", "inject": i["id"], "canal": "", "de": i["vers"], "vers": "", "contenu": e.get("decision") or "(décision non consignée)", "delai": d,
"statut": "dans les temps" if d <= i["delai_max_min"] else "en retard"})
ordre = {"envoi": 0, "réponse": 1, "échéance dépassée": 2}
return sorted(lignes, key=lambda x: (x["t"], ordre[x["type"]], x["inject"]))
def courante_csv(lignes):
import csv
import io
out = io.StringIO()
w = csv.writer(out, lineterminator="\n")
w.writerow(["heure", "type", "inject", "canal", "de", "vers", "contenu", "delai_min", "statut"])
for x in lignes:
w.writerow([_hm(x["t"]), x["type"], x["inject"], x["canal"], x["de"], x["vers"], x["contenu"], x["delai"], x["statut"]])
return out.getvalue()
def courante_md(lignes):
l = ["| Heure | Type | Inject | De → vers | Contenu | Délai | Statut |", "|---|---|---|---|---|---|---|"]
for x in lignes:
lien = f"{x['de']} → {x['vers']}" if x["de"] and x["vers"] else (x["de"] or x["vers"])
l.append(f"| {_hm(x['t'])} | {x['type']} | {x['inject']} | {lien} | {x['contenu']} | {x['delai'] if x['delai'] != '' else '-'} | {x['statut'] or '-'} |")
return "\n".join(l)
# ----------------------------------------------------------------------------------------------- tests
def _base():
return {
"nom": "TEST", "format": "table", "duree_min": 180, "donnees_personnelles": True,
"objectifs": {"O1": "alerter", "O2": "communiquer", "O3": "décider"},
"roles_joueurs": ["DG", "RSSI", "COM"],
"personnes": [
{"nom": "Ana", "role": "planificateur"}, {"nom": "Bob", "role": "joueur"},
{"nom": "Cléo", "role": "observateur", "salle": "A"},
],
"injects": [
{"id": "I1", "t": 10, "canal": "tel", "de": "Accueil", "vers": "RSSI", "texte": "EXERCICE - écrans bloqués", "objectifs": ["O1"], "decision": True, "attendu": "réunir la cellule", "delai_max_min": 10},
{"id": "I2", "t": 25, "canal": "media", "de": "Journaliste", "vers": "COM", "texte": "EXERCICE - un journaliste appelle", "objectifs": ["O2"], "decision": True, "attendu": "préparer un élément de langage", "delai_max_min": 20},
{"id": "I3", "t": 40, "canal": "mail", "de": "Juridique", "vers": "DG", "texte": "EXERCICE - données clients volées ?", "objectifs": ["O3"], "sujet": "cnil", "decision": True, "attendu": "décider de notifier", "delai_max_min": 30},
],
}
def _codes(sc):
return {c for _, c, _ in verifier(sc)}
class TestVerifier(unittest.TestCase):
def test_scenario_valide(self):
self.assertEqual(verifier(_base()), [])
def test_objectif_sans_inject(self):
sc = _base(); sc["injects"][0]["objectifs"] = ["O2"]
self.assertIn("E10", _codes(sc))
def test_role_non_sollicite(self):
sc = _base(); sc["roles_joueurs"].append("RH")
self.assertIn("E11", _codes(sc))
def test_balise_exercice_obligatoire(self):
sc = _base(); sc["injects"][1]["texte"] = "Un journaliste appelle"
self.assertIn("E06", _codes(sc))
def test_cnil_exigee_si_donnees_personnelles(self):
sc = _base(); del sc["injects"][2]["sujet"]
self.assertIn("E12", _codes(sc))
sc["donnees_personnelles"] = False
self.assertNotIn("E12", _codes(sc))
def test_impact_reel_interdit(self):
sc = _base(); sc["injects"][0]["action_reelle"] = True
self.assertIn("E07", _codes(sc))
def test_decision_sans_attendu_ni_delai(self):
sc = _base(); sc["injects"][0]["attendu"] = ""
self.assertIn("E08", _codes(sc))
sc = _base(); sc["injects"][0]["delai_max_min"] = 0
self.assertIn("E08", _codes(sc))
def test_instant_hors_exercice_et_doublon(self):
sc = _base(); sc["injects"][0]["t"] = 999; sc["injects"][1]["id"] = "I1"
self.assertTrue({"E04", "E03"} <= _codes(sc))
def test_planificateur_joueur(self):
sc = _base(); sc["personnes"].append({"nom": "Ana", "role": "joueur"})
self.assertIn("E13", _codes(sc))
def test_observateurs_et_hierarchie(self):
sc = _base()
sc["personnes"] += [{"nom": "D", "role": "observateur", "salle": "A"}, {"nom": "E", "role": "observateur", "salle": "A", "superieur_de": ["Bob"]}]
self.assertTrue({"W03", "W04"} <= _codes(sc))
def test_nombre_objectifs_et_duree(self):
sc = _base(); del sc["objectifs"]["O3"]; sc["injects"][2]["objectifs"] = ["O1"]; sc["duree_min"] = 30
self.assertTrue({"W01", "W02"} <= _codes(sc))
def test_silence_long(self):
sc = _base(); sc["injects"][2]["t"] = 100
self.assertIn("W07", _codes(sc))
def test_simulation_exige_animateur_et_secretaire(self):
sc = _base(); sc["format"] = "simulation"
self.assertTrue({"W05", "W06"} <= _codes(sc))
def test_format_inconnu_et_aucun_objectif(self):
sc = _base(); sc["format"] = "atelier"
self.assertIn("E01", _codes(sc))
sc = _base(); sc["objectifs"] = {}
self.assertIn("E02", _codes(sc))
def test_canal_et_objectif_inconnus(self):
sc = _base(); sc["injects"][0]["canal"] = "pigeon"
self.assertIn("E05", _codes(sc))
sc = _base(); sc["injects"][0]["objectifs"] = ["O9"]
self.assertIn("E09", _codes(sc))
def test_canal_oral_valide(self):
sc = _base(); sc["injects"][0]["canal"] = "oral"
self.assertEqual(verifier(sc), [])
class TestSorties(unittest.TestCase):
def test_animer_trie_par_instant(self):
sc = _base(); sc["injects"].reverse()
txt = animer(sc)
self.assertLess(txt.index("T+0h10"), txt.index("T+0h25"))
self.assertLess(txt.index("T+0h25"), txt.index("T+0h40"))
self.assertIn("EXERCICE", txt)
def test_rapport_delais_et_statuts(self):
sc = _base()
j = [{"inject": "I1", "livre_min": 10, "reponse_min": 15}, # 5 min <= 10 : dans les temps
{"inject": "I2", "livre_min": 25, "reponse_min": 60}, # 35 min > 20 : en retard
{"inject": "I3", "livre_min": 40, "reponse_min": None}] # sans réponse
m = rapport(sc, j)
st = {d["inject"]: (d["statut"], d["delai"]) for d in m["decisions"]}
self.assertEqual(st, {"I1": ("dans les temps", 5), "I2": ("en retard", 35), "I3": ("sans réponse", None)})
self.assertEqual(m["objectifs"], {"O1": (1, 1), "O2": (0, 1), "O3": (0, 1)})
self.assertEqual(m["roles_absents"], ["DG"])
def test_rapport_inject_non_joue(self):
m = rapport(_base(), [])
self.assertTrue(all(d["statut"] == "non joué" for d in m["decisions"]))
def test_delai_pile_au_maximum_est_dans_les_temps(self):
sc = _base()
m = rapport(sc, [{"inject": "I1", "livre_min": 10, "reponse_min": 20}])
self.assertEqual(m["decisions"][0]["statut"], "dans les temps")
def test_rapport_markdown_contient_le_plan_d_action(self):
md = rapport_md(_base(), [{"inject": "I1", "livre_min": 10, "reponse_min": 12}])
self.assertIn("Plan d'action", md)
self.assertIn("Rôles qui n'ont produit aucune décision mesurée", md)
class TestCourante(unittest.TestCase):
J = [{"inject": "I1", "livre_min": 10, "reponse_min": 15}, # dans les temps
{"inject": "I2", "livre_min": 25, "reponse_min": 60}, # en retard
{"inject": "I3", "livre_min": 40, "reponse_min": None}] # sans réponse
def test_chronologie_et_types(self):
c = courante(_base(), self.J)
self.assertEqual([(x["t"], x["type"], x["inject"]) for x in c],
[(10, "envoi", "I1"), (15, "réponse", "I1"), (25, "envoi", "I2"), (40, "envoi", "I3"), (60, "réponse", "I2"), (70, "échéance dépassée", "I3")])
def test_statuts_et_delais(self):
c = {(x["inject"], x["type"]): x for x in courante(_base(), self.J)}
self.assertEqual((c[("I1", "réponse")]["statut"], c[("I1", "réponse")]["delai"]), ("dans les temps", 5))
self.assertEqual((c[("I2", "réponse")]["statut"], c[("I2", "réponse")]["delai"]), ("en retard", 35))
self.assertEqual(c[("I3", "échéance dépassée")]["statut"], "sans réponse")
def test_reponse_pile_au_delai_maximal_est_dans_les_temps(self):
c = [x for x in courante(_base(), [{"inject": "I1", "livre_min": 10, "reponse_min": 20}]) if x["type"] == "réponse"]
self.assertEqual((c[0]["delai"], c[0]["statut"]), (10, "dans les temps"))
def test_echeance_depassee_a_livraison_plus_delai_max(self):
c = [x for x in courante(_base(), self.J) if x["type"] == "échéance dépassée"]
self.assertEqual(c[0]["t"], 40 + 30)
def test_decision_consignee_ou_non(self):
j = [{"inject": "I1", "livre_min": 10, "reponse_min": 15, "decision": "cellule réunie, serveurs isolés"}, {"inject": "I2", "livre_min": 25, "reponse_min": 30}]
c = {(x["inject"], x["type"]): x["contenu"] for x in courante(_base(), j)}
self.assertEqual(c[("I1", "réponse")], "cellule réunie, serveurs isolés")
self.assertEqual(c[("I2", "réponse")], "(décision non consignée)")
def test_message_d_information_sans_reponse_attendue(self):
sc = _base(); sc["injects"][0].pop("decision")
c = courante(sc, [{"inject": "I1", "livre_min": 10, "reponse_min": None}])
self.assertEqual([x["type"] for x in c], ["envoi"])
def test_inject_inconnu_ou_non_livre_ignore(self):
c = courante(_base(), [{"inject": "X9", "livre_min": 5, "reponse_min": 6}, {"inject": "I1", "livre_min": None, "reponse_min": None}])
self.assertEqual(c, [])
def test_csv_en_tete_et_guillemets(self):
sc = _base(); sc["injects"][0]["texte"] = 'EXERCICE - écrans, "bloqués"; machines arrêtées'
out = courante_csv(courante(sc, [{"inject": "I1", "livre_min": 10, "reponse_min": 12}]))
self.assertTrue(out.startswith("heure,type,inject,canal,de,vers,contenu,delai_min,statut\n"))
import csv
import io
rows = list(csv.reader(io.StringIO(out)))
self.assertEqual(rows[1][6], 'EXERCICE - écrans, "bloqués"; machines arrêtées')
def main(argv):
if argv[:1] == ["--test"]:
res = unittest.main(argv=[sys.argv[0]], exit=False, verbosity=1).result
return 0 if res.wasSuccessful() else 1
if len(argv) < 2 or argv[0] not in {"verifier", "animer", "rapport", "courante"}:
print(__doc__)
return 2
try:
sc = charger(argv[1])
if argv[0] == "verifier":
res = verifier(sc)
for niveau, code, msg in res:
print(f"{niveau:<14} {code} {msg}")
n_err = sum(1 for n, _, _ in res if n == "ERREUR")
print(f"{n_err} erreur(s), {len(res) - n_err} avertissement(s) sur {len(sc.get('injects', []))} injects.")
return 1 if n_err else 0
if argv[0] == "animer":
print(animer(sc))
return 0
if argv[0] == "courante":
lignes = courante(sc, charger(argv[2]))
print(courante_csv(lignes), end="") if "--csv" in argv else print(courante_md(lignes))
return 0
print(rapport_md(sc, charger(argv[2])))
return 0
except (OSError, ValueError, KeyError) as e:
print(f"Fichier ou structure invalide : {e}", file=sys.stderr)
return 2
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
scenario-exemple.json
{
"nom": "RANSOM-PME (scénario d'exemple fictif)",
"format": "table",
"duree_min": 180,
"donnees_personnelles": true,
"objectifs": {
"O1": "Vérifier que toutes les personnes utiles sont alertées, dans le bon ordre",
"O2": "S'entraîner à arbitrer entre continuité d'activité et sécurité",
"O3": "Tester la communication de crise (interne, clients, presse)",
"O4": "Vérifier la prise en compte des obligations (CNIL, assureur, plainte)"
},
"roles_joueurs": [
"DG",
"RSSI",
"DAF",
"RH",
"COM",
"Production"
],
"personnes": [
{
"nom": "Claire",
"role": "planificateur",
"fonction": "animateur-principal"
},
{
"nom": "Hugo",
"role": "observateur",
"salle": "cellule"
},
{
"nom": "Inès",
"role": "observateur",
"salle": "cellule"
},
{
"nom": "Marc",
"role": "joueur",
"fonction": "DG"
},
{
"nom": "Sophie",
"role": "joueur",
"fonction": "RSSI"
},
{
"nom": "Paul",
"role": "joueur",
"fonction": "DAF"
},
{
"nom": "Laure",
"role": "joueur",
"fonction": "RH"
},
{
"nom": "Yanis",
"role": "joueur",
"fonction": "COM"
},
{
"nom": "Éric",
"role": "joueur",
"fonction": "Production"
}
],
"injects": [
{
"id": "I01",
"t": 20,
"canal": "tel",
"de": "Chef d'atelier",
"vers": "Production",
"texte": "EXERCICE - Les postes de l'atelier affichent un message exigeant une rançon ; les machines à commande numérique ne reçoivent plus leurs programmes.",
"objectifs": [
"O1"
],
"decision": true,
"attendu": "prévenir le RSSI et le directeur général, ouvrir un registre d'événements",
"delai_max_min": 10
},
{
"id": "I02",
"t": 23,
"canal": "tel",
"de": "Assistante de direction",
"vers": "DG",
"texte": "EXERCICE - Le standard est saturé : trois clients demandent pourquoi les commandes ne sortent plus.",
"objectifs": [
"O1"
]
},
{
"id": "I03",
"t": 27,
"canal": "mail",
"de": "Technicien informatique",
"vers": "RSSI",
"texte": "EXERCICE - La messagerie est injoignable ; des fichiers portent l'extension .locked sur deux serveurs de fichiers.",
"objectifs": [
"O1",
"O2"
],
"decision": true,
"attendu": "décider d'isoler les serveurs touchés et de réunir la cellule de crise",
"delai_max_min": 10
},
{
"id": "I04",
"t": 32,
"canal": "tel",
"de": "Responsable des sauvegardes",
"vers": "RSSI",
"texte": "EXERCICE - La sauvegarde de la nuit est présente mais stockée sur le même réseau ; on ne sait pas si elle est atteinte.",
"objectifs": [
"O2"
],
"decision": true,
"attendu": "demander une vérification de l'état des copies hors ligne avant toute restauration",
"delai_max_min": 15
},
{
"id": "I05",
"t": 38,
"canal": "oral",
"de": "Directeur de production",
"vers": "DG",
"texte": "EXERCICE - Un client donneur d'ordre exige une livraison demain matin ; arrêter l'atelier coûte 40 000 euros par jour.",
"objectifs": [
"O2"
],
"decision": true,
"attendu": "arbitrer entre isolement total et production partielle, et le dire par écrit",
"delai_max_min": 20
},
{
"id": "I06",
"t": 50,
"canal": "mail",
"de": "Prestataire de réponse à incident",
"vers": "RSSI",
"texte": "EXERCICE - Premier avis : accès initial par un compte VPN sans double authentification ; un téléchargement vers l'extérieur est suspecté.",
"objectifs": [
"O4"
],
"decision": true,
"attendu": "qualifier une possible fuite de données et en informer le DPO",
"delai_max_min": 15
},
{
"id": "I07",
"t": 65,
"canal": "media",
"de": "Journaliste d'un média régional",
"vers": "COM",
"texte": "EXERCICE - Un journaliste a reçu une alerte anonyme : votre entreprise serait victime d'un rançongiciel. Il demande une réaction avant 18 h.",
"objectifs": [
"O3"
],
"decision": true,
"attendu": "valider une réponse écrite et un porte-parole unique",
"delai_max_min": 20
},
{
"id": "I08",
"t": 75,
"canal": "mail",
"de": "Juridique",
"vers": "DG",
"texte": "EXERCICE - Les pirates publient un échantillon : des fiches de paie et des coordonnées de clients.",
"objectifs": [
"O4"
],
"decision": true,
"attendu": "décider de la notification à la CNIL (72 h) et de la plainte",
"delai_max_min": 30,
"sujet": "cnil"
},
{
"id": "I09",
"t": 85,
"canal": "tel",
"de": "Assureur",
"vers": "DAF",
"texte": "EXERCICE - L'assureur demande d'être prévenu dans les 48 h et de ne payer aucun prestataire sans accord préalable.",
"objectifs": [
"O4"
],
"decision": true,
"attendu": "déclarer le sinistre et geler les engagements financiers",
"delai_max_min": 20
},
{
"id": "I10",
"t": 95,
"canal": "mail",
"de": "Représentant du personnel",
"vers": "RH",
"texte": "EXERCICE - Les salariés demandent s'ils seront payés à la fin du mois ; la paie passe par un logiciel inaccessible.",
"objectifs": [
"O3"
],
"decision": true,
"attendu": "choisir un mode dégradé pour la paie et informer les salariés",
"delai_max_min": 25
},
{
"id": "I11",
"t": 105,
"canal": "reseau",
"de": "Compte anonyme",
"vers": "COM",
"texte": "EXERCICE - Un message sur un réseau social annonce la fuite avec des captures d'écran.",
"objectifs": [
"O3"
]
},
{
"id": "I12",
"t": 115,
"canal": "mail",
"de": "Pirates",
"vers": "DG",
"texte": "EXERCICE - Message de rançon : 120 000 euros en cryptomonnaie sous 72 h, sinon publication de tout.",
"objectifs": [
"O2",
"O4"
],
"decision": true,
"attendu": "fixer une position écrite sur le paiement et l'enregistrer avec ses motifs",
"delai_max_min": 20
},
{
"id": "I13",
"t": 130,
"canal": "tel",
"de": "Donneur d'ordre",
"vers": "DG",
"texte": "EXERCICE - Le client demande une attestation de sécurité et menace de suspendre les commandes.",
"objectifs": [
"O3"
],
"decision": true,
"attendu": "répondre au client avec un message validé et un point de contact",
"delai_max_min": 25
},
{
"id": "I14",
"t": 145,
"canal": "tel",
"de": "Responsable informatique",
"vers": "RSSI",
"texte": "EXERCICE - Le prestataire estime la remise en service du réseau à cinq jours ouvrés.",
"objectifs": [
"O2"
],
"decision": true,
"attendu": "annoncer un calendrier réaliste et arbitrer les priorités de reprise",
"delai_max_min": 20
}
]
}
À lire aussi
- Sauvegardes 3-2-1-1-0 contre les rançongiciels : un exercice de crise ne prouve pas qu’on sait restaurer : le test de restauration, lui, le prouve.
- Sanity check après incident : ce qu’il faut vérifier quand la crise est passée, avant de déclarer le retour à la normale.
Sources
- ANSSI et Club de la continuité d’activité, « Organiser un exercice de gestion de crise cyber », version 1.0 (2020, fondé sur la norme ISO 22398:2013) : page du guide · PDF · modèle de chronogramme
- Directive (UE) 2022/2555 (NIS 2), article 21, paragraphe 2, point c : EUR-Lex
- Règlement (UE) 2022/2554 (DORA), articles 24 et 26 : EUR-Lex
- ANSSI et CDSE, « Crise d’origine cyber : les clés d’une gestion opérationnelle et stratégique », version 1.0, décembre 2021 (ANSSI-PA-089) : PDF
- NIST SP 800-84, « Guide to Test, Training, and Exercise Programs for IT Plans and Capabilities » (septembre 2006) : csrc.nist.gov
- CISA, « CISA Tabletop Exercise Packages » : cisa.gov
- IBM, « Cost of a Data Breach Report » (non chiffré dans l’article, voir plus haut) : ibm.com
- CERT-FR : cert.ssi.gouv.fr ; Cybermalveillance.gouv.fr : cybermalveillance.gouv.fr