help/content/files/challenge.md

9.9 KiB

date title weight
2019-04-04T15:59:52+02:00 challenge.txt 15

Le fichier challenge.txt définit les paramètres de votre étape (au format toml). On y retrouve notamment :

Les gains

gain = 42 : nombre de points que rapporte cette étape.

Généralement les gains se répartissent comment suit :

  • étape 1 : 5 points ;
  • étape 2 : 11 points ;
  • étape 3 : 23 points ;
  • étape 4 : 47 points ;
  • étape 5 : 95 points.

Vous pouvez intervertir ou moduler en fonction de la difficulté réelle par rapport aux autres scénarios.

Les métadonnées

Travail en cours

wip = true : indique que l'étape n'est pas terminée.

Cet attribut est utilisé pour signifier aux potentiels testeurs, lors des FIC blancs par exemple, que votre étape n'est pas encore prête à être testée.

Cela débloque automatiquement l'étape suivante.

Rendu de l'avertissement d'étape non terminée

Les tags

tags = ["Android", "RAT", "ROM"] : mots-clefs de l'étape.

Les tags représentent les points d'intérêt de votre étape.

C'est utile aux participants pour essayer de filtrer les scénarios qu'ils souhaient faire en fonction de leurs compétences.

Les dépendances

Chaque étape, à l'exception de la première qui est ouverte à tous, doit déclarer une dépendance sur la résolution de l'étape précédente.

  • [[depend]] : dépendance à une autre étape :
    • id = CHID : identifiant de l'étape dont on dépend ;
    • theme = "NomDuTheme" : (facultatif) nom du scénario/thème dans lequel aller chercher l'identifiant (par défaut, on prend le scénario courant) ;

Exemple

[[depend]]
id = 2

Les flags

Retrouvez les différents flags supportés dans [la section dédiée de la documentation]({{< relref "/responses" >}}).

Voici un aperçu des propriétés disponibles :

  • [[flag]] : chaîne de validation pour résoudre l'étape :
    • type = "key" : (facultatif, par défaut "key") type de flag :
      • key : [drapeau classique]({{< relref "/responses/simple.md" >}}),
      • number : [drapeau numérique]({{< relref "/responses/number.md" >}}),
      • vector : [liste de drapeaux]({{< relref "/responses/vector.md" >}}),
      • text : [contenu sur plusieurs lignes]({{< relref "/responses/multiline.md" >}}),
      • mcq : [question à choix multiple]({{< relref "/responses/mcq.md" >}}) (cases à cocher) avec ou sans [justification]({{< relref "/responses/mcq_justified.md" >}}),
      • ucq : [liste de choix]({{< relref "/responses/ucq.md" >}}),
      • label : [texte informatif]({{< relref "/responses/label.md" >}}) qui ne donne pas lieu à validation ;
    • id = 42 : (facultatif) identifiant du flag au sein de l'étape, pour définir des dépendances ;
    • label = "Intitulé" : (facultatif, par défaut : Flag) intitulé du drapeau ;
    • raw = 'MieH2athxuPhai6u' ou raw = ['part1', 'part2'] : drapeau(x) exact(s) à trouver ; sous forme de tableau, le participant n'aura pas connaissaance du nombre d'éléments (à moins de définir l'attribut showlines) ;
    • showlines = false : (facultatif, par défaut : false) lorsque le drapeau est un tableau et que showlines est vrai, le nombre d'éléments du tableau sera donné au participant, sinon il devra déterminer lui-même le nombre d'éléments à trouver (pour l'instant cette option est limitée à un tableau de 9 éléments maximum, c'est normal si ça bug au-delà, demandez-moi si vous avez besoin de plus) ;
    • bonus_gain = 33 : (facultatif) donne des points supplémentaires si complété ;
    • ordered = false : (facultatif, par défaut : false) ignore l'ordre dans lequel les éléments du tableau sont passés ;
    • capture_regexp = "^(?:sudo +)?(.*)$" : (facultatif) expression rationnelle dont les groupes capturés serviront comme chaîne à valider (notez que ?: au début d'un groupe ne le capturera pas) ;
    • casesensitive = true : (facultatif, par défaut : false) prend en compte la casse de ce drapeau ;
    • placeholder = "dd/mm/yyyy" : (facultatif) chaîne de caractères initiale placée dans le champ du formulaire, idéale pour donner une indication de format ;
    • help = "Complément" : (facultatif) petit paragraphe placé sous le champ du formulaire, idéal pour donner une indication complémentaire ;
    • unit = "°C" : (facultatif) chaîne de caractères accolée à la fin du champ de texte, idéale pour préciser l'unité liée au contenu demandé ;
    • choices_cost = 42 : (facultatif) coût pour afficher les choix : avant l'affichage, se comporte comme un drapeau key classique (à 0, les choix sont affichés directement)
    • noshuffle = true : (facultatif, par défaut false) conserve l'ordre des propositions, au lieu de les mélanger ;
    • need_flags = [1, 2, 3] : (facultatif) indique les identifiants des flags qui doivent être validés pour débloquer ce flag ;
    • [[flag.choice]] : représente un choix, répétez autant de fois qu'il y a de choix (pour les mcq et ucq) :
      • label = "Intitulé de la réponse" (facultatif, par défaut raw),
      • value = true (facultatif, par défaut false, sauf si raw est précisé) : valeur attendue pour ce choix,
      • raw = "Justification" (nécessaire pour un [QCM justifié]({{< relref "/responses/mcq_justified.md" >}})) : utilisez une chaîne de caractères (notez qu'il n'est pas possible de combiner des réponses vraies justifiées et non justifiées),
      • help = "Flag correspondant" : (facultatif) indication affichée dans le champ de texte des QCM justifiés,
      • ... toutes les autres propriétés applicables à un flag simple peuvent être utilisées : ordered, capture_regexp, casesensitive, ... ;

Dépendances entre flags

Un flag peut avoir une dépendance sur l'état de validation d'un ou plusieurs autres flags.

Il convient de déclarer la dépendance au sein du [[flag]] qui porte la dépendance. Soit :

  • [[flag.need_flag]] : liste des flags devant être validés avant de débloquer celui-ci :
    • id = 23 : identifiant du flag tel qu'il a été défini plus tôt dans le fichier.

Ou bien simplement en ajoutant un attribut au flag :

[[flag]]
id = 42
...
need_flags = [ 1, 2, 3 ]

Dans ce dernier exemple, le flag ne sera visible au participant qu'après qu'il ait validé les flags d'identifiant 1, 2 et 3.

Débloquage de fichier

Un fichier peut n'être dévoilé qu'après qu'un flag ait été validé.

Il convient de déclarer le débloquage au sein du [[flag]] qui, une fois validé, débloquera le-dit fichier.

  • [[flag.unlock_file]] : bloque l'accès à un fichier tant que le flag n'est pas obtenu :
    • filename = "toto.txt" : nom du fichier tel qu'il apparaît dans le dossier files.

Les indices

Les étapes peuvent avoir des indices, sous forme de fichier à télécharger (avec un attribut filename) ou sous forme de texte (attribut content) :

  • [[hint]] : paramètres pour un indice :
    • filename = "toto.txt" : (mutuellement exclusif avec content) nom du fichier tel qu'il apparaît dans le dossier files ;
    • content = "Contenu de l'indice" : (mutuellement exclusif avec filename) contenu de l'indice affiché, en markdown ;
    • cost = 10 : (facultatif, par défaut 1/4 des gains de l'étape) coût de l'indice ;
    • title = "Foo Bar" : (facultatif, par défaut "Astuce $id") titre de l'astuce dans l'interface ;
    • [[hint.need_flag]] : liste des flags devant être validés pour débloquer cet indice :
      • id = 23 : identifiant du flag ;

Les fichiers

Tous les fichiers sont importés par défaut, voir [la page concernée]({{< relref "/files/files.md" >}}). Cependant il peut être nécessaire de préciser certains attributs. Cela se fait alors avec :

  • [[file]] : paramètres pour un indice :
    • filename = "toto.txt" : nom du fichier tel qu'il apparaît dans le dossier files ;
    • hidden = true : indique si le fichier doit être caché aux participants par défaut (l'équipe serveur pourra le distribuer si besoin, dans tous les cas il sera affiché lorsque le challenge sera archivé) ;
    • disclaimer = "**Ne pas exécuter**" : ajoute un avertissement supplémentaire lors du téléchargement du fichier (Markdown interprété) ;

Exemple d'un challenge.txt complet

gain = 42

[[depend]]
id = 2

[[file]]
filename = "btmp.log"
hidden = true

[[flag]]
label = "Date d'exfiltration"
placeholder "yyyy-mm"
raw = '2015-12'

[[flag]]
label = "IPv6 d'exfiltration"
raw = 'fe80::319c:1002:7c60:68fa'

[[flag]]
id = 2
type = "mcq"
label = "Conditions générales de validation de challenge"
raw = 'conscent'

  [[flag.choice]]
  label = "J'accepte les conditions"
  value = 'conscent'

[[flag]]
type = "ucq"
label = "Quelle est la couleur du cheval blanc d'Henri IV ?"
raw = 'blanc'
choices_cost = 21

  [[flag.choice]]
  value = 'Noir'

  [[flag.choice]]
  label = 'Roux'
  value = 'Alezan'

  [[flag.choice]]
  label = 'Brun'
  value = 'Alezan'

  [[flag.choice]]
  label = "Crème"
  value = 'Blanc'

  [[flag.need_flag]]
  id = 2

[[flag]]
type = "mcq"
label = "Quels sont les films réalisés par C. Nolan ?"

  [[flag.choice]]
  label = "Memento"
  value = true

  [[flag.choice]]
  label = "Inception"
  value = true

  [[flag.choice]]
  label = "Transcendance"

[[hint]]
filename = 'enocean-specs.pdf'
title = "Spécifications du protocole utilisé"

[[hint]]
content = """
Le TOML c'est magique.
Je peux avoir des chaînes de caractères sur plusieurs lignes !
"""
title = "L'astuce du siècle"
cost = 30