Finish documentation

This commit is contained in:
nemunaire 2019-07-05 18:13:19 +02:00
parent 8bc7019ebb
commit 2ff2b7d8a0
27 changed files with 305 additions and 72 deletions

View File

@ -74,6 +74,8 @@ un autre service qu'unsplash.
La taille et l'orientation de l'image n'a pas d'importance, mais gardez en tête
que c'est son centre qui sera affiché, si la hauteur dépasse la taille prévue.
![Rendu heading.jpg](scenario_heading.png)
### `overview.txt`
@ -96,6 +98,10 @@ Le chemin *doit* être un chemin _absolu_ vers l'image, considérant la racine
comme étant le dossier du scémario (pour l'overview du thème) ou de l'exercice
(pour les autres textes).
![Rendu overview.txt](scenario_overview_public.png)
![Rendu overview.txt](scenario_headline.png)
## Fichiers pour un défi
@ -113,6 +119,8 @@ Comme l'ensemble des textes importés, vous pouvez utiliser du
[Markdown](https://daringfireball.net/projects/markdown/) pour mettre en forme
vos textes.
![Rendu finished.txt](exercice_finished.png)
### `links.txt`
@ -137,6 +145,10 @@ affichées au public : il s'agit à la fois d'aguicher le participant pour qu'il
fasse votre scénario plutôt que celui d'un autre groupe, mais aussi de donner
envie au public de lire plus en détail.
![Rendu overview.txt](exercice_overview_public.png)
![Rendu overview.txt](exercice_headline.png)
### `resolution.mp4`
@ -157,6 +169,8 @@ Comme l'ensemble des textes importés, vous pouvez utiliser du
[Markdown](https://daringfireball.net/projects/markdown/) pour mettre en forme
vos textes.
![Rendu statement.txt](exercice_statement.png)
### `files/`

View File

@ -10,39 +10,31 @@ weight: 20
- `[[depend]]` : dépendance à un autre exercice :
* `id = CHID` : identifiant du challenge ;
* `theme = "NomDuTheme"` : (facultatif) nom du thème dans lequel aller chercher l'identifiant (par défaut, on prend le thème courant) ;
- `[[flag]]` : drapeau classique à valider pour résoudre le challenge :
- `[[flag]]` : chaîne de validation pour résoudre le challenge :
* `type = "key"` : (facultatif, par défaut "key") type de flag :
+ `key` : [drapeau classique]({{< relref "/responses/simple.md" >}}),
+ `vector` : [liste de drapeaux]({{< relref "/responses/vector.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" >}}) ;
* `id = 42` : (facultatif) identifiant du flag au sein de l'exercice, pour définir des dépendances ;
* `label = "Intitulé"` : (facultatif, par défaut : `Flag`) intitulé du drapeau ;
* `raw = 'MieH2athxuPhai6u'` ou `raw = ['part1', 'part2']` : drapeau exact à trouver ; sous forme de tableau, le participant n'aura pas connaissaance du nombre d'éléments ;
* `validator_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) ;
* `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 ;
* `ordered = false` : (facultatif, par défaut : `false`) ignore l'ordre dans lequels les éléments du tableau sont passés ;
* `ignorecase = true` : (facultatif, par défaut : `false`) ignore la case de ce drapeau ;
* `validator_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 case de ce drapeau ;
* `help = "Indication"` : (facultatif) chaîne de caractères placée sous le champ du formulaire, idéale pour donner une indication de format ;
* `choice_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 ;
* `[[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` ;
* `[[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 ;
- `[[flag_mcq]]` : drapeau sous forme de question à choix multiple (cases à cocher) :
* `label = "Intitulé du groupe"` : (facultatif) intitulé du groupe de choix ;
* `[[flag_mcq.choice]]` : représente un choix, répétez autant de fois qu'il y a de choix :
* `[[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"`,
+ `value = true` : (facultatif, par défaut `false`) valeur attendue pour ce choix ; pour un QCM justifié, utilisez une chaîne de caractères (notez qu'il n'est pas possible de combiner des réponses vraies justifiées et justifiées),
+ `help = "Flag correspondant"` : (facultatif) indication affichée dans le champ de texte des QCM justifiés ;
- `[[flag_ucq]]` : drapeau sous forme de question à choix unique :
* `id = 42` : (facultatif) identifiant du flag au sein de l'exercice, pour définir des dépendances ;
* `label = "Intitulé du groupe"` : (facultatif) intitulé du groupe de choix ;
* `raw = 'MieH2athxuPhai6u'` : drapeau attendu parmi les propositions ;
* `validator_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) ;
* `help = "Indication"` : (facultatif, uniquement si `displayAs = select`) chaîne de caractères placée sous le champ du formulaire ;
* `displayAs = "select|radio"` : (facultatif, par défaut `radio`) manière dont est affichée le choix : `select` pour une liste de choix, `radio` pour des boutons radios ;
* `choices_cost = 20` : (facultatif, par défaut `0`) coût pour afficher les choix, avant l'affichage, se comporte comme un `flag` classique (à 0, les choix sont affichés directement) ;
* `[[flag_ucq.choice]]` : représente un choix, répétez autant de fois qu'il y a de choix :
+ `value = "response"` : valeur qui sera retournée pour comparaison avec la valeur `raw` du ucq,
+ `label = "Intitulé de la réponse"` : (facultatif, par défaut identique à `value`) ;
* `[[flag_ucq.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` ;
* `[[flag_ucq.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 ;
+ `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`, `validator_regexp`, `casesensitive`, ... ;
- `[[hint]]` : paramètres pour un indice :
* `filename = "toto.txt"` : (mutuellement exclusif avec `content`) nom du fichier tel qu'il apparaît dans le dossier `hints` ;
* `content = "Contenu de l'indice"` : (mutuellement exclusif avec `filename`) contenu de l'indice affiché, en markdown ;
@ -53,7 +45,7 @@ Voir aussi [la section sur les flags]({{< relref "/responses" >}}).
## Exemple
```
```toml
gain = 42
[[depend]]
@ -67,49 +59,52 @@ raw = '2015-12'
[[flag]]
label = "IPv6 d'exfiltration"
raw = 'fe80::319c:1002:7c60:68fa'
ignorecase = true
casesensitive = false
[[flag_ucq]]
[[flag]]
type = "mcq"
label = "Conditions générales de validation de challenge"
raw = 'conscent'
[[flag_ucq.choice]]
[[flag.choice]]
label = "J'accepte les conditions"
value = 'conscent'
[[flag_ucq]]
[[flag]]
type = "ucq"
label = "Quelle est la couleur du cheval blanc d'Henri IV ?"
raw = 'blanc'
ignorecase = true
displayAs = "select"
casesensitive = false
choice_cost = 21
[[flag_ucq.choice]]
[[flag.choice]]
value = 'Noir'
[[flag_ucq.choice]]
[[flag.choice]]
label = 'Roux'
value = 'Alezan'
[[flag_ucq.choice]]
[[flag.choice]]
label = 'Brun'
value = 'Alezan'
[[flag_ucq.choice]]
[[flag.choice]]
label = "Crème"
value = 'Blanc'
[[flag_mcq]]
[[flag]]
type = "mcq"
label = "Quels sont les films réalisés par C. Nolan ?"
[[flag_mcq.choice]]
[[flag.choice]]
label = "Memento"
value = true
[[flag_mcq.choice]]
[[flag.choice]]
label = "Inception"
value = true
[[flag_mcq.choice]]
[[flag.choice]]
label = "Transcendance"
[[hint]]
@ -124,6 +119,3 @@ Je peux avoir des chaînes de caractères sur plusieurs lignes !
title = "L'astuce du siècle"
cost = 30
```
## Rendu

View File

@ -21,7 +21,7 @@ l'arborescence n'a pas été altérée et que les fichiers servis sont bien les
mêmes que sur vos dépôts Git.
{{% /notice %}}
La commande `b2sum` fait parti des *GNU Core Utilities* depuis la [version
La commande `b2sum` fait partie des *GNU Core Utilities* depuis la [version
8.26](https://github.com/coreutils/coreutils/commit/ea94589e9ef02624a3837f97f80efd7d3dcf56bf).
L'algorithme [blake2b](https://blake2.net/) est utilisé à la place d'un SHA-1
@ -43,3 +43,7 @@ nécessaire.
023939b0c52b0dfce66954318ab82f7a8c10af4c79c8d5781612b58c74f3ace056067d7b15967e612b176a186b46d3d900c4db8881ba47202521eec33e5bb87b fic.org
7c91450239cf9b0717642c55c3429dd7326db26e87d4ca198758053333f0640ee89d2dd9b2f1919598f89644b06aa8fc2085648e3d1e542a6db324c9b16a0bdf header.tex
```
## Rendu
![Rendu fichiers](exercice_files.png)

View File

@ -4,11 +4,26 @@ title: resolution.mp4
weight: 35
---
+ `resolution.mp4` : la vidéo de résolution, montée :
- format MP4 (H.264 + AAC + 3GPP Timed Text)
- utiliser les sous-titres pour commenter les étapes ; pas de commentaires audio
- environ 2' par vidéo : maxi 1'30" pour les challenges simples, 3-4' maxi
- `ffmpeg -video_size 1920x1080 -framerate 25 -f x11grab -i :0.0 -f alsa -ac 2 -i hw:0 -strict experimental resolution.mp4`
- [recordMyDesktop](http://recordmydesktop.sourceforge.net/) sous Linux
- [Screencast Capture Lite](http://cesarsouza.github.io/screencast-capture/) pour Windows (pas de logiciel de « démonstration » => il faut payer la licence pour publier une vidéo)
- [Aegisub](http://www.aegisub.org/), [Gnome Subtitle](http://gnomesubtitles.org/), emacs/vim, ... pour les sous-titres
Ce fichier doit contenir la vidéo de résolution, montée selon ces caractéristiques :
- format MP4 (H.264 + AAC + 3GPP Timed Text)
- utiliser les sous-titres pour commenter les étapes ; pas de commentaires audio
- environ 2' par vidéo : maxi 1'30" pour les challenges simples, 3-4' maxi
## Exemple de logiciel de capture d'écran
{{% notice warning %}}
N'utilisez pas de logiciel en version de « démonstration » : il faudrait payer la licence pour publier la vidéo.
{{% /notice %}}
- `ffmpeg -video_size 1920x1080 -framerate 25 -f x11grab -i :0.0 -f alsa -ac 2 -i hw:0 -strict experimental resolution.mp4`
- [recordMyDesktop](http://recordmydesktop.sourceforge.net/) sous Linux
- [Screencast Capture Lite](http://cesarsouza.github.io/screencast-capture/) pour Windows
- [Aegisub](http://www.aegisub.org/), [Gnome Subtitle](http://gnomesubtitles.org/), emacs/vim, ... pour les sous-titres
## Rendu
Les vidéos de résolution sont affichées uniquement sur la version du site statique, publiée après le challenge.
![Rendu resolution.mp4](exercice_resolution.png)

View File

@ -11,6 +11,7 @@ Choisissez-les en faisant en sorte qu'il ne puisse pas y avoir d'ambiguïté, to
De nombreux type de flag sont à votre disposition :
* [simple]({{< relref "/responses/simple.md" >}}) ;
* [liste de flags]({{< relref "/responses/vector.md" >}}) ;
* [QCM]({{< relref "/responses/mcq.md" >}}) ;
* [QCM avec justification]({{< relref "/responses/mcq_justified.md" >}}) ;
* [liste de choix]({{< relref "/responses/ucq.md" >}}).

View File

@ -4,11 +4,34 @@ title: QCM
weight: 10
---
{{% notice note %}}Ébauche à compléter
{{% /notice %}}
Ce type de flag est approprié pour suggérer aux participants différentes propositions parmi lesquelles il devra déterminer si elles sont vraies ou fausses.
Lors de la résolution de ce type de flag, le nombre de différences d'état des cases à cocher est affiché (type Mastermind).
# Propriétés
### Exemple
```toml
[[flag]]
type = "mcq"
label = "Fichiers exfiltrés :"
[[flag.choice]]
label = "Documents PDF"
[[flag.choice]]
label = "Tableurs Excel"
value = true
[[flag.choice]]
label = "Image PNG"
value = true
```
## Propriétés
type
: `"mcq"`
id
: (facultatif) identifiant du flag au sein de l'exercice, pour définir des dépendances ;
@ -21,3 +44,20 @@ noshuffle
help
: (facultatif) chaîne de caractères placée sous le champ du formulaire, idéale pour donner une indication de format ;
## Propriétés des choix
id
: (facultatif) identifiant du flag au sein de l'exercice, pour définir des dépendances ;
label
: intitulé du choix ;
value
: (facultatif, par défaut : `false`) état attendue de la case à cocher pour ce choix (`true` = coché, `false` = décoché).
## Rendu
![Rendu flag QCM](flag.png)

View File

@ -4,11 +4,39 @@ title: QCM justifiés
weight: 15
---
{{% notice note %}}Ébauche à compléter
{{% /notice %}}
Ce type de flag est précaunisé pour orienter les participants lorsqu'il faut trouver beaucoup de flags. Il devra déterminer si chacune est vraie ou fausse, puis pour les proposition qu'il juge vraies, apporter un élément de justification.
Lors de la résolution de ce type de flag, le nombre de différences d'état des cases à cocher est affiché (type Mastermind).
La résolution de ce flag peut se faire en deux étapes : lorsque le participant a trouvé tous les choix vrais dans le QCM (sans pour autant avoir les bonnes justifications), les choix sont alors verrouillés et des informations supplémentaires sur les justifications sont affichées.
### Exemple
```toml
[[flag]]
type = "mcq"
label = "Fichiers exfiltrés :"
[[flag.choice]]
label = "Documents PDF"
[[flag.choice]]
label = "Tableurs Excel"
raw = "Salaires09.xls"
help = "Indication utile si besoin"
casesensitive = true
[[flag.choice]]
label = "Image PNG"
raw = "heading.png"
casesensitive = true
```
# Propriétés
## Propriétés
type
: `"justified"`
id
: (facultatif) identifiant du flag au sein de l'exercice, pour définir des dépendances ;
@ -21,3 +49,33 @@ noshuffle
help
: (facultatif) chaîne de caractères placée sous le champ du formulaire, idéale pour donner une indication de format ;
## Propriétés des choix
id
: (facultatif) identifiant du flag au sein de l'exercice, pour définir des dépendances ;
label
: intitulé du choix ;
raw
: [drapeau]({{< relref "/responses/simple.md" >}}) ou [tableau de drapeaux]({{< relref "/responses/vector.md" >}}) exact à trouver ;
validator_regexp
: (facultatif) [expression rationnelle]({{< relref "/responses/simple.md#flag-modulable" >}}) dont les groupes capturés serviront comme chaîne à valider (notez que `?:` au début d'un groupe ne le capturera pas) ;
casesensitive
: (facultatif, par défaut : `false`) prend en compte la la casse de ce drapeau lors de la validation ;
ordered
: (facultatif, par défaut : `false`) ignore l'ordre dans lequels les éléments du tableau sont passés ;
help
: (facultatif) chaîne de caractères placée dans le champ du formulaire avant la frappe (*placeholder*), idéale pour donner une indication de format ;
## Rendu
![Rendu flag QCM justifié](flag.png)

View File

@ -17,7 +17,7 @@ casse[^gocase].
### Exemple
```
```toml
[[flag]]
label = "IPv6 d'exfiltration"
raw = 'fe80::319c:1002:7c60:68fa'
@ -36,7 +36,7 @@ casse lors de la vérification du flag.
### Exemple
```
```toml
[[flag]]
label = "Mot de passe du compte"
raw = 'rech1aichoh2Tei1ohHe'
@ -55,7 +55,7 @@ casse.
Si par exemple, on estime que plusieurs réponses sont correctes (ici, plusieurs secondes) :
```
```toml
[[flag]]
label = "Heure de l'exfiltration"
raw = '11:22:33+02:00'
@ -63,7 +63,7 @@ validator_regexp = "([0-9]{1,2}):([0-9]{1,2}):[0-9]{1,2}"
```
# Propriétés
## Propriétés
id
: (facultatif) identifiant du flag au sein de l'exercice, pour définir des dépendances ;
@ -72,16 +72,18 @@ label
: (facultatif, par défaut : `Flag`) intitulé du drapeau ;
raw
: drapeau exact à trouver ; sous forme de tableau, le participant n'aura pas connaissaance du nombre d'éléments ;
: drapeau exact à trouver ; sous [forme de tableau]({{< relref "/responses/vector.md" >}}), le participant n'aura pas connaissaance du nombre d'éléments ;
validator_regexp
: (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) ;
ordered
: (facultatif, par défaut : `false`) ignore l'ordre dans lequels les éléments du tableau sont passés ;
: (facultatif) [expression rationnelle]({{< relref "/responses/simple.md#flag-modulable" >}}) dont les groupes capturés serviront comme chaîne à valider (notez que `?:` au début d'un groupe ne le capturera pas) ;
casesensitive
: (facultatif, par défaut : `false`) prend en compte la la casse de ce drapeau lors de la validation ;
help
: (facultatif) chaîne de caractères placée sous le champ du formulaire, idéale pour donner une indication de format ;
: (facultatif) chaîne de caractères placée dans le champ du formulaire avant la frappe (*placeholder*), idéale pour donner une indication de format ;
## Rendu
![Rendu flag simple](flag.png)

View File

@ -4,11 +4,13 @@ title: Liste de choix
weight: 20
---
{{% notice note %}}Ébauche à compléter
{{% /notice %}}
Ce type de flag s'utilise pour valider une réponse que le participant aurait du mal à écrire correctement ou à déterminer sans avoir plus d'indications. C'est notamment le cas pour les numéros de CVE (la liste de choix permet alors de recentrer les recherches à effectuer), ou les types de *payloads* : comme chacun peut avoir sa façon d'écrire ou de nommer une charge malveillante.
# Propriétés
## Propriétés
type
: `"ucq"`
id
: (facultatif) identifiant du flag au sein de l'exercice, pour définir des dépendances ;
@ -17,7 +19,7 @@ label
: (facultatif, par défaut : `Flag`) intitulé du drapeau ;
raw
: drapeau exact à trouver ; sous forme de tableau, le participant n'aura pas connaissaance du nombre d'éléments ;
: drapeau exact à trouver ; forme de [tableau]({{< relref "/responses/vector.md" >}}) possible, mais déconseillée ;
validator_regexp
: (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) ;
@ -32,4 +34,52 @@ help
: (facultatif) chaîne de caractères placée sous le champ du formulaire, idéale pour donner une indication de format ;
choice_cost
: (facultatif) coût pour afficher les choix : avant l'affichage, se comporte comme un `flag` classique (à 0, les choix sont affichés directement) ;
: (facultatif, par défaut 0) coût pour afficher les choix : avant l'affichage, se comporte comme un `flag` classique (si `choice_cost` = 0, les choix sont affichés directement) ;
## Propriétés des choix
label
: (facultatif, par défaut `value` est utilisé) intitulé du choix ;
value
: valeur envoyé par le formulaire de validation lorsque le choix est sélectionné.
### Exemple
```toml
[[flag]]
type = "ucq"
label = "Type de malware"
validator_regexp = "^.*(dropper).*$"
raw = "Il installe quelque chose à son tour ! Il s'agit d'un dropper."
choices_cost = 25
[[flag.choice]]
value = "Il exécute arbitrairement une commande passée en paramètre par un botnet !"
[[flag.choice]]
value = "Un évènement est déclenché à un temps précis ! Il s'agit d'un logic-bomb !"
[[flag.choice]]
value = "Il supprime tout dans le disque."
[[flag.choice]]
value = "Il installe quelque chose à son tour ! Il s'agit d'un dropper."
[[flag.choice]]
value = "Il communique avec un autre ordinateur à distance."
```
## Rendu
![Rendu flag UCQ](flag.png)
### Rendu avec `choice_cost > 0`
![Rendu flag UCQ](flag_locked.png)
Le participant a la possibilité d'écrire lui-même le type de malware dans un premier temps, mais s'il n'y arrive pas, il peut dépenser 25 points pour obtenir une liste de choix.

View File

@ -0,0 +1,57 @@
---
date: 2019-04-05T15:59:52+02:00
title: Liste de flags
weight: 7
---
Ce type de flag s'utilise pour valider plusieurs chaînes de caractères liées au même flag.
Par exemple, s'il faut trouver une liste d'administrateurs, les IP appartenant à un botnet, les fichiers infectés, ...
Attention, par défaut, les propositions ne sont pas sensible à la casse[^gocase].
[^gocase]: Casse selon les classes Unicode de charactères, ce ne concerne pas
que l'alphabet traditionnel. Pour plus d'infos, consultez la [documentation
de la fonction utilisée](https://golang.org/pkg/bytes/#ToLower).
### Exemple
```toml
[[flag]]
label = "IPv6 du botnet"
raw = ['fe80::319c:1002:7c60:68fa', 'fe80::319c:1002:7c60:68fb', 'fe80::319c:1002:7c60:68fc', 'fe80::319c:1002:7c60:68fd' ]
```
Il convient de lister toutes les IP du botnet, l'ordre importe peut, donc on ne précise pas la propriété `ordered` ; la case d'un IP n'a pas non plus d'importance, donc on laisse la propriété `casesensitive` à sa valeur par défaut.
## Propriétés
type
: `"vector"`
id
: (facultatif) identifiant du flag au sein de l'exercice, pour définir des dépendances ;
label
: (facultatif, par défaut : `Flag`) intitulé du drapeau ;
raw
: tableau TOML de drapeaux exacts à trouver ; sous forme de tableau, le participant n'aura pas connaissaance du nombre d'éléments ;
validator_regexp
: (facultatif) [expression rationnelle]({{< relref "/responses/simple.md#flag-modulable" >}}) dont les groupes capturés serviront comme chaîne à valider (notez que `?:` au début d'un groupe ne le capturera pas) ; Attention, la regexp est appliquée seulement sur la représentation de la chaîne de caractères obtenue, pas sur chaque élément.
ordered
: (facultatif, par défaut : `false`) ignore l'ordre dans lequels les éléments du tableau sont passés ;
casesensitive
: (facultatif, par défaut : `false`) prend en compte la la casse des drapeaux lors de la validation ;
help
: (facultatif) chaîne de caractères placée sous le champ du formulaire, idéale pour donner une indication de format ;
## Rendu
![Rendu list de flag](flag.png)
Dans cet exemple, on demande explicitement que les IP soient listées dans l'ordre, on aura pris soin d'ajouter `ordered = true`.

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB