
P4wnP1 A.L.O.A. par MaMe82 est un framework qui transforme un Raspberry Pi Zero W en une plateforme flexible et peu coûteuse pour le pentesting, le red teaming et les engagements physiques... ou en « A Little Offensive Appliance ».
P4wnP1 A.L.O.A. par MaMe82 est un framework qui transforme un Raspberry Pi Zero W en une plateforme flexible et peu coûteuse pour le pentesting, le red teaming et les engagements physiques… ou en « A Little Offensive Appliance » (un petit appareil offensif).
La dernière image se trouve sous l’onglet des releases.
La manière la plus simple d’accéder à une installation fraîche de P4wnP1 A.L.O.A. est d’utiliser le client web via le WiFi généré (le PSK est MaMe82-P4wnP1, l’URL http://172.24.0.1:8000) ou SSH (mot de passe par défaut toor).
Math pour les calculs de souris, etc.)Peu de choses à dire ici, P4wnP1 A.L.O.A. est basé sur KALI Linux, donc tout est à portée de main (ou peut être installé via apt)
Donc, si vous voulez utiliser un fichier batch sur un hôte Windows distant pour configurer P4wnP1… pas de problème :
host à vos commandes clientBien que cela n’ait pas été prévu initialement, P4wnP1 A.L.O.A. peut être configuré à l’aide d’un client web. Même si le client n’était pas prévu, il a évolué pour devenir un joli logiciel. En fait, il est devenu l’outil de configuration principal de P4wnP1 A.L.O.A. Le client web possède des capacités qui ne sont pas accessibles depuis le CLI (stockage de modèles, création de « TriggerActions »).
Les fonctionnalités principales :
CTRL+ESPACE)L’approche d’automatisation de l’ancienne version de P4wnP1 (scripts bash statiques) n’est plus utilisable.
L’approche d’automatisation de P4wnP1 A.L.O.A. devait répondre à ces exigences :
Avec l’introduction des « TriggerActions » et leur combinaison avec le système de modèles (stockage persistant des paramètres pour tous les sous-systèmes), toutes les exigences ont pu être satisfaites. Les détails sur les TriggerActions se trouvent dans la section Workflow.
P4wnP1 A.L.O.A. n’utilise pas de concepts comme une configuration statique ou des payloads. En fait, il n’a aucun workflow statique.
P4wnP1 A.L.O.A. est conçu pour être aussi flexible que possible, afin de pouvoir être utilisé dans tous les scénarios possibles (y compris ceux auxquels je n’aurais pas pensé en créant P4wnP1 A.L.O.A.).
Mais il existe certains concepts de base que j’aimerais aborder dans cette section. Comme il est difficile de tout expliquer sans créer une documentation (vidéo) appropriée, je vais parcourir quelques cas d’usage et exemples courants afin d’expliquer ce qui doit être expliqué.
Néanmoins, il est peu probable que j’aie le temps de fournir une documentation complète. J’encourage donc tout le monde à me soutenir avec des tutoriels et des idées, qui pourraient être liés à ce README.
Commençons maintenant par l’une des tâches les plus basiques :
La configuration minimale requise pour atteindre cet objectif est :
La configuration par défaut de P4wnP1 (image non modifiée) répond déjà à ces exigences :
MaMe82-P4wnP1172.24.0.1172.16.0.1P4wnP11337172.26.0.1root, le mot de passe par défaut est toorRemarque : Déployer une connexion HTTPS ne fait actuellement pas partie du projet. Veuillez donc en tenir compte si vous manipulez des données sensibles, comme des identifiants WiFi, dans le client web. L’ensemble du projet n’est pas conçu dans un souci de sécurité (et il est peu probable que cela devienne une exigence un jour). Veuillez donc déployer les mesures appropriées (par exemple, restreindre l’accès au client web avec iptables si le point d’accès est configuré avec une authentification ouverte ; ne pas laisser la découvrabilité et la connectabilité Bluetooth activées sans protection par PIN, etc.).
À ce stade, je suppose :
Pour exécuter le client CLI depuis la session SSH, émettez la commande suivante :``` root@kali:~# P4wnP1_cli The CLI client tool could be used to configure P4wnP1 A.L.O.A. from the command line. The tool relies on RPC so it could be used remotely.
Version: v0.1.0-alpha1
Usage: P4wnP1_cli [command]
Available Commands: db Database backup and restore evt Receive P4wnP1 service events help Help about any command hid Use keyboard or mouse functionality led Set or Get LED state of P4wnP1 net Configure Network settings of ethernet interfaces (including USB ethernet if enabled) system system commands template Deploy and list templates trigger Fire a group send action or wait for a group receive trigger usb USB gadget settings wifi Configure WiFi (spawn Access Point or join WiFi networks)
Flags: -h, --help help for P4wnP1_cli --host string The host with the listening P4wnP1 RPC server (default "localhost") --port string The port on which the P4wnP1 RPC server is listening (default "50051")
Use "P4wnP1_cli [command] --help" for more information about a command.
L'écran d'aide montre déjà que le client CLI utilise différentes commandes pour interagir avec les différents sous-systèmes de P4wnP1 A.L.O.A. La plupart de ces commandes ont également leurs propres sous-commandes. L'aide pour chaque commande ou sous-commande peut être consultée en ajoutant `-h` à la commande CLI :```
root@kali:~# P4wnP1_cli hid run -h
Run script provided from standard input, commandline parameter or by path to script file on P4wnP1
Usage:
P4wnP1_cli hid run [flags]
Flags:
-c, --commands string HIDScript commands to run, given as string
-h, --help help for run
-r, --server-path string Load HIDScript from given path on P4wnP1 server
-t, --timeout uint32 Interrupt HIDScript after this timeout (seconds)
Global Flags:
--host string The host with the listening P4wnP1 RPC server (default "localhost")
--port string The port on which the P4wnP1 RPC server is listening (default "50051")
Maintenant, pour taper "Hello world" à destination de l'hôte USB, la commande CLI suivante pourrait être utilisée :
P4wnP1_cli hid run -c 'type("Hello world")'
Le résultat affiché dans la session SSH devrait ressembler à ceci :``` TempFile created: /tmp/HIDscript295065725 Start appending to 'HIDscript295065725' in folder 'TMP' Result: null
Sur l'hôte USB, "Hello World" devrait avoir été tapé dans l'application ayant le focus clavier.
*Si votre client SSH s'exécute sur l'hôte USB lui-même, le "Hello world" tapé se retrouve quelque part entre la sortie résultante
de la commande CLI (elle n'appartient pas à la sortie, mais a été tapée entre les deux).*
**Objectif atteint. Nous avons injecté des frappes dans la cible.**
Beaucoup de lecture pour une tâche aussi simple que l'injection de frappes, mais encore une fois, cette section vise à expliquer les concepts de base.
### 2.2 Passer à des fonctionnalités linguistiques plus sophistiquées de HIDScript
Si vous avez réussi à exécuter l'injection de frappes "Hello world", c'est un bon moment pour explorer certaines fonctionnalités supplémentaires de HIDScript.
Nous connaissons déjà la commande `type`, mais essayons de discuter de commandes HIDScript plus sophistiquées :
#### Appuyer sur des touches spéciales et des combinaisons
La commande `type` permet d'appuyer sur la touche Entrée, en encodant un caractère "nouvelle ligne" dans la chaîne d'entrée, comme ceci :```
P4wnP1_cli hid run -c 'type("line 1\nline 2\nline 3 followed by pressing RETURN three times\n\n\n")'
Mais qu'en est-il des touches spéciales ou des combinaisons de touches ?
La commande press vient à la rescousse !
Utilisons press pour envoyer CTRL+ALT+DELETE à l'hôte USB :```
P4wnP1_cli hid run -c 'press("CTRL ALT DELETE")'
*Remarque: Deux des touches étaient des modificateurs (CTRL et ALT) et une seule était une touche réelle (DELETE)*
Appuyons sur la touche 'A' sans aucune touche modificateur:```
P4wnP1_cli hid run -c 'press("A")'
Le résultat devrait être un 'a' minuscule, car press("A") interprète 'A' comme une touche. La commande type("A"),
d'autre part, essaie d'appuyer sur une combinaison de touches qui devrait produire un caractère 'A' majuscule.
Combinons une touche modificatrice et une touche non modificatrice, afin de produire un caractère 'A' majuscule (imiter le
comportement de type("A"):```
P4wnP1_cli hid run -c 'press("SHIFT A")'
Cela aurait dû produire une sortie en A majuscule.
Il est important de comprendre, que `press` interprète ses arguments de clé en tant que touches, tandis que type essaie de trouver les
combinaisons de touches appropriées pour produire les caractères de sortie souhaités.
Dans un dernier exemple, combinons `press` et `type`.```
P4wnP1_cli hid run -c 'type("before caps\n"); press("CAPS"); type("after caps\n"); press("CAPS");'
La dernière commande a tapé une chaîne, a basculé le verrouillage majuscule (CAPSLOCK), a tapé une autre chaîne et a de nouveau basculé le verrouillage majuscule. En résultat, le verrouillage majuscule devrait être dans son état initial (basculé deux fois), mais l'une des chaînes est tapée en majuscule, l'autre en minuscule bien que les deux chaînes aient été fournies en minuscule.
Notes supplémentaires sur les pressions de touches avec press :
Je ne souhaite pas plonger dans les profondeurs du fonctionnement interne des rapports de clavier USB, mais certaines choses méritent d'être mentionnées pour cerner les limites et les possibilités de la commande press (qui elle-même fonctionne sur la base de rapports de clavier bruts) :
press consomme jusqu'à six touches normales ou spéciales
press("Z") donne USB_KEY_Z pour une disposition de clavier EN_US, mais produit USB_KEY_Y pour une disposition allemande. Cela correspond à appuyer sur la touche physique 'Z' sur un clavier allemand, qui produirait également USB_KEY_Y.)/usr/local/P4wnP1/keymaps/common.json contient une carte de touches JSON formatée avec toutes les touches possibles (faites attention à ne pas modifier le fichier)press ne produit pas une séquence de touches. Toutes les touches données sont enfoncées en même temps et relâchées en même temps.press relâche les touches automatiquement, ce qui signifie qu'une séquence comme "maintenir ALT, appuyer sur TAB, appuyer sur TAB, relâcher ALT" n'est actuellement pas possibleLa commande HIDScript pour changer la disposition du clavier est layout(<language map name>).
L'exemple suivant bascule la disposition du clavier vers 'US', tape quelque chose et bascule la disposition vers 'Allemand' avant de continuer à taper :``` P4wnP1_cli hid run -c 'layout("us"); type("Typing with EN_US layout\n");layout("de"); type("Typing with German layout supporting special chars üäö\n");'
Le résultat de la commande donnée ci-dessus dépend de la disposition cible utilisée par l'hôte USB.
Sur un hôte avec une disposition de clavier allemande, le résultat ressemble à ceci :```
Tzping with EN?US lazout
Typing with German layout supporting special chars üäö
Sur un hôte avec une disposition de clavier américain cela ressemble à ceci:``` Typing with EN_US layout Tzping with German lazout supporting special chars [';
Veuillez noter que la sortie souhaitée n'est obtenue que si la disposition du clavier de P4wnP1 correspond à la disposition du clavier effectivement utilisée par l'hôte USB.
La commande `layout` permet d'aligner la disposition interne de P4wwP1 sur celle de l'hôte USB cible.
Pouvoir changer la disposition au milieu d'un HIDScript en cours peut s'avérer utile : Qui sait, peut-être aimez-vous forcer brutalement la disposition du clavier de l'hôte cible en émettant des commandes avec des dispositions changeantes jusqu'à ce que l'une des commandes tapées obtienne l'effet souhaité.
**Important :** La disposition a un effet global. Cela signifie que si plusieurs HIDScripts s'exécutent simultanément et que l'un d'eux définit une nouvelle disposition, tous les autres scripts sont également affectés immédiatement.
#### Vitesse de frappe
Par défaut, P4wnP1 injecte les frappes aussi rapidement que possible. Selon votre objectif, cela peut être un peu trop (pensez aux contre-mesures qui empêchent l'injection de frappes basées sur l'analyse du comportement de la vitesse de frappe). HIDScript prend en charge une commande pour modifier ce comportement.
`typingSpeed(delayMillis, jitterMillis)`
Le premier argument de la commande `typingSpeed` représente un délai constant en millisecondes, qui est appliqué entre deux frappes. Le second argument est une gigue supplémentaire en millisecondes. Il ajoute un délai aléatoire supplémentaire, qui varie entre 0 et la gigue donnée en millisecondes, au délai statique fourni avec le premier argument.
Essayons d'utiliser `typingSpeed` pour ralentir la frappe :```
P4wnP1_cli hid run -c 'typingSpeed(100,0); type("Hello world")'
Ensuite, au lieu d'un délai constant, nous essayons une gigue aléatoire :``` P4wnP1_cli hid run -c 'typingSpeed(0,500); type("Writing with random jitter up to 500 milliseconds")'
Enfin, en combinant et ajustant les deux valeurs, nous pourrions simuler une vitesse de frappe naturelle :```
P4wnP1_cli hid run -c 'typingSpeed(100,150); type("Writing with more natural speed")'
Important : La vitesse de frappe a un effet global. Cela signifie que si plusieurs scripts HID sont exécutés simultanément et que l'un d'eux définit une nouvelle vitesse de frappe, tous les autres scripts sont immédiatement affectés.
Attendre le rapport LED, ou plus précisément les changements d'état des LED, est l'une des fonctionnalités les plus sophistiquées de HIDScript. Elle peut être très puissante mais nécessite un peu d'explication.
Vous avez peut-être remarqué que (selon le système d'exploitation de l'hôte USB) les modificateurs d'état du clavier (VERR NUM, ARRÊT DÉFIL, VERROUILLAGE MAJ) sont partagés entre plusieurs claviers connectés. Par exemple, si vous connectez deux claviers à un hôte Windows et que vous activez le VERROUILLAGE MAJ sur l'un d'eux, la LED VERROUILLAGE MAJ change sur les deux claviers.
Exactement ce test pourrait être utilisé pour déterminer si les modificateurs d'état du clavier sont partagés sur tous les claviers pour un système d'exploitation donné.
Si un hôte USB prend en charge ce type de partage d'état (par exemple Windows le fait), le langage HIDScript de P4wnP1 pourrait en tirer parti.
Imaginez le scénario suivant :
P4wnP1 est connecté à un hôte USB et vous souhaitez effectuer une injection de frappes, mais vous ne voulez pas que le script HID exécute les frappes immédiatement. Au lieu de cela, le script HID doit attendre que vous appuyiez sur VERR NUM, VERROUILLAGE MAJ ou ARRÊT DÉFIL sur le vrai clavier de l'hôte. Pourquoi ? Peut-être êtes-vous impliqué dans une mission, quelqu'un est entré et vous ne voulez pas que ce 'quelqu'un' voie comment une grande quantité de caractères est tapée comme par magie dans une fenêtre de console qui est soudainement apparue. Donc, vous attendez que 'quelqu'un' sorte, appuyez sur VERR NUM et finalement une fenêtre de console apparaît et une grande quantité de caractères sont tapés comme par magie... Je pense que vous avez compris.
Le comportement décrit pourrait être réalisé comme ceci :``` P4wnP1_cli hid run -c 'waitLED(NUM); type("A huge amount of characters\n")'
Si vous avez testé la commande ci-dessus, la frappe ne devrait démarrer que si NUM LOCK est enfoncé sur le clavier matériel de l'hôte USB,
mais vous pourriez rencontrer des cas où les frappes sont immédiatement émises, même si NUM LOCK n'était pas activé (et que
le voyant du clavier n'a pas changé).
Ce comportement est intentionnel et la raison en est un autre cas d'usage pour la commande `waitLED` :
Peut-être avez-vous déjà utilisé d'autres langages de script pour clavier et d'autres périphériques USB capables d'injecter des frappes.
La plupart de ces périphériques partagent un problème commun : vous ne savez pas quand commencer à taper !
Si vous commencez à taper immédiatement après la mise sous tension du périphérique USB, il est probable que l'hôte USB n'ait pas terminé
l'énumération du périphérique et n'ait donc pas réussi à charger les pilotes du clavier. Finalement, vos frappes sont perdues.
Pour contourner cela, vous pourriez ajouter un délai avant le début de l'injection de frappes. Mais combien de temps ce délai doit-il être ? Cinq
secondes, 10 secondes, 30 secondes ?
La réponse est : cela dépend ! Cela dépend de la rapidité avec laquelle l'hôte est capable d'énumérer le périphérique et de charger le pilote
du clavier. En fait, vous ne pouvez pas savoir combien de temps cela prend sans tester sur la cible réelle.
Mais comme nous l'avons déjà appris, les systèmes d'exploitation comme Windows partagent l'état des voyants entre plusieurs claviers.
Cela signifie que si le voyant NUM LOCK du clavier hôte est allumé avant de brancher un second clavier, le voyant NUM LOCK
sur ce nouveau clavier doit également être allumé une fois branché. Si le voyant NUM LOCK avait été éteint, de toute façon,
le clavier nouvellement branché reçoit l'état du voyant (tous les voyants éteints dans ce cas). Ce qui est intéressant, c'est que
cette "mise à jour du voyant" ne peut être envoyée de l'hôte USB au clavier branché que si le pilote du clavier a
fini de se charger (il serait impossible d'envoyer l'état du voyant autrement).
N'est-ce pas magnifique ? L'hôte USB nous dit : "Je suis prêt à recevoir des frappes". Inutile de tâtonner avec des
délais initiaux.
Mais il y a un autre problème : Supposons que nous connectons P4wnP1 à un hôte USB. Nous exécutons un HIDScript commençant par `waitLED` au lieu
d'un délai artisanal. La frappe commence après le `waitLED`, mais rien ne se produit - nos frappes sont perdues, de toute façon ! Pourquoi ?
Parce qu'il est probable que nous ayons manqué la mise à jour de l'état du voyant, car elle est arrivée avant même que nous ayons démarré notre HIDScript.
C'est exactement cette "condition de concurrence" qui explique pourquoi P4wnP1 conserve tous les changements d'état de voyant reconnus, à moins qu'au moins un
HIDScript les consomme en appelant `waitLED` (ou `waitLEDRepeat`). Cela pourrait entraîner le comportement décrit plus tôt,
où un `waitLED` retourne immédiatement, même si aucun changement de voyant n'a eu lieu. Nous savons maintenant : Le changement de voyant a bien eu lieu,
mais il a pu se produire bien plus tôt (avant même que nous ayons démarré le HIDScript), car le changement d'état a été conservé.
Nous savons également que ce comportement est nécessaire pour éviter de manquer des changements d'état de voyant, au cas où `waitLED` est utilisé pour tester
"l'état de préparation du pilote de clavier de l'hôte USB".
*Remarque : Il est utile de mentionner que `waitLED` ne retourne que si l'état du voyant reçu diffère de l'état interne de P4wnP1.
Cela signifie que même si nous écoutons un changement sur n'importe quel voyant avec `waitLED(ANY)`, il pourrait encore arriver que nous recevions
un état initial d'un hôte USB qui ne diffère pas de l'état interne de P4wnP1. Dans ce cas, `waitLED(ANY)`
bloquerait indéfiniment (ou jusqu'à ce qu'un vrai changement de voyant se produise).
Ce cas particulier peut être géré en appelant `waitLED(ANY_OR_NONE)`, qui retourne dès qu'un nouvel état de voyant arrive,
même s'il n'entraîne pas de changement.*
**Assez d'explications, passons à la pratique... avant cela, nous devons modifier un peu la configuration matérielle :**
Branchez une alimentation externe sur le deuxième port USB du Raspberry Pi Zero (celui extérieur). Cela garantit que
P4wnP1 ne perd pas l'alimentation lorsqu'il est débranché de l'hôte USB, car il ne dépend plus de l'alimentation par bus. Le port USB qui
doit être utilisé pour connecter P4wnP1 à l'hôte USB cible est le plus intérieur des deux ports.
Maintenant, lancez le HIDScript suivant```
P4wnP1_cli hid run -c 'while (true) {waitLED(ANY);type("Attached\n");}'
Détachez le P4wnP1 de l'hôte USB (et assurez-vous qu'il reste sous tension) ! Rebranchez-le à l'hôte USB... Chaque fois que vous rebranchez le P4wnP1 à l'hôte, "Attached" doit être tapé vers l'hôte.
Cela nous a appris 3 faits :
waitLED pourrait être utilisé comme commande initiale dans les scripts, pour commencer à taper dès que le pilote du clavier est prêtwaitLED n'est pas le choix parfait pour mettre en pause les scripts HID jusqu'à ce qu'une touche modifiant la LED soit pressée sur l'hôte USB, car
les changements d'état préservés pourraient débloquer la commande de manière non intentionnelleComme nous n'avons pas encore fini avec la commande waitLED, nous nous occupons maintenant du troisième fait. Quittons la CLI.
http://172.24.0.1:8000)ms_snake.js soit un très bon
exemple de la puissance des déclencheurs basés sur LED)Remplacez le script dans la fenêtre de l'éditeur par le suivant :``` return waitLED(ANY);
Après avoir cliqué sur un bouton d'exécution, le côté droit de la fenêtre devrait afficher une nouvelle tâche HID en cours d'exécution. Si vous appuyez sur le petit
bouton « info » à droite de la tâche HIDScript, vous pouvez voir des détails, comme son état (devrait être en cours d'exécution), l'ID de la tâche
et l'ID de la VM (c'est le numéro de la machine virtuelle JavaScript qui exécute cette tâche. Il y a 8 de ces VM, donc 8 HIDScripts pourraient
s'exécuter en parallèle).
Maintenant, si un changement de LED est émis par l'hôte USB (en activant/désactivant NUM, CAPS ou SCROLL), la tâche HIDScript devrait se terminer.
Elle peut toujours être trouvée sous les tâches « Réussies ».
Si vous appuyez de nouveau sur le petit bouton « info », il devrait y avoir une information sur la valeur de résultat (encodée en JSON),
qui ressemble à ceci :```
{"ERROR":false,"ERRORTEXT":"","TIMEOUT":false,"NUM":true,"CAPS":false,"SCROLL":false,"COMPOSE":false,"KANA":false}
Donc la commande waitLED renvoie un objet JavaScript qui ressemble à ceci :```
{
ERROR: false, // gets true if an error occurred (f.e. HIDScript was aborted, before waitLED could return)
ERRORTEXT: "", // corresponding error string
TIMEOUT: false, // gets true if waitLED timed out (more on this in a minute)
NUM: true, // gets true if NUM LED had changed before waitLED returned
CAPS: false, // gets true if CAPS LED had changed before waitLED returned
SCROLL: false, // gets true if SCROLL LED had changed before waitLED returned
COMPOSE: false, // gets true if COMPOSE LED had changed before waitLED returned (uncommon)
KANA: false // gets true if KANA LED had changed before waitLED returned (uncommon)
}
Dans mon cas, `NUM` est devenu vrai. Dans votre cas, c'était peut-être `CAPS`. Peu importe quelle LED c'était. Ce qui importe est le fait que la valeur de retour donne l'opportunité d'examiner le changement de LED qui fait que la commande retourne et ainsi elle pourrait être utilisée pour prendre des décisions de branchement dans votre HIDScript (basé sur les changements d'état de LED émis par le clavier réel de l'hôte USB).
Essayons un exemple :```
while (true) {
result = waitLED(ANY);
if (result.NUM) {
type("NUM has been toggled\n");
}
if (result.SCROLL) {
type("SCROLL has been toggled\n");
}
if (result.CAPS) {
break; //exit loop
}
}
En supposant que le script donné est déjà en cours d'exécution, appuyer sur NUM sur l'hôte USB devrait entraîner la frappe de « NUM has been toggled », tandis qu'appuyer sur SCROLL LOCK résulte en le texte tapé « SCROLL has been toggled ». Ce comportement se répète, jusqu'à ce que CAPS LOCK soit enfoncé et que le changement de LED résultant interrompe la boucle et mette fin au HIDScript.
Puhhh ... beaucoup de texte sur cette commande pour une seule commande HIDScript, mais il reste encore quelques points.
Nous avons fourni des arguments comme NUM, ANY ou ANY_OR_NONE à la commande waitLED, sans plus d'explications.
La commande waitLED accepte jusqu'à deux arguments :
Le premier argument, comme vous l'avez peut-être deviné, est un filtre de liste blanche pour les LEDs à surveiller. Les arguments valides sont :
ANY (réagit à un changement sur n'importe quelle LED)ANY_OR_NONE (réagit à chaque nouvel état des LEDs, même s'il n'y a pas de changement)NUM (ignore tous les changements de LED, sauf sur la LED NUM)CAPS (ignore tous les changements de LED, sauf sur la LED NUM CAPS)SCROLL (ignore tous les changements de LED, sauf sur la LED NUM SCROLL)CAPS | NUM, NUM | SCROLLLe deuxième argument, que nous n'avons pas utilisé jusqu'à présent, est une durée de temporisation en millisecondes. Si aucun changement de LED ne se produit pendant cette durée de temporisation, waitLED se termine et TIMEOUT: true est défini dans l'objet résultant (de plus, ERROR est défini sur true et ERRORTEXT indique un dépassement de temporisation).
La commande suivante attendrait un changement sur la LED NUM, mais interrompt l'attente après 5 secondes :``` waitLED(NUM,5000)
Même si `waitLED` est une commande très puissante si elle est utilisée correctement, elle n'a pas aidé à gérer notre tâche simple de mise en pause robuste d'un HIDScript jusqu'à ce qu'une touche de modification d'état soit enfoncée sur l'hôte USB cible (rappelez-vous : nous voulions mettre en pause l'exécution pour s'assurer que l'« intrus » indésirable soit sorti avant que la frappe ne commence, mais `waitLED` revenait parfois prématurément à cause des changements d'état de LED préservés).
C'est là que `waitLEDRepeat` entre en jeu et vient à la rescousse.
Collez le script suivant dans l'éditeur et essayez de faire revenir la commande. Inspectez ensuite les résultats du HIDScript.```
return waitLEDRepeat(ANY)
Vous remarquerez rapidement que la même LED doit être changée plusieurs fois fréquemment, afin que la commande
waitLEDRepeat retourne. La commande waitLEDRepeat ne retournerait pas si des LEDs différentes changent d'état ou si la
LED change sur une seule LED trop lentement.
L'argument fourni à waitLEDRepeat (qui est ANY dans l'exemple) sert exactement le même but que pour waitLED.
Il s'agit d'un filtre de liste blanche. Par exemple, waitLEDRepeat(NUM) ne retournerait que pour les changements de la LED NUM LOCK - peu importe
la rapidité et la fréquence avec lesquelles vous frappez sur la touche CAPS LOCK, cela ne retournerait pas tant que NUM LOCK n'est pas pressé fréquemment.
Par défaut, l'une des LEDs de la liste blanche doit changer 3 fois et le délai entre deux changements successifs ne doit pas être
supérieur à 800 millisecondes pour que waitLEDRepeat retourne. Ce comportement peut être ajusté en fournissant
des arguments supplémentaires comme illustré dans cet exemple :```
filter = ANY; // same filters as for waitLED
num_changes = 5; // how often the SAME LED has to change, in order to return from waitLEDRepeat
max_delay = 800; // the maximum duration between two LED changes, which should be taken into acccount (milliseconds)
timeout = 10000; // timeout in milliseconds
waitLEDRepeat(filter, num_changes, max_delay); //wait till a LED frequently changed 5 times, no timeout waitLEDRepeat(filter, num_changes, max_delay, timeout); //wait till a LED frequently changed 5 times, abort after 10 seconds
Ainsi, voici comment interagir avec les rapports LED depuis un hôte USB en HIDScript.
*Note : `waitLEDRepeat` ne diffère pas de `waitLED` en ce qui concerne la consommation des changements d'état LED préservés.
Quoi qu'il en soit, il est beaucoup plus difficile de le déclencher involontairement.*
Donc `waitLEDRepeat` est le bon choix si la tâche consiste à mettre en pause les HIDScripts jusqu'à ce qu'une interaction humaine se produise. Bien sûr, il
pourrait également être utilisé pour des branchements, car il fournit le même objet de retour que `waitLED`.
Jusqu'à présent, nous avons acquis pas mal de connaissances sur HIDScript (bien sûr pas tout, nous n'avons même pas
examiné les capacités de contrôle de la souris de ce langage de script). Quoi qu'il en soit, ce tutoriel porte sur le flux de travail de P4wnP1 A.L.O.A.
et les concepts de base. Nous n'allons donc pas explorer d'autres fonctionnalités de HIDScript pour l'instant, et passons à la suite.
Récapitulons ce que nous avons appris sur le flux de travail et les concepts de P4wnP1 jusqu'à présent :
- nous pouvions lancer des actions comme l'injection de frappes depuis le client CLI, à la demande
- nous pouvions utiliser le client web pour obtenir le même résultat, tout en ayant un contrôle supplémentaire sur les tâches HIDScript
- si nous connectons une alimentation externe à P4wnP1 A.L.O.A., nous nous connectons/déconnectons de différents hôtes USB et les
HIDScripts déjà lancés continuent de fonctionner de manière transparente
- nous pouvions configurer la pile USB exactement selon nos besoins (et modifier sa configuration en cours d'exécution, sans redémarrer
P4wnP1)
- nous pouvions écrire des HIDScripts polyvalents, avec une logique complexe basée sur JavaScript (avec prise en charge des fonctions, boucles,
branchements, etc.)
### 3. Flux de travail partie 2 - Templating et TriggerActions
Avant de continuer avec les autres concepts majeurs de P4wnP1 A.L.O.A., affinons notre premier objectif, qui était « d'exécuter une injection
de frappes contre un hôte USB » :
- Le nouvel objectif est de taper « Hello world » dans l'éditeur d'un hôte USB Windows (notepad.exe).
- L'éditeur doit être ouvert par P4wnP1 (pas manuellement par l'utilisateur).
- L'éditeur doit automatiquement se fermer lorsque l'une des LED du clavier de l'hôte USB est activée.
- Chaque fois que P4wnP1 est connecté à l'hôte USB, ce comportement doit se répéter (avec une alimentation externe, sans redémarrage de
P4wnP1).
- Le processus *ne doit s'exécuter qu'une seule fois*, à moins que P4wnP1 ne soit reconnecté à l'hôte USB, même si des changements successifs de LED du
clavier se produisent après le démarrage du HIDScript.
- Même si P4wnP1 est redémarré, le même comportement doit pouvoir être récupéré sans recréer les détails de la configuration à partir de
zéro.
Ouvrir notepad, taper « Hello world » et fermer notepad après un changement de LED pourrait être réalisé avec ce que nous avons appris
jusqu'à présent. Un HIDScript correspondant pourrait ressembler à ceci :```
// Starting notepad
press("WIN R"); // Windows key + R, to open run dialog
delay(500); // wait 500ms for the dialog to open
type("notepad.exe\n"); // type 'notepad.exe' to the run dialog, append a RETURN press
delay(2000); // wait 2 seconds for notepad to come up
// Type the message
type("Hello world") // Type "Hello world" to notepad
// close notepad after LED change
waitLED(ANY); // wait for a single LED change
press("ALT F4"); // ALT+F4 shortcut to close notepad
//as we changed content, there will be a confirmation dialog before notepad exits
delay(500); // wait for the confirmation dialog
press("RIGHT"); // move focus to next button (don't save) with RIGHT ARROW
press("SPACEBAR"); // confirm dialog with space
La seule nouveauté dans ce script est la commande delay, qui n'a pas besoin de beaucoup d'explications. Elle retarde l'exécution du nombre de millisecondes donné.
Le script pourrait être collé dans l'éditeur HIDScript du client web et démarré avec "run" afin de le tester.
Il devrait fonctionner comme prévu, donc nous avons presque terminé. Afin de pouvoir réutiliser le script, même après un redémarrage, nous le stockons de manière persistante. Cela peut être réalisé en cliquant sur le bouton "store" dans l'onglet HIDScript du client web. Après avoir saisi un nom (nous utilisons tutorial1 pour l'instant) et confirmé la boîte de dialogue, le HIDScript devrait être stocké. Nous pouvons vérifier cela en cliquant sur le bouton "Load & Replace" dans le client web. Le script stocké devrait apparaître dans la liste des scripts stockés avec le nom tutorial1.js (l'extension .js est ajoutée automatiquement si elle n'a pas déjà été fournie dans la boîte de dialogue "store").
Attention : Si un nom de fichier déjà existant est utilisé dans la boîte de dialogue "store", le fichier correspondant est écrasé sans demander de confirmation supplémentaire.
Essayons de démarrer le script stocké en utilisant le client CLI depuis une session SSH, comme ceci :``` P4wnP1_cli hid run tutorial1.js
Cela aurait dû fonctionner. Cela signifie qu'il est possible de lancer des HIDScripts stockés à partir de toutes les applications prenant en charge les commandes shell
ou à partir d'un simple script bash, en utilisant le client CLI P4wnP1 A.L.O.A.
Il serait même possible de lancer le script à distance depuis un client CLI compilé pour Windows.
En supposant que l'hôte Windows puisse atteindre P4wnP1 A.L.O.A. via WiFi et que l'IP de P4wnP1 soit définie sur `172.24.0.1`, la commande appropriée ressemblerait à ceci :```
P4wnP1_cli.exe --host 172.24.0.1 hid run tutorial1.js
Remarque : Au moment où j'écris ceci, je n'ai pas encore décidé si P4wnP1 A.L.O.A. fournit un binaire CLI pour chaque plateforme et architecture possible. Mais il est probable que des versions précompilées pour les principales plateformes soient fournies. Sinon, ce n'est pas un gros problème, car la cross-compilation du code Go du client CLI prend moins d'une minute.
L'étape suivante consiste à permettre au script de s'exécuter à nouveau, chaque fois que P4wnP1 est reconnecté à un hôte USB. Une approche que nous avons déjà utilisée pour obtenir un tel comportement était d'envelopper le tout dans une boucle et de préfixer un waitLED(ANY_OR_NONE). Le waitLED(ANY_OR_NONE) assurait tha la boucle ne continue que si l'hôte USB cible signale que le pilote de clavier est prêt à recevoir une entrée en envoyant une mise à jour de l'état global des LEDs du clavier sate. Un script modifié en conséquence pourrait ressembler à ceci :```
while (true) {
waitLED(ANY_OR_NONE); // wait till keyboard driver sends the initial LED state
// Starting notepad press("WIN R"); // Windows key + R, to open run dialog delay(500); // wait 500ms for the dialog to open type("notepad.exe\n"); // type 'notepad.exe' to the run dialog, append a RETURN press delay(2000); // wait 2 seconds for notepad to come up
// Type the message type("Hello world") // Type "Hello world" to notepad
// close notepad after LED change waitLED(ANY); // wait for a single LED change press("ALT F4"); // ALT+F4 shortcut to close notepad
//as we changed content, there will be a confirmation dialog before notepad exits delay(500); // wait for the confirmation dialog press("RIGHT"); // move focus to next button (don't save) with RIGHT ARROW press("SPACEBAR"); // confirm dialog with space }
Le script donné ci-dessus s'exécuterait effectivement chaque fois que le P4wnP1 est connecté à un hôte USB. Mais le script n'est pas très robuste, car il implique un second `waitLED`, qui attend que notepad.exe soit refermé, à nouveau.
Faire ainsi implique plusieurs problèmes. Par exemple, si le P4wnP1 est débranché avant que "Hello world" ne soit tapé, le `waitLED` maintenant bloquant serait celui avant `press("ALT F4")` et l'exécution continuerait exactement à ce point du HIDScript une fois que le P4wnP1 est reconnecté à un hôte USB (peut-être différent), à nouveau.
Un critère d'arrêt définitif pour l'approche choisie est le problème suivant : l'exigence que le script ne s'exécute qu'une seule fois après avoir branché le P4wnP1 à un hôte USB ne pouvait pas être respectée, car appuyer plusieurs fois sur NUM LOCK relancerait le script encore et encore.
Alors, comment résoudre cela ?
#### Présentons les TriggerActions
La solution au problème est ce qu'on appelle des 'TriggerActions'. Comme son nom l'indique, ce concept de workflow P4wnP1 A.L.O.A. déclenche des actions basées sur des déclencheurs prédéfinis.
Pour avoir une idée de ce dont je parle, dirigez-vous vers l'onglet 'TRIGGER ACTIONS' du client web. Selon la configuration actuelle, il peut déjà y avoir des TriggerActions. Nous ne nous soucions pas des TriggerActions existantes, pour l'instant.
Appuyez sur le bouton 'ADD ONE' et une nouvelle TriggerAction devrait être ajoutée et instantanément ouverte en mode édition. La nouvelle TriggerAction est désactivée par défaut et doit être activée pour être modifiable. Nous basculons donc l'interrupteur d'activation.
Maintenant, dans le menu déroulant appelé 'Trigger', l'option 'USB gadget connected to host' doit être sélectionnée. L'action doit avoir une présélection de 'write log entry'. Nous laissons ainsi et appuyons sur le bouton 'Update'.
La TriggerAction nouvellement ajoutée devrait maintenant être visible dans l'aperçu des TriggerActions (celle avec l'ID le plus élevé) et afficher un résumé du Trigger et de l'Action sélectionnés sous forme lisible.
Pour tester si la TriggerAction nouvellement définie fonctionne, naviguez vers l'onglet 'Event Log' du client web. Assurez-vous d'avoir le client web ouvert via WiFi (pas via Ethernet USB). Appliquez une alimentation externe au P4wnP1, déconnectez-le de l'hôte USB et reconnectez-le. Un message de journal devrait être envoyé au client chaque fois que le P4wnP1 est connecté à un hôte USB, immédiatement.
Si vous répétez cela plusieurs fois, vous avez peut-être remarqué que le déclencheur 'USB gadget connected to host' se déclenche très rapidement (ou à un stade précoce de la phase d'énumération USB). Pour être plus précis : lorsque ce déclencheur se déclenche, on sait que le P4wnP1 a été connecté à un hôte USB, mais il n'y a aucune garantie que l'hôte USB ait réussi à charger tous les pilotes de périphérique USB nécessaires. **En fait, il est très peu probable que le pilote du clavier USB soit chargé lorsque le déclencheur se déclenche. Nous devons garder cela à l'esprit.**
Avant de poursuivre notre tâche, nous effectuons un test supplémentaire. Retournez sur l'onglet 'TriggerAction' et appuyez sur le petit bouton bleu en forme de stylo pour notre TriggerAction nouvellement créée. Nous nous retrouvons à nouveau en mode édition.
Cette fois, nous activons l'option `One shot`. Retournez ensuite dans le 'Event Log', et à nouveau, déconnectez et reconnectez le P4wnP1 de l'hôte USB. Cette fois, la TriggerAction ne devrait se déclencher qu'une seule fois. Peu importe combien de fois le P4wnP1 est reconnecté à l'hôte USB par la suite, aucun nouveau message de journal indiquant une connexion USB ne devrait être créé.
Il est intéressant de mentionner qu'une TriggerAction 'One shot' n'est pas supprimée après le déclenchement du Trigger. Au lieu de cela, la TriggerAction est à nouveau désactivée. La réactivation permet de réutiliser une TriggerAction sans la redéfinir. Rien n'est perdu jusqu'à ce que le bouton rouge 'trash' soit enfoncé sur une TriggerAction, ce qui supprimera la TriggerAction correspondante.
**Attention : Si le bouton de suppression d'une TriggerAction est cliqué, la TriggerAction est supprimée définitivement sans autre confirmation.**
À ce stade, faisons l'évidence. Nous modifions la TriggerAction créée et sélectionnons 'start a HIDScript' au lieu de 'write log entry' pour l'action à exécuter. De plus, nous désactivons à nouveau 'one-shot'. Un nouveau champ de saisie appelé 'script name' apparaît. Cliquer sur ce champ de saisie ouvre une boîte de dialogue de sélection pour tous les HIDScripts stockés, y compris notre HIDScript `tutorial1.js` créé précédemment.
*Avant de tester si cela fonctionne, laissez-moi faire une brève remarque sur l'action 'write log entry' : P4wnP1 A.L.O.A. ne garde pas la trace des Triggers qui ont déjà été déclenchés. Cela signifie que les entrées de journal créées par une action 'write log entry' sont délivrées à tous les clients à l'écoute, mais ne sont pas stockées par le service P4wnP1 (pour diverses raisons). Le client web, en revanche, stocke l'entrée de journal jusqu'à ce que le client web lui-même soit rechargé. La même chose s'applique aux événements, qui sont liés aux tâches HIDScript. Si un HIDScript se termine (avec succès ou erreur), un événement est poussé vers tous les clients web actuellement ouverts. En résumé, chaque client web possède un état d'exécution, qui contient plus d'informations que le service central lui-même. Si l'état d'exécution du client web devient trop volumineux (trop d'utilisation de la mémoire), il suffit de recharger le client pour effacer les informations d'état 'historiques'. Si le service central se comportait de la même manière et stockait toutes les informations historiques, il manquerait rapidement de ressources. Ainsi, ce concept s'applique à la plupart des sous-systèmes de P4wnP1 A.L.O.A.*
Revenons maintenant à notre tâche. Nous avons une TriggerAction prête, qui devrait déclencher notre HIDScript chaque fois que le P4wnP1 est connecté à un hôte USB.
Selon l'hôte USB cible, cela fonctionne plus ou moins fiablement. Dans ma configuration de test, cela n'a pas fonctionné du tout et il y a une raison :
Examinons les premières lignes de notre HIDScript :```
// Starting notepad
press("WIN R"); // Windows key + R, to open run dialog
delay(500); // wait 500ms for the dialog to open
type("notepad.exe\n"); // type 'notepad.exe' to the run dialog, append a RETURN press
... snip ...
Rappelant le fait que le déclencheur "USB gadget connected" se déclenche dans la phase précoce d'énumération USB et que le pilote de clavier de l'hôte USB n'a pas nécessairement été chargé, le problème devient évident. Nous devons ajouter une sorte de délai au script pour nous assurer que le pilote de clavier est actif (sinon nos frappes de touches aboutiraient dans le néant).
Comme nous savons déjà qu'il n'est pas possible de prédire le délai optimal, nous optons pour l'approche waitLED(ANY_OR_NONE), expliquée précédemment. Le nouveau script ressemble à ceci :```
waitLED(ANY_OR_NONE); //assure keyboard driver is ready
// Starting notepad press("WIN R"); // Windows key + R, to open run dialog delay(500); // wait 500ms for the dialog to open type("notepad.exe\n"); // type 'notepad.exe' to the run dialog, append a RETURN press delay(2000); // wait 2 seconds for notepad to come up
// Type the message type("Hello world") // Type "Hello world" to notepad
// close notepad after LED change waitLEDRepeat(ANY); // wait for a single LED change press("ALT F4"); // ALT+F4 shortcut to close notepad
//as we changed content, there will be a confirmation dialog before notepad exits delay(500); // wait for the confirmation dialog press("RIGHT"); // move focus to next button (don't save) with RIGHT ARROW press("SPACEBAR"); // confirm dialog with space
Stocker le script modifié sous le même nom (`tutorial1`) écrase l'ancien HIDScript sans confirmation supplémentaire, comme déjà précisé. Il n'est donc pas nécessaire d'ajuster notre TriggerAction, car le nom de l'HIDScript auquel la TriggerAction fait référence n'a pas changé.
Avec cette petite modification, tout devrait fonctionner comme prévu et le script devrait se déclencher chaque fois que nous nous connectons à un hôte USB, mais ne s'exécuter qu'une seule fois.
Maintenant, si P4wnP1 est redémarré ou perd l'alimentation, notre HIDScript survivrait, car nous l'avons stocké de manière persistante, mais la TriggerAction serait perdue. Inutile de dire que les TriggerActions peuvent également être stockées de manière persistante.
Le bouton "store" dans l'onglet "TriggerAction" fonctionne exactement comme celui de l'éditeur HIDScript. Il convient de noter que *toutes les TriggerActions actuellement actives* seront stockées si la boîte de dialogue "store" est confirmée (y compris celles désactivées).
La meilleure pratique consiste à supprimer toutes les TriggerActions qui n'appartiennent pas à la tâche en cours avant de stocker (elles auraient dû être stockées plus tôt, si nécessaire) et à ne stocker que le petit ensemble de TriggerActions pertinentes pour la tâche en cours, en utilisant un nom approprié. Il existe deux options pour recharger les TriggerActions stockées dans les actives :
- "load & replace" efface toutes les actions de déclenchement actives et charge uniquement celles stockées
- "load & add" conserve les TriggerActions déjà actives et ajoute celles stockées. Ainsi, "load & add" pourrait être utilisé pour construire un ensemble complexe de TriggerActions à partir de petits ensembles. L'ensemble résultant pourrait ensuite être à nouveau stocké.
Pour l'instant, nous devons simplement stocker notre seule TriggerAction, qui lance notre HIDScript. Le nom que nous utilisons pour stocker est à nouveau `tutorial1` et n'entrera pas en conflit avec l'HIDScript appelé `tutorial1`.
Confirmez le stockage réussi en cliquant sur le bouton "load & replace" dans l'onglet "TriggerAction". L'ensemble de TriggerActions stocké devrait apparaître dans la liste et se nommer `tutorial1`.
**Warning: Les boîtes de dialogue "load" de TriggerAction permettent de supprimer les TriggerActions stockées en cliquant sur le bouton rouge "corbeille" à côté de chaque action. Cliquer sur ce bouton supprime définitivement l'ensemble de TriggerActions correspondant, sans confirmation supplémentaire**
À ce stade, nous pourrions supprimer en toute sécurité notre TriggerAction de l'onglet "TriggerActions" (!! pas avec le bouton corbeille d'une des boîtes de dialogue de chargement !!).
Avec la TriggerAction supprimée des actions actives, rien ne se produit si nous débranchons et rebranchons P4wnP1 de l'hôte USB.
Quoi qu'il en soit, l'ensemble de TriggerActions stocké `tutorial1` persistera après les redémarrages et pourra être rechargé à tout moment.
Au lieu de recharger l'ensemble de TriggerActions depuis le client web, nous essayons d'y parvenir en utilisant le client CLI.
Jetons un coup d'œil rapide à l'écran d'aide de la sous-commande `template deploy` :```
root@kali:~# P4wnP1_cli template deploy -h
Deploy given gadget settings
Usage:
P4wnP1_cli template deploy [flags]
Flags:
-b, --bluetooth string Deploy Bluetooth template
-f, --full string Deploy full settings template
-h, --help help for deploy
-n, --network string Deploy network settings template
-t, --trigger-actions string Deploy trigger action template
-u, --usb string Deploy USB settings template
-w, --wifi string Deploy WiFi settings templates
Global Flags:
--host string The host with the listening P4wnP1 RPC server (default "localhost")
--port string The port on which the P4wnP1 RPC server is listening (default "50051")
L'écran d'utilisation montre que les modèles TriggerAction peuvent être déployés avec l'indicateur -t. Nous exécutons la commande suivante pour restaurer l'ensemble TriggerAction stocké :```
P4wnP1_cli template deploy -t tutorial1
L'Action de déclenchement qui exécute le HIDScript lors des connexions hôte USB est maintenant chargée à nouveau et devrait être visible dans l'onglet TriggerActions du client web. Si P4wnP1 A.L.O.A. est connecté à un hôte USB, le script devrait s'exécuter à nouveau.
Le stockage, le chargement et le déploiement de modèles sont l'un des deux concepts principaux derrière le flux de travail d'automatisation de P4wnP1, l'autre étant les déjà connues TriggerActions. Il convient de mentionner que non seulement les ensembles de TriggerActions peuvent être stockés et chargés en tant que modèles eux-mêmes, mais que les TriggerActions peuvent être utilisées pour déployer des modèles déjà stockés, si cela a du sens.
En revisitant nos tâches, il semble que toutes les exigences définies soient maintenant remplies :
- nous avons tapé "Hello world" dans l'éditeur d'un hôte Windows USB
- l'éditeur est ouvert par P4wnP1, pas manuellement par l'utilisateur
- l'éditeur se ferme automatiquement lorsqu'une des LEDs du clavier bascule une fois
- chaque fois que P4wnP1 est connecté à un hôte USB, ce comportement se répète
- le HIDScript s'exécute une seule fois, à moins que P4wnP1 ne soit reconnecté à l'hôte USB, même si des changements successifs de LEDs du clavier se produisent
- si P4wnP1 est redémarré, le même comportement peut être récupéré en chargeant l'ensemble de TriggerActions stocké (qui fait à nouveau référence au HIDScript stocké). Cela peut être réalisé soit avec une seule commande CLI, soit avec un simple "load&add" ou "load&replace" depuis l'onglet trigger action du client web.
Ajoutons encore une fois des objectifs supplémentaires :
- il faut s'assurer que la configuration USB a la fonctionnalité de clavier activée (la configuration actuelle ne le fait pas et la TriggerAction ne pourrait pas démarrer le HIDScript si le clavier USB est désactivé)
- la configuration créée doit être appliquée au démarrage de P4wnP1 A.L.O.A., sans avoir besoin de charger manuellement l'ensemble de TriggerActions. La configuration doit survivre à un redémarrage de P4wnP1.
Pour atteindre ces deux objectifs supplémentaires, nous devons nous plonger dans un nouveau sujet et ...
#### Présentation des modèles maîtres et du modèle maître de démarrage
Avant de nous pencher sur les modèles maîtres, nous faisons quelque chose que nous n'avons pas encore fait, car tout a bien fonctionné comme prévu jusqu'à présent : nous définissons une configuration USB valide, correspondant à notre tâche !
- device serial number: 123456789
- device product name: Auto Writer
- device manufacturer: The Creator
- Product ID: 0x9876
- Vendor ID: 0x1D6B
- enabled USB functions
- HID keyboard
- HID mouse
Jetons d'abord un coup d'œil à l'écran d'utilisation de la commande CLI, qui pourrait être utilisé pour déployer ces paramètres :```
root@kali:~# P4wnP1_cli usb set -h
set USB Gadget settings
Usage:
P4wnP1_cli usb set [flags]
Flags:
-e, --cdc-ecm Use the CDC ECM gadget function
-n, --disable If this flag is set, the gadget stays inactive after deployment (not bound to UDC)
-h, --help help for set
-k, --hid-keyboard Use the HID KEYBOARD gadget function
-m, --hid-mouse Use the HID MOUSE gadget function
-g, --hid-raw Use the HID RAW gadget function
-f, --manufacturer string Manufacturer string (default "MaMe82")
-p, --pid string Product ID (format '0x1347') (default "0x1347")
-o, --product string Product name string (default "P4wnP1 by MaMe82")
-r, --rndis Use the RNDIS gadget function
-s, --serial Use the SERIAL gadget function
-x, --sn string Serial number (alpha numeric) (default "deadbeef1337")
-u, --ums Use the USB Mass Storage gadget function
--ums-cdrom If this flag is set, UMS emulates a CD-Rom instead of a flashdrive (ignored, if UMS disabled)
--ums-file string Path to the image or block device backing UMS (ignored, if UMS disabled)
-v, --vid string Vendor ID (format '0x1d6b') (default "0x1d6b")
Global Flags:
--host string The host with the listening P4wnP1 RPC server (default "localhost")
--json Output results as JSON if applicable
--port string The port on which the P4wnP1 RPC server is listening (default "50051")
La commande a un tas d'options, mais il existe aussi un tas de paramètres USB modifiables. Le déploiement de notre configuration USB définie pourrait être effectué comme ceci, en utilisant la CLI :``` root@kali:~# P4wnP1_cli usb set \
--sn 123456789
--product "Auto Writer"
--manufacturer "The Creator"
--pid "0x9876"
--vid "0x1d6b"
--hid-keyboard
--hid-mouse Successfully deployed USB gadget settings Enabled: true Product: Auto Writer Manufacturer: The Creator Serialnumber: 123456789 PID: 0x9876 VID: 0x1d6b
Functions: RNDIS: false CDC ECM: false Serial: false HID Mouse: true HID Keyboard: true HID Generic: false Mass Storage: false
Le résultat de la commande (assez longue) affiche les paramètres USB obtenus. Vérifions l'onglet "USB settings" du webclient pour confirmer qu'ils ont été appliqués. Toutes les modifications devraient être reflétées, si rien ne s'est mal passé.
Bien qu'il soit parfaitement possible de déployer une configuration USB en utilisant le CLI, l'utilisation du webclient présente plusieurs avantages par rapport au CLI. Dans ce cas :
- modifier les paramètres depuis le webclient est plus facile et plus pratique
- le webclient possède un état interne des paramètres, ce qui permet de définir des paramètres USB sans les déployer (le CLI, en revanche, ne pouvait manipuler les paramètres qu'en les déployant. Ceci, encore une fois, réinitialise l'ensemble de la pile USB de P4wnP1 et toutes les fonctionnalités dépendantes. Par exemple, un HIDScript déjà en cours serait interrompu ou les interfaces réseau USB seraient redéployées)
- les paramètres actuels du webclient peuvent être stockés dans un modèle persistant, sans les déployer au préalable
- le client CLI (actuellement) n'est pas capable de stocker les paramètres USB
Dans notre cas actuel, il est évidemment préférable d'utiliser le webclient pour les modifications nécessaires aux paramètres USB. L'avantage de l'approche CLI (que nous avons déjà utilisée ici) : comme le CLI nous a obligés à déployer les paramètres USB, nous avons pu confirmer qu'ils fonctionnent avant de les stocker dans un modèle persistant.
Continuons avec le stockage des paramètres USB :
Nous cliquons à nouveau sur le bouton "store", cette fois dans l'onglet "USB settings". Nous appelons à nouveau le modèle `tutorial1` (il n'y a pas de conflit avec le modèle TriggerAction stocké sous le même nom, car un espace de noms différent est utilisé pour les paramètres USB).
Nous avons maintenant deux nouveaux modèles stockés de manière persistante :
1) un modèle pour l'ensemble TriggerAction, nommé `tutorial1`
2) un modèle pour les paramètres USB, également nommé `tutorial1`
En supposant que l'état (des paramètres USB actuels, TriggerActions ou les deux) ait changé d'une manière ou d'une autre, nous pourrions recharger les deux paramètres stockés en une seule fois, en exécutant la commande CLI suivante :```
P4wnP1_cli template deploy --usb tutorial1 --trigger-actions tutorial1
La commande P4wnP1 template deploy pourrait charger un modèle pour chacun des sous-systèmes de P4wnP1 A.L.O.A. en une seule exécution (pour le sous-système réseau, plusieurs modèles pourraient être chargés, un par adaptateur). Le déploiement de modèles pour divers sous-systèmes est considéré comme une tâche courante lors du travail avec P4wnP1 A.L.O.A., car dans la plupart des cas, il devrait être nécessaire de reconfigurer plusieurs sous-systèmes pour atteindre un seul objectif. Pour prendre en compte cela, ce qu'on appelle des Modèles Maîtres ont été introduits.
Un Modèle Maître pourrait se composer de :
Un Modèle Maître pourrait être défini, enregistré ou chargé, en utilisant l'« Éditeur de Modèles Maîtres » depuis l'onglet « Paramètres Génériques » du client web. L'utilisation du client web est un moyen pratique de définir des Modèles Maîtres, car il vous assiste en ne permettant de sélectionner que les modèles qui ont déjà été enregistrés pour les sous-systèmes respectifs (et actuellement, le client web est le seul moyen de définir des Modèles Maîtres).
Donc, définissons un Modèle Maître pour notre tâche actuelle :
tutorial1 et confirmez avec le bouton « OK »tutorial1 (qui est un modèle différent pour le sous-système USB, bien qu'il partage le nom avec celui des Actions de Déclenchement)tutorial1Pour confirmer que le modèle a été enregistré, vous pouvez utiliser le bouton « Charger enregistré » – le modèle devrait apparaître dans la sélection. Annulez à nouveau la boîte de dialogue « Charger enregistré ».
Cliquez maintenant sur le bouton « Déployer enregistré », sélectionnez le modèle nommé startup et confirmez avec « OK ».
Contrairement à la fonction « Charger enregistré », qui charge un modèle enregistré dans l'Éditeur de Modèles Maîtres, la fonction « Déployer enregistré » applique tous les paramètres d'un Modèle Maître aux sous-systèmes correspondants de P4wnP1, immédiatement (sans même les charger dans l'Éditeur de Modèles Maîtres).
Comme le Modèle Maître startup écrase les paramètres WiFi actuels, il se peut que vous ayez perdu la connexion au client web et que vous deviez vous reconnecter au réseau WiFi P4wnP1.
Une fois reconnecté avec succès et après avoir inspecté les paramètres USB actuels et les Actions de Déclenchement actuelles, les paramètres que nous avons enregistrés plus tôt ont été écrasés par les sous-paramètres du Modèle Maître startup.
Il y a deux façons de déployer à nouveau le Modèle Maître tutorial1 :
startup il y a une minute)P4wnP1_cli template deploy --full tutorial1 (le drapeau --full est un alias pour Modèle Maître)En étant capable de déployer le Modèle Maître tutorial1, nous avons déjà atteint l'un de nos nouveaux objectifs :
Il est assuré que la configuration USB a la fonctionnalité de clavier activée lorsque nous chargeons notre configuration d'injection de frappes.
Un résumé rapide du fonctionnement :
tutorial1 charge les paramètres USB, appelés tutorial1 qui ont
tutorial1 charge un ensemble d'actions de déclenchement avec une seule action de déclenchement
tutorial1.js chaque fois que P4wnP1 est connecté à un hôte USB
waitLED se déclenche (pilote de clavier prêt) et se termine après un changement successif de LEDLe seul objectif restant est le suivant : La configuration créée doit être appliquée au démarrage de P4wnP1 A.L.O.A., sans avoir besoin de charger manuellement l'ensemble d'actions de déclenchement. La configuration doit survivre à un redémarrage de P4wnP1.
Cet objectif pourrait être atteint assez facilement maintenant. L'onglet « Paramètres Génériques » du client web présente une carte appelée Modèle Maître de Démarrage. Modifier le Modèle Maître de Démarrage en tutorial1 à ce stade aurait un effet immédiat et détruirait probablement la configuration de démarrage fonctionnelle de P4wnP1 A.L.O.A..
Important : Si un Modèle Maître a des sous-modèles laissés vides (par exemple, s'il n'y a pas de modèle Bluetooth sélectionné), le sous-système respectif n'est pas reconfiguré lorsque le Modèle Maître est chargé. Bien que cela soit pratique pour une reconfiguration en cours d'exécution sans réinitialiser les sous-systèmes déjà en cours d'exécution comme la pile USB ou la pile WiFi si nécessaire, les Modèles Maîtres utilisés comme Modèle Maître de Démarrage laissent les sous-systèmes sans modèles définis dans un ÉTAT INDÉFINI. Si, par exemple, aucun modèle WiFi valide n'est fourni, il est peu probable que P4wnP1 A.L.O.A. soit accessible via WiFi après le redémarrage
Donc, avant de déployer notre nouveau Modèle Maître tutorial1 comme Modèle Maître de Démarrage, nous assurons que des paramètres appropriés sont chargés pour les autres sous-systèmes. Nous faisons cela comme suit :
tutorial1 dans l'éditeur.tutorial1 défini pour « Modèle d'Actions de Déclenchement » et pour « Modèle USB »startupstartupbteth_startupusbeth_startupwlan0_startup_dhcp_servertutorial1 avec les nouveaux paramètres (cliquez sur « Enregistrer », entrez tutorial1 et confirmez avec « OK »)tutorial1. Toutes les sous-sections du Modèle Maître chargé devraient ressembler à celles décrites ici.Maintenant, nous sommes prêts à déployer notre nouveau Modèle Maître comme Modèle Maître de Démarrage. Après l'avoir fait, nous cliquons sur le bouton « redémarrer ».
Une fois redémarré, P4wnP1 A.L.O.A. devrait déclencher automatiquement le script HID (et devrait toujours être accessible via WiFi, pour permettre une reconfiguration)
Félicitations, tous les objectifs atteints
Vous avez appris les concepts de base du flux de travail de P4wnP1 A.L.O.A.
Il n'est actuellement pas possible de fournir une documentation complète. Voici donc quelques commentaires sur des sujets qui n'ont pas encore été abordés, mais qui méritent d'être explorés.
P4wnP1 permet d'exécuter des scripts Bash à partir d'Actions de Déclenchement. Les scripts utilisables depuis les Actions de Déclenchement sont situés dans /usr/local/P4wnP1/scripts. Si un script est appelé depuis une Action de Déclenchement, plusieurs arguments (comme le déclencheur réel) sont transmis via des variables bash. Le fichier /usr/local/P4wnP1/scripts/trigger-aware.sh fournit un bon exemple d'un script bash qui agit différemment selon le déclencheur appelant. Il vaut la peine de jeter un œil à ce script, car il utilise toutes les « variables d'Actions de Déclenchement » actuellement disponibles.
La communauté de l'ancienne version de P4wnP1 a parfois proposé des modifications matérielles ou des extensions du Raspberry PI et la question de savoir comment les intégrer. Il ne m'est pas possible de fournir une solution générique à ce problème. Ce n'est pas non plus une bonne idée de fournir un support pour une extension matérielle très spécifique, qui n'est utilisée que par peu de personnes. Avec l'introduction des Actions de Déclenchement, l'idée est venue de supporter les GPIO à la fois comme déclencheurs via une entrée GPIO et comme actions émettant une sortie GPIO. Bien que non prévu pour la première version, cette fonctionnalité a déjà été implémentée. Je n'ai toujours pas eu le temps de la documenter et il pourrait facilement arriver que certaines choses changent. La fonctionnalité utilise la bibliothèque « periph.io » avec quelques extensions mineures (détection de front personnalisée avec anti-rebond personnalisé pour GPIO, merci à @marcaruel pour les échanges à ce sujet)
Le firmware WiFi inclus avec P4wnP1 A.L.O.A. a été modifié (en utilisant le framework nexmon) pour supporter KARMA. Cette fonctionnalité n'a pas encore été intégrée au cœur (nécessite une refonte du firmware) et n'est donc pas disponible depuis le client web ou la CLI. Si vous voulez expérimenter les fonctionnalités karma, il existe une CLI Python héritée qui permet de définir les options KARMA à la volée. Le script Python se trouve ici :
/usr/local/P4wnP1/legacy/karmatool.py
Astuce : Pour tirer le meilleur parti de la fonctionnalité KARMA, vous devriez configurer P4wnP1 A.L.O.A. pour fournir un point d'accès WiFi sans authentification, sinon cela n'aurait pas beaucoup de sens. Pour une inondation de balises pauvre, ce n'est pas nécessaire, mais les SSID personnalisés (statiques) pour le balisage sont limités en nombre (économie de ressources sur la puce WiFi)
RePo: https://github.com/mame82/P4wnP1_nexmon_additions Creds to: seemoo-lab for "NEXMON" project
A hostapd based Access Point should be up and running, when using this tool (see the README for details).
Usage: python karmatool.py [Arguments]
Arguments: -h Print this help screen -i Interactive mode -d Load default configuration (KARMA on, KARMA beaconing off, beaconing for 13 common SSIDs on, custom SSIDs never expire) -c Print current KARMA firmware configuration -p 0/1 Disable/Enable KARMA probe responses -a 0/1 Disable/Enable KARMA association responses -k 0/1 Disable/Enable KARMA association responses and probe responses (overrides -p and -a) -b 0/1 Disable/Enable KARMA beaconing (broadcasts up to 20 SSIDs spotted in probe requests as beacon) -s 0/1 Disable/Enable custom SSID beaconing (broadcasts up to 20 SSIDs which have been added by the user with '--addssid=' when enabled) --addssid="test" Add SSID "test" to custom SSID list (max 20 SSIDs) --remssid="test" Remove SSID "test" from custom SSID list --clearssids Clear list of custom SSIDs --clearkarma Clear list of karma SSIDs (only influences beaconing, not probes) --autoremkarma=600 Auto remove KARMA SSIDs from beaconing list after sending 600 beacons without receiving an association (about 60 seconds, 0 = beacon forever) --autoremcustom=3000 Auto remove custom SSIDs from beaconing list after sending 3000 beacons without receiving an association (about 5 minutes, 0 = beacon forever)
Example: python karmatool.py -k 1 -b 0 Enables KARMA (probe and association responses) But sends no beacons for SSIDs from received probes python karmatool.py -k 1 -b 0 Enables KARMA (probe and association responses) and sends beacons for SSIDs from received probes (max 20 SSIDs, if autoremove isn't enabled)
python karmatool.py --addssid="test 1" --addssid="test 2" -s 1 Add SSID "test 1" and "test 2" and enable beaconing for custom SSIDs
### Canal caché WiFi
Le canal caché WiFi n'a pas été porté vers Go et ne fait pas partie du noyau P4wnP1. Quoi qu'il en soit, la fonctionnalité héritée est fournie. Pour que le canal caché fonctionne, plusieurs conditions doivent être remplies :
- une injection de frappes doit être appliquée au client cible pour injecter stage1
- stage1 charge stage2 via une version simplifiée du canal caché HID, donc un périphérique HID USB spécial doit être fourni et un serveur de canal caché HID spécial doit être démarré sur P4wnP1, afin de fournir stage2
- un second serveur doit être démarré et interfacer le firmware WiFi modifié, afin de gérer les clients se connectant via le canal caché WiFi et fournir un accès shell interactif à ces clients (le serveur est une application console destinée à fonctionner dans un multiplexeur de terminal, comme `screen`)
Toutes les conditions susmentionnées pourraient être remplies en utilisant l'ensemble des fonctionnalités de P4wnP1 A.L.O.A., si les composants nécessaires (stager HID, serveur de canal caché WiFi, agent client à livrer) sont fournis.
Mener une telle tâche avec P4wnP1 A.L.O.A. est un excellent exemple de ses capacités. De plus, cela aide à distinguer ce que P4wnP1 A.L.O.A. est censé être et ce qu'il n'est pas censé être.
P4wnP1 A.L.O.A. n'est pas censé :
- être un outil "armé"
- fournir des payloads RTR, que tout le monde pourrait exécuter sans comprendre ce qui se passe ou quels risques sont impliqués
P4wnP1 A.L.O.A. est censé :
- être une plateforme flexible, peu coûteuse, de poche
- servir de facilitateur pour des tâches comme celle décrite ici
- soutenir le prototypage, les tests et l'exécution de toutes sortes de tâches liées à l'USB, couramment utilisées lors d'engagements de pentest ou de redteam, sans fournir une solution statique finalisée
Dans un certain sens, le dossier `/usr/local/P4wnP1/legacy` abrite les outils externes nécessaires pour exécuter le canal caché WiFi (à savoir le serveur WiFi, le serveur stager du canal caché HID et l'agent client du canal caché WiFi). Ces composants peuvent être considérés comme des parties externes (n'appartiennent pas au noyau de P4wnP1 A.L.O.A.).
De plus, P4wnP1 A.L.O.A. fournit une configuration qui utilise les composants donnés pour effectuer les actions suivantes :
- attaque drive-by contre des hôtes Windows afin de livrer du code client en mémoire pour télécharger stage2 via le canal caché HID, basé sur une injection de frappes (HIDScript)
- démarrer l'injection de frappes dès que P4wnP1 est connecté à un hôte USB (TriggerAction émettant HIDScript)
- lancer le stager, qui livre l'agent client du canal caché WiFi via le canal caché HID, dès que l'injection de frappes commence (TriggerAction exécutant un script bash, qui à son tour démarre le serveur externe)
- lancer le serveur de canal caché WiFi, si nécessaire (même TriggerAction et BashScript)
- déployer une configuration USB qui fournit un clavier USB (pour permettre l'injection de frappes) et un périphérique HID brut supplémentaire (sert de canal caché pour la livraison de stage2) - les paramètres USB sont stockés dans un modèle de paramètres
- déployer une configuration WiFi, qui permet un accès distant à P4wnP1, afin de permettre l'interaction avec l'interface CLI du serveur de canal caché WiFi - les paramètres WiFi sont stockés dans un modèle de paramètres
- fournir un point d'entrée unique, pour déployer toutes les configurations nécessaires en une fois (effectué par un Master Template, qui comprend les paramètres WiFi appropriés, les paramètres USB appropriés et les TriggerActions nécessaires pour démarrer le HIDScript)
Le Master Template s'appelle "wifi covert channel". En le déployant depuis l'onglet "generic settings" du client web ("DEPLOY STORED" depuis l'éditeur de Master Template), P4wnP1 A.L.O.A. est prêt configuré pour exécuter toutes les étapes décrites.
Dès qu'il est reconnecté à un hôte USB, il devrait commencer à taper stage1 et les serveurs correspondants sont démarrés en interne.
Depuis une session SSH (par exemple via WiFi), le serveur de canal caché WiFi peut être accédé en utilisant `screen -d -r wifi_c2` pour interagir avec les clients qui se sont reconnectés via le canal caché WiFi.
Comme l'injection de frappes dépend de la disposition linguistique de l'hôte USB, le HIDScript correspondant appelé `wifi_covert_channel.js` a une variable `language` qui peut être utilisée pour ajuster la disposition du clavier utilisée. De plus, il y a une variable appelée `hide` (false par défaut). Si `hide` est défini sur true, la fenêtre de console sur le client est masquée pendant que stage1 est tapé. Cela souligne encore comment des tâches complexes peuvent être réduites à une simple variable booléenne, grâce à HIDScript et au moteur JavaScript sous-jacent.
La démo "wifi covert channel" fournie avec les Master Templates de P4wnP1 peut également être utilisée comme Startup Master Template, car l'accès WiFi est toujours possible et ainsi la configuration peut être modifiée à nouveau, à distance à tout moment.
Le BashScript impliqué, qui est appelé depuis une TriggerAction, est un bon exemple de la flexibilité que le client CLI peut atteindre. Comme le stager HID doit savoir sur quel fichier de périphérique écouter (celui qui représente le périphérique HID générique), mais cette information n'est disponible qu'au moment de l'exécution (dépend des fonctions USB gadget activées), le script demande au CLI de rapporter le périphérique HID correct en exécutant `hidraw=$(P4wnP1_cli usb get device raw)`.
Le BashScript complet est hébergé dans le dossier `/usr/local/P4wnP1/scripts`, comme tous les scripts bash qui doivent être accessibles depuis les TriggerActions.
### Bluetooth NAP
P4wnP1 fournit des fonctionnalités réseau basées sur Bluetooth via le Bluetooth Network Encapsulation Protocol (BNEP). La fonctionnalité actuellement la plus intéressante est le Bluetooth Network Access Point (NAP), qui permet un accès distant IP via Bluetooth à P4wnP1, par exemple depuis des mobiles.
Pour utiliser cette fonctionnalité, certaines choses doivent être connues :
- L'interface réseau Bluetooth, appelée `bteth`, peut être configurée et modélisée comme les autres interfaces réseau (webclient ou CLI)
- Pour autoriser l'accès NAP depuis un mobile Android (iPhone non testé), le mobile doit non seulement se connecter, mais en plus P4wnP1 doit fournir une IP appropriée pour la passerelle par défaut sur l'interface `bteth` via DHCP. En effet, le mobile souhaite utiliser le NAP comme passerelle vers Internet (ce qui serait l'utilisation prévue). Si le NAP lui-même ne fournissait pas de passerelle, le mobile Android n'effectuerait plus aucune demande après le DHCP D.O.R.A. La manière la plus simple de contourner ceci est d'instruire le serveur DHCP pour qu'il fournisse l'IP de l'interface `bteth` elle-même comme passerelle par défaut (option DHCP 3). Même s'il n'y a pas de véritable connexion amont, cela a fonctionné lors de mes tests - car le mobile doit accéder à la passerelle avec une communication couche 3 pour "phone home". Même si les tests de connectivité successifs échouent, la connexion couche 3 fonctionnelle persiste. Cela permet, par exemple, un accès SSH via Bluetooth. Avec "High Speed" activé, le webclient fonctionne également très bien.
- Pour permettre l'appairage basé sur un code PIN, Simple Secure Pairing (SSP) doit être désactivé. Si SSP est activé, l'agent d'appairage en cours confirme chaque mot de passe (ce qui signifie encore moins de sécurité qu'avec l'appairage PIN hérité, car tout appareil peut se connecter). Peut-être qu'une boîte de dialogue de confirmation pour l'appairage basé sur le mot de passe SSP sera implémentée pour le CLI/webclient à l'avenir, mais actuellement cela ne fait pas partie du champ d'application. Je suggère fortement de désactiver 'discoverable' et 'bondable' si SSP est utilisé, dès que l'appareil prévu est appairé.
- Un autre inconvénient d'avoir SSP désactivé est que 'High Speed' ne serait pas utilisable pour les connexions Bluetooth (ou pour activer High Speed, l'appairage doit être fait avec SSP). Sans 'High Speed' activé (utilise des trames 802.11 pour la communication), il faudrait environ 10 minutes pour demander le webclient, avec high speed activé cela prend quelques secondes. Utiliser SSH et le client CLI sur un NAP sans 'High Speed' devrait néanmoins convenir.
- Les paramètres par défaut de l'interface réseau Bluetooth (`bteth_startup`) et les paramètres Bluetooth par défaut (`startup`) devraient permettre un accès 'Low Speed' via SSH avec appairage PIN hérité. Le code PIN est `1337` et peut être modifié depuis le webclient.
### Groupes TriggerAction
Les TriggerActions sont dotées d'une capacité de rattachement intéressante appelée 'Groups'. Je n'ai pas réussi à proposer une démo de fonctionnalité à temps, mais je prévois d'inclure un exemple de compteur binaire 4 bits basé sur des LEDs (utilisant des GPIOs, un interrupteur à bascule et 4 LEDs).
L'idée des groupes est la suivante :
Considérez que vous souhaitez avoir 4 TriggerActions (TAs) se déclenchant sur le même Trigger (par exemple 'on attached to USB host'). Vous pourriez y parvenir en créant 4 TAs, chacune avec le Trigger 'on attached to USB host'.
Alternativement, vous pourriez créer une TriggerAction qui envoie la valeur `1` à un groupe nommé `'connected'` lorsque le 'on attached to USB host' se produit. Ensuite, vous définissez vos autres 4 TriggerActions pour se déclencher lorsque la valeur `1` est reçue sur un groupe nommé `'connected'`. Le résultat serait le même et n'aurait pas beaucoup de sens pour l'instant (en fait cela nécessite une TriggerAction supplémentaire). Le seul effet positif, pour l'instant, est que les TriggerActions sont légèrement plus lisibles, grâce au nom du groupe, qui peut être choisi librement.
Maintenant, la première chose avancée que vous pourriez faire est d'exécuter la commande CLI suivante :```
P4wnP1_cli trigger send --group-name=connected --group-value=1
Cette commande aurait exactement le même effet que la TriggerAction « on attached to USB host » et toutes les 4 autres TA, qui attendent la valeur 1 sur le groupe connected, se déclencheraient. Comme vous vous en souvenez peut-être, le client CLI peut s'exécuter à distance (depuis différentes plateformes), il pourrait donc être utilisé pour déclencher une commande à distance.
La Trigger qui réagit aux « canaux de groupe » s'appelle « value on group channel ». La Trigger la plus intéressante s'appelle « multiple values on group channel ». Cette trigger « multiple values » permet d'écouter des séquences ordonnées de valeurs, ou une seule valeur parmi plusieurs, ou toutes les valeurs dans une séquence non ordonnée, avant de se déclencher.
Disons que vous voulez déclencher un script Bash lorsque ces conditions sont remplies :
Vous pourriez créer des TA pour les deux événements comme ceci :
Vous pourriez ensuite déployer une troisième TriggerAction comme ceci :
Dans cette configuration, le script bash ne se lancerait que si les deux triggers « conditions » ont été déclenchées.
Si l'on avait utilisé « exact ordered sequence » au lieu de « All (logical AND) » comme type, le script bash ne se lancerait que si le point d'accès WiFi s'active avant la trigger « USB connected » (et non l'inverse). Combiné avec des triggers GPIO, cela pourrait par exemple être utilisé pour déclencher des actions basées sur la saisie d'un simple clavier à code PIN.
Je suis sûr que vous avez de bonnes idées d'utilisation pour les canaux de groupe.
À noter :
Le client CLI peut effectuer une attente bloquante jusqu'à ce qu'une valeur spécifique arrive sur un « canal de groupe », en utilisant une commande comme ceci :``` P4wnP1_cli trigger wait --group-name=waitgroup --group-value=1
Cela pourrait être utilisé pour piloter des scripts depuis TriggerActions, en utilisant la CLI (avec toute leur puissance comme GPIO).
En cours de développement, sections manquantes :
- Variables de déclenchement HIDScript (variables transmises aux HIDScripts déclenchés depuis TriggerActions)
- Aides HIDScript (fonctions powershell)
- Démo serpent HIDScript (souris)
- Stockage de masse USB (helper genimg)
## 4. Sauvetage : Aide, je n'arrive plus à accéder à P4wnP1 A.L.O.A. car j'ai mal configuré
P4wnP1 A.L.O.A. ne vous protège pas des mauvaises configurations qui le rendent inutilisable (tout comme une console root ne vous protégerait pas de l'exécution de `rm -rf /`).
Si vous avez tout gâché, voici quelques idées pour résoudre les problèmes :
### Sauvegarde de la base de données
Avant d'apporter des modifications critiques à une configuration P4wnP1 encore fonctionnelle, créez une sauvegarde de la base de données. Cela peut être fait depuis l'onglet « Paramètres génériques » du client Web ou via la CLI, avec la commande `P4wnP1_cli db backup`.
La sauvegarde sera stockée dans le dossier `/usr/local/P4wnP1/db` sous le nom choisi.
La fonction « restaurer » ou la commande `P4wnP1_cli db restore` peut être utilisée pour restaurer une sauvegarde donnée.
Une sauvegarde contient tous les modèles stockés (USB, WiFi, Réseau, Bluetooth, TriggerActions, MasterTemplates) ainsi que le Master Template de démarrage qui a été défini. La sauvegarde n'inclut pas les HIDScripts ou BashScripts, car ceux-ci sont stockés sous forme de fichiers pour permettre une édition facile.
### Je n'ai pas de sauvegarde et j'ai tout gâché
Lorsque P4wnP1 A.L.O.A. démarre, il vérifie si une base de données existe. Si la base de données n'existe pas, il en crée une nouvelle à partir d'une sauvegarde initiale fournie avec P4wnP1 A.L.O.A.
La sauvegarde initiale se trouve à `/usr/local/P4wnP1/db/init.db` et **ne doit jamais être supprimée ou écrasée**.
Afin de forcer la recréation, la base de données réelle doit être supprimée. Pour ce faire, montez la carte SD de P4wnP1 A.L.O.A. sur un système capable d'écrire sur des partitions EXT.
Une fois fait, supprimez le dossier `/usr/local/P4wnP1/store` de la partition racine de la carte SD. Cela supprime la base de données et force ainsi sa recréation au prochain démarrage de P4wnP1.
### J'ai une sauvegarde, mais je ne peux pas accéder à P4wnP1 pour la restaurer
Si vous ne pouvez pas restaurer une base de données existante parce que vous n'avez pas accès, vous pouvez toujours suivre les étapes de la section « Je n'ai pas de sauvegarde et j'ai tout gâché ». En plus de la suppression de `/usr/local/P4wnP1/store`, remplacez le fichier `/usr/local/P4wnP1/db/init.db` par celui de votre sauvegarde (assurez-vous d'avoir une copie de sauvegarde de init.db).
Cela devrait recréer votre base de données personnalisée au prochain redémarrage de P4wnP1.
### J'ai gâché le Master Template de démarrage de ma sauvegarde
Si vous avez une sauvegarde pour laquelle le Master Template de démarrage ne fonctionne pas, vous devez effectuer quelques étapes supplémentaires, car il n'est pas possible de modifier directement le Template de démarrage dans une sauvegarde.
Suivez d'abord les étapes de la section « Je n'ai pas de sauvegarde et j'ai tout gâché » qui recréent la base de données initiale de P4wnP1.
Après un redémarrage de P4wnP1, vous devriez pouvoir accéder à nouveau au client Web de P4wnP1 à distance.
Rendez-vous dans les « Paramètres génériques » et restaurez votre propre sauvegarde (celle avec le mauvais Master Template de démarrage).
Le « Master Template de démarrage » devrait afficher votre Master Template « cassé » comme sélectionné. Si ce n'est pas le cas, rechargez l'onglet du navigateur hébergeant l'application client Web.
Naviguez à nouveau jusqu'à l'onglet « Paramètres génériques » et sélectionnez un Master Template de démarrage connu pour fonctionner.
À ce stade, vous devriez être prêt à redémarrer.
### Rien de ce qui précède n'a aidé
Désolé, il semble que vous deviez recréer votre carte SD P4wnP1 A.L.O.A. à partir d'une image propre.
## 5. Crédits
En construction, ordre aléatoire
- @JohanBrandhorst (échange rapproché sur gRPC-web via gopherjs, implémentation ridiculement rapide de « websocket pour streaming serveur », demande de fonctionnalité)
- @steevdave, @_binkybear (scripts de construction Kali, discussion et échange continus)
- @Re4sonKernel (Soutien pour le déplacement des modifications du noyau P4wnP1 vers un dépôt bien maintenu et populaire, collaboration sur les correctifs Bluez)
- @SymbianSyMoh (Inspiration pour la réactivation de l'attaque HID sans redémarrage)
- @quasarframework (pourrait figurer sous les bibliothèques tierces, mais le travail accompli ici est incroyable ; l'apparence du client Web P4wnP1 est plus ou moins basée sur les composants par défaut de cette magnifique bibliothèque)
- @CyberArms (l'un des tout premiers supporters de P4wnP1, auteur du meilleur tutoriel et même de livres sur ces sujets)
- @LucaBongiorni (non seulement l'un des premiers supporters, il fait en matériel ce que je ne peux faire qu'en logiciel ; il donne des conférences sur le thème USB et honore les solutions Open Source, bref un gars génial et une inspiration)
- @evilsocket (son bloc m'a poussé vers Go, un excellent développeur OSS, lisez son code et vous comprendrez ce que je veux dire)
- @RoganDawes et @Singe de @SensePost (gars inspirants)
- @Swiftb0y (Premier supporter, créateur du « vieux » Wiki P4wnP1, testeur précoce pour les idées sur P4wnP1 A.L.O.A.)
- @marcaruel (discussion sur la détection de front sur GPIO en utilisant periph.io)
## 6. À faire et soutien
Ce n'est pas une liste exhaustive des tâches, mais quelques jalons restent, et je serai ravi de recevoir du soutien de la communauté pour ceux-ci :
- Porter l'intégralité des fonctionnalités du canal caché HID vers le noyau Go (je suis seul sur ce point)
- **ajouter la commande de configuration Bluetooth pour la CLI**
- Créer des dispositions de clavier supplémentaires (actuellement br, de, es, fr, gb, it, ru et us sont pris en charge)
- Étendre les fonctionnalités Bluetooth pour permettre la connexion à d'autres appareils découvrables (authentification et confiance)
- Déplacer la fonctionnalité WiFi KARMA d'un outil Python dédié vers le noyau P4wnP1 (avec support du client Web)
- Créer une documentation complète pour HIDScript (il manque essentiellement la partie souris)
- Créer une documentation complète pour P4wnP1 (en espérant l'aide de la communauté)
- Se débarrasser d'une dépendance restante au netlink Docker (voir README du dossier `netlink`)
Note sur Bluetooth :
P4wnP1 fonctionne avec des liaisons personnalisées à l'API Bluez. Bien que l'API Bluez prenne en charge le Low Energy (GATT, émulation de périphériques, etc.), il n'est pas prévu d'intégrer cette fonctionnalité dans P4wnP1 A.L.O.A.
Note sur Nexmon :
P4wnP1 utilise nexmon. La plupart des gens connaissent nexmon comme une modification du firmware qui permet d'activer le mode moniteur et l'injection de paquets pour les puces WiFi Broadcom (y compris la BCM43430a1 utilisée par le Raspberry Pi Zero W). Mais nexmon est plus que cela : c'est un framework qui permet de modifier des blobs de firmware ARM (après un peu de rétro-ingénierie), avec des correctifs écrits en code C de haut niveau. P4wnP1 utilise ce framework pour appliquer des correctifs personnalisés au firmware WiFi, permettant ainsi le support matériel de KARMA et le support du firmware (ainsi que du pilote) pour le canal caché WiFi. Ces modifications n'ont pas pour but de fournir un mode moniteur ou une injection correcte pour l'interface WiFi intégrée. Bien que la fonctionnalité de mode moniteur héritée de nexmon soit incluse dans le firmware WiFi actuel, elle est considérée comme « erronée » car elle interfère avec les fonctionnalités WiFi standard utilisées par P4wnP1 (crashs si l'interface est utilisée en mode station, etc.).
## 7. Droits d'auteur
P4wnP1 A.L.O.A.
Copyright (C) 2018 Marcus Mengs
Ce programme est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
selon les termes de la Licence Publique Générale GNU telle que publiée par
la Free Software Foundation ; soit la version 3 de la Licence, soit
(à votre discrétion) toute version ultérieure.
Ce programme est distribué dans l'espoir qu'il sera utile,
mais SANS AUCUNE GARANTIE ; sans même la garantie implicite de
COMMERCIALISATION ou d'ADAPTATION À UN USAGE PARTICULIER. Voir la
Licence Publique Générale GNU pour plus de détails.
Vous devriez avoir reçu une copie de la Licence Publique Générale GNU
avec ce programme ; si ce n'est pas le cas, consultez <http://www.gnu.org/licenses/>.