Comment publier une application sur Scoop
Dans le cadre d’expérimentation et d’apprentissage de scans de vulnérabilités, j’ai voulu installer Nuclei.
Il existe différentes méthodes d’installation, mais celle que je préfère n’est pas disponible: l’installation via Scoop.
En effet, personne n’a encore fait le nécessaire pour ajouter cet outil dans un dépôt Scoop. On va donc s’en occuper, et apprendre par la même occasion comment procéder.
L’app manifest
Tout d’abord, il faut retenir qu’une application Scoop = un fichier “app manifest”.
Il s’agit d’un fichier JSON qui contiendra toute les informations nécessaires pour télécharger et installer l’application que l’on souhaite.
Voyons voir quelles informations sont requises:
- La version actuelle
- Une brève description
- Le lien du site officiel
- La licence
- Le ou les liens de téléchargement, en fonction de l’architecture disponible, avec leurs hashes (pour s’assurer de l’intégrité des données téléchargées)
Nuclei étant un outil qui s’utilise en ligne de commande, nous allons aussi spécifier le paramètre “bin” pour ajouter notre executable dans notre PATH et pouvoir ainsi l’exécuter dans notre terminal, peu importe ou l’on se situe.
Cela nous donne pour le moment:
{
"version": "3.2.8",
"description": "Fast and customizable vulnerability scanner based on simple YAML based DSL.",
"homepage": "https://github.com/projectdiscovery/nuclei",
"license": "MIT",
"architecture": {
"64bit": {
"url": "https://github.com/projectdiscovery/nuclei/releases/download/latest/nuclei_3.2.8_windows_amd64.zip",
"hash": "a7fc946b6d1b7ed8707d65e257c04f34df0758c02acb00607430c644ad941a60"
},
"32bit": {
"url": "https://github.com/projectdiscovery/nuclei/releases/download/latest/nuclei_3.2.8_windows_386.zip",
"hash": "f575d116c56d9aae60edccfd638e3a381f75bee1770f2ec0bf16129e0623651e"
}
},
"bin": "nuclei.exe"
}
Comme vous le constatez, on spécifie une version.
Cela implique que lors des installations futures, cette version précise sera installée, hors on veut toujours installer la derniere release.
Mettre à jour manuellement tout les manifest est long et fastidieux, mais nous allons pouvoir automatiser tout ça.
Pour ce faire nous allons ajouter quelques clés optionnelles qui permettent au manifest de modifier automatiquement les données pour y inclure la dernière version.
Il faut ajouter une clé “checkver”, qui servira à indiquer où chercher le numéro de la nouvelle version.
Dans notre cas, le projet Nuclei étant hébérgé sur Github, Scoop sait aller chercher cette information tout seul. On a juste à indiquer “github”.
{
...
"checkver": "github"
}
Autrement, il aurait fallu indiquer une URL d’une page web qui contient la nouvelle version et une regex pour extraire le numéro de version.
Ensuite, il faut indiquer comment retrouver le hash du dernier .zip.
Par défaut, Scoop utilise ces 2 expressions régulières pour récuperer le hash:
// Regex: ^([a-fA-F0-9]+)$
abcdef0123456789abcdef0123456789abcdef01
// Regex: ([a-fA-F0-9]{32,128})[\x20\t]+.*`$basename(?:[\x20\t]+\d+)?
abcdef0123456789abcdef0123456789abcdef01 example.zip
$basename est une variable (automatiquement injectée par Scoop) correspondante au nom du fichier, extrait de l’URL
Dans notre cas pour Nuclei, le fichier des hashes se présente sous la forme suivante:
f12a37426738661ffb183473b8b074c4a46644a1e206ff2f4c041cd02cfa2a21 nuclei_3.2.8_linux_386.zip
2f6a1e527a7d78dcd768f7939d25601138e66703f6581d36b6d49e049185262d nuclei_3.2.8_linux_amd64.zip
fb2914eb71f1288060b1739ee1fa6d66eaec743b1fe96079d767bee4a35c146c nuclei_3.2.8_linux_arm.zip
3c8caa2b93cb02253eb95321d832de569392550391075a46915f7cea40b6f2a1 nuclei_3.2.8_linux_arm64.zip
6cc75baa107488288d95dc35cc4d5c4573d8179353f6373c10b5a41890c761ac nuclei_3.2.8_macOS_amd64.zip
11c6b980b30d8e9ca492189db8f1384cfc7f613871f83ad1977896d7238aff5a nuclei_3.2.8_macOS_arm64.zip
f575d116c56d9aae60edccfd638e3a381f75bee1770f2ec0bf16129e0623651e nuclei_3.2.8_windows_386.zip
a7fc946b6d1b7ed8707d65e257c04f34df0758c02acb00607430c644ad941a60 nuclei_3.2.8_windows_amd64.zip
On constate que la seconde regex est parfaitement adaptée: on n’aura donc pas besoin d’en spécifier une.
Dans votre cas, si vous avez besoin d’une regex custom, je conseille 101regex.com, un excellent site pour se fabriquer des regex sur mesure et les tester en direct.
Au final, voici notre fichier au complet:
{
"version": "3.2.8",
"description": "Fast and customizable vulnerability scanner based on simple YAML based DSL.",
"homepage": "https://github.com/projectdiscovery/nuclei",
"license": "MIT",
"notes":[
"This is only the Nuclei tool by itself.",
"You may want to install the Nuclei templates:",
"run: nuclei "
],
"architecture": {
"64bit": {
"url": "https://github.com/projectdiscovery/nuclei/releases/download/latest/nuclei_3.2.8_windows_amd64.zip",
"hash": "a7fc946b6d1b7ed8707d65e257c04f34df0758c02acb00607430c644ad941a60"
},
"32bit": {
"url": "https://github.com/projectdiscovery/nuclei/releases/download/latest/nuclei_3.2.8_windows_386.zip",
"hash": "f575d116c56d9aae60edccfd638e3a381f75bee1770f2ec0bf16129e0623651e"
}
},
"bin": "nuclei.exe",
"checkver": "github",
"autoupdate": {
"architecture": {
"64bit": {
"url": "https://github.com/projectdiscovery/nuclei/releases/download/latest/nuclei_$version_windows_amd64.zip",
"hash": {
"url": "$baseurl/nuclei_$version_checksums.txt"
}
},
"32bit": {
"url": "https://github.com/projectdiscovery/nuclei/releases/download/latest/nuclei_$version_windows_386.zip",
"hash": {
"url": "$baseurl/nuclei_$version_checksums.txt"
}
}
}
}
}
Il n’y a pas de dépendence pour Nuclei, mais si c’était le cas il aurait fallu ajouter une clé “depends”:
{
...
"depends":["dependance1", "dependance2"]
}
L’ajout de l’app manifest à notre bucket personnel
On va créer sur Github un nouveau dépôt.
Le mien sera à l’adresse suivante: https://github.com/Adamatt/AdamattBucket
On se place dans le dossier “buckets” de scoop puis on fait un petit coup de
git clone https://github.com/Adamatt/AdamattBucket
cd AdamattBucket
git add nuclei.json
git commit -m "Adding nuclei"
git push
Et nous avons notre bucket créé avec notre premier manifest !
Si pour X raison vous n’avez pas cloné le projet directement dans le dossier “buckets”, il faudra au préalable l’ajouter avec la commande
scoop bucket add AdamattBucket https://github.com/Adamatt/AdamattBucket
On peut maintenant installer nuclei:
scoop install AdamattBucket/nuclei
Si vous ne souhaitez pas publier votre bucket, il est tout à fait possible de rester en local. Il faudra simplement mettre tout vos fichiers manifest dans un dossier qui portera le nom de votre bucket local, dans le dossier “buckets”. Par ex: C:\Users\votreuser\scoop\buckets\MonBucketPerso\myApp.json
Vous pourrez alors installer l’application de la même manière en utilisant “scoop install MonBucketPerso/myApp.json”
L’ajout de l’app manifest au dépôt officiel
On va en profiter également pour faire une petite demande chez nos amis de Scoop pour ajouter ce manifest dans le bucket principal.
On va donc forker le projet et créer une nouvelle branche.
Comme beaucoup de projets open-source, pour pouvoir contribuer on nous demande de respecter des conventions. Voici les indications qu’on doit respecter:
-
Les clés doivent être spécifiée dans l’ordre suivant:
version description homepage license notes depends suggest architecture url hash extract_dir extract_to pre_install installer post_install env_add_path env_set bin shortcuts persist pre_uninstall uninstaller post_uninstall checkver autoupdate
-
L’indentation de la tabulation doit correspondre à 4 espaces.
-
La licence doit être un identifiant SPDX valide.
-
Il faut privilégier les configurations portable (by using persist).
-
Si c’est une application en ligne de commande, il ne faut pas l’ajouter aux raccourcis windows.
-
Si c’est une application avec interface graphique, il ne faut pas l’ajouter au PATH (donc ne pas inclure la clé “bin”).
-
Si un tableau contient un seul élément, il faut plutôt l’écrire en tant que chaîne de caractère directement.
-
Il faut tester notre app manifest en l’installant / désinstallant / essayant les fonctionnalités et la persistence des données si besoin etc…
-
Il faut que notre app manifest se mette à jour correctement
Si tout ces règles sont respectées, on peut alors ouvrir une pull request sur Github en veillant à ce que le titre soit
“Use <nom de l’application>: Add version
”
Il faudra aussi commenter immédiatement cette PR avec “/verify” afin de déclencher une première vérification automatique de l’app manifest avec leur bot.
Mettre à jour
Maintenant que le fichier manifest est terminé et le bucket créé, nous pouvons utiliser la commande “checkver” de scoop pour vérifier si une mise à jour existe pour notre application.
Pour cela, il faut se placer dans le dossier scoop\apps\scoop\current et exécuter la commande checkver avec le nom de l’application et le chemin de notre bucket:
.\bin\checkver.ps1 -a nuclei -d C:\Users\votreuser\scoop\buckets\AdamattBucket -u
Le script va automatiquement modifier notre fichier manifest pour y remplacer la version par la dernière.
On pourra ensuite aller dans le dossier du bucket et push notre manifest mis à jour avec un
git add nuclei.json
git commit -m "Update nuclei"
git push
Il suffira alors d’actualiser le bucket avec
scoop update
Et lors du prochain “scoop install nuclei”, nous aurons bien la dernière version.