Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
P4wnP1_aloa — P4wnP1 A.L.O.A. by MaMe82 è un framework che trasforma un Rapsberry Pi Zero W in una piattaforma flessibile e a basso costo per pentesting, red teaming e physical engagements ... o in "A Little Offensive Appliance". | Kitploit
Strumenti/GitHubGitHub/rogandawes/p4wnp1_aloa
Auditing Wi-FiSicurezza BluetoothFramework di ExploitMappatura della ReteHacking HardwarePenetration TestingRed TeamingSviluppo Payload
GitHubrogandawes/p4wnp1_aloa

P4wnP1_aloa

P4wnP1 A.L.O.A. by MaMe82 è un framework che trasforma un Rapsberry Pi Zero W in una piattaforma flessibile e a basso costo per pentesting, red teaming e physical engagements ... o in "A Little Offensive Appliance".

Vedi Repository
4.4k5802 anni faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

P4wnP1 A.L.O.A.

P4wnP1 A.L.O.A. di MaMe82 è un framework che trasforma un Raspberry Pi Zero W in una piattaforma flessibile e a basso costo per penetration testing, red teaming e impegni fisici ... o in "A Little Offensive Appliance".

0. Come installare

L'ultima immagine si trova nella scheda delle release.

Il modo più semplice per accedere a una nuova installazione di P4wnP1 A.L.O.A. è utilizzare il client web tramite il WiFi generato (il PSK è MaMe82-P4wnP1, l'URL http://172.24.0.1:8000) o SSH (password predefinita toor).

1. Funzionalità

Emulazione di dispositivi USB Plug&Play

  • Funzioni USB:
    • Ethernet USB (RNDIS e CDC ECM)
    • Seriale USB
    • Memoria di massa USB (Flashdrive o CD-Rom)
    • Tastiera HID
    • Mouse HID
  • riconfigurazione runtime dello stack USB (senza riavvio)
  • il rilevamento di connessione/disconnessione consente di mantenere acceso P4wnP1 A.L.O.A (alimentazione esterna) e attivare un'azione se il dispositivo USB emulato viene collegato a un nuovo host
  • non è necessario gestire diverse interfacce ethernet interne, poiché CDC ECM e RNDIS sono collegati a un bridge virtuale
  • salvataggio e caricamento persistenti di modelli di configurazione per le impostazioni USB

HIDScript

  • sostituzione per il limitato DuckyScript
  • linguaggio di scripting sofisticato per automatizzare tastiera e mouse
  • fino a 8 job HIDScript possono essere eseguiti in parallelo (tenere un job attivo per muovere il mouse, mentre altri vengono avviati su richiesta per eseguire iniezioni di mouse e tasti arbitrari senza soluzione di continuità)
  • HIDScript è basato su JavaScript, con librerie comuni disponibili, che consente script più complessi (chiamate di funzioni, uso di Math per calcoli del mouse ecc.)
  • tastiera
    • basata su UTF-8, quindi non c'è limitazione ai caratteri ASCII
    • può reagire al feedback della tastiera reale dell'host leggendo i cambiamenti di stato dei LED di BLOC NUM, BLOC MAIUSC e BLOC SCORR (se il sistema operativo target condivide lo stato dei LED su tutte le tastiere collegate, cosa che non accade per OSX)
    • prendere decisioni di ramificazione in HIDScript, basate sul feedback dei LED
  • mouse
    • movimento relativo (veloce, ma non preciso)
    • movimento relativo a passi (più lento, ma accurato ... muove il mouse a passi di 1 DPI)
    • posizionamento assoluto su Windows (perfetto al pixel se le dimensioni dello schermo del target sono note)
  • Tastiera e mouse non sono solo controllati dallo stesso linguaggio di scripting, entrambi possono essere usati nello stesso script. Questo consente di combinarli per raggiungere obiettivi che non potrebbero essere raggiunti usando solo tastiera o mouse.
  • layout di lingua attuali: br, de, es, fr, gb, it, ru e us

Bluetooth

  • interfaccia completa allo stack Bluez (attualmente nessun supporto per rilevamento/connessione di dispositivi remoti)
  • permette di eseguire un Punto di Accesso di Rete Bluetooth (NAP)
  • associazione personalizzabile (modalità legacy basata su PIN o SSP)
  • supporto per l'Alta Velocità (utilizza frame 802.11 per ottenere velocità di trasferimento simili al WiFi)
  • Riconfigurazione runtime dello stack Bluetooth
  • Nota: anche PANU è possibile, ma attualmente non supportato (nessuna connessione a dispositivi remoti)
  • salvataggio e caricamento persistenti di modelli di configurazione per le impostazioni Bluetooth

WiFi

  • firmware modificato (costruito con il framework Nexmon)
    • permette KARMA (spoof di risposte valide per Access Point sondati da dispositivi remoti e consente l'associazione)
    • trasmette Beacons aggiuntivi, per emulare più SSID
    • canale nascosto WiFi
    • Nota: la modalità monitor legacy di Nexmon è inclusa, ma non supportata da P4wnP1. La modalità monitor è ancora instabile e potrebbe far crashare il firmware se la configurazione cambia.
  • configurazione facile del punto di accesso
  • configurazione facile della modalità stazione (connessione a un AP esistente)
  • modalità failover (se non è possibile connettersi all'Access Point target, avvia un proprio Access Point)
  • riconfigurazione runtime dello stack WiFi
  • salvataggio e caricamento persistenti di modelli di configurazione per le impostazioni WiFi

Rete

  • facile configurazione dell'interfaccia ethernet per
    • interfaccia NAP bluetooth
    • interfaccia USB (se RNDIS/CDC ECM è abilitato)
    • interfaccia WiFi
  • supporta un server DHCP dedicato per interfaccia
  • supporto per la modalità client DHCP
  • configurazione manuale
  • salvataggio e caricamento persistenti di modelli di configurazione per ogni interfaccia

Strumenti

Non c'è molto da dire qui, P4wnP1 A.L.O.A. è basato su KALI Linux, quindi tutto dovrebbe essere a portata di mano (o può essere installato usando apt)

Configurazione e controllo tramite CLI, anche da remoto

  • tutte le funzionalità menzionate finora possono essere configurate utilizzando un client CLI
  • il servizio core di P4wnP1 è un singolo binario, eseguito come unità systemd che preserva lo stato runtime
  • il client CLI si interfaccia con questo servizio tramite RPC (gRPC per essere precisi) per modificare lo stato del core
  • poiché la CLI utilizza un approccio RPC, può essere utilizzata anche per la configurazione remota
  • se si accede a P4wnP1 tramite SSH, il client CLI è lì, in attesa dei tuoi comandi (o delle tue abilità di completamento con tab)
  • la CLI è scritta in Go (come la maggior parte del codice) e quindi si compila per la maggior parte delle piattaforme e architetture principali

Quindi se vuoi usare un file batch in esecuzione su un host Windows remoto per configurare P4wnP1 ... nessun problema:

  1. compila il client per Windows
  2. assicurati di poter connetterti a P4wnP1 in qualche modo (Bluetooth, WiFi, USB)
  3. aggiungi il parametro host ai tuoi comandi client
  4. ... e usa la CLI come faresti con accesso locale.

Configurazione e controllo tramite client web

Sebbene non fosse inizialmente previsto, P4wnP1 A.L.O.A. può essere configurato utilizzando un client web. Anche se il client non era previsto, si è evoluto in un bel software. Di fatto è diventato il principale strumento di configurazione per P4wnP1 A.L.O.A. Il client web ha funzionalità che non possono essere accessibili dalla CLI (archiviazione di modelli, creazione di "TriggerActions").

Le funzionalità principali:

  • dovrebbe funzionare sulla maggior parte dei browser mobili e desktop, con aspetto e sensazione coerenti (Quasar Framework)
  • utilizza gRPC tramite websocket (nessuna API RESTful, nessuna XHR, approccio quasi identico alla CLI)
  • Grazie a questa interfaccia, il client web non si basa solo su uno schema richiesta-risposta, ma riceve "push event" dal core di P4wnP1. Ciò significa:
    • se tu (o uno script) modifichi lo stato di P4wnP1 A.L.O.A., queste modifiche verranno immediatamente riflesse nel client web
    • se hai più client web in esecuzione, le modifiche allo stato del core verranno riflesse da un client a tutti gli altri client
  • include un editor HIDScript, con
    • evidenziazione della sintassi
    • completamento automatico (CTRL+SPACE)
    • archiviazione e caricamento persistenti per HIDScript
    • esecuzione su richiesta di HIDScript direttamente dal browser
    • un gestore di job HIDScript (annulla job in esecuzione, ispeziona stato e risultati dei job)
  • include una panoramica e un editor per TriggerActions
  • supporto completo per modelli su tutte le funzionalità descritte finora
  • il WebClient è una Single Page Application, una volta caricato tutto viene eseguito lato client, vengono scambiate solo richieste gRPC

Automazione

L'approccio di automazione della vecchia versione di P4wnP1 (script bash statici) non poteva più essere utilizzato.

L'approccio di automazione di P4wnP1 A.L.O.A. doveva soddisfare questi requisiti:

  • facile da usare e comprendere
  • utilizzabile da un client web
  • essere generico e flessibile, allo stesso tempo
  • tutto ciò che era possibile con il vecchio approccio "bash script", dovrebbe essere ancora possibile
  • in grado di accedere a tutti i sottosistemi (USB, WiFi, Bluetooth, Interfacce Ethernet, HIDScript ...)
  • modulare, con parti riutilizzabili
  • capacità di supportare compiti logici (semplici) senza scrivere codice aggiuntivo
  • consentire il physical computing, utilizzando le porte GPIO

Con l'introduzione dei cosiddetti "TriggerActions" e combinandoli con il sistema di modelli (archiviazione persistente delle impostazioni per tutti i sottosistemi) tutti i requisiti possono essere soddisfatti. I dettagli sui TriggerActions si trovano nella sezione WorkFlow.

Tutorial di utilizzo

2. Flusso di lavoro parte 1 - HIDScript

P4wnP1 A.L.O.A. non utilizza concetti come configurazione statica o payload. In effetti non ha affatto un flusso di lavoro statico.

P4wnP1 A.L.O.A. è pensato per essere il più flessibile possibile, per permettere di usarlo in tutti gli scenari possibili (inclusi quelli a cui non ho potuto pensare durante la creazione di P4wnP1 A.L.O.A.).

Ma ci sono alcuni concetti di base che vorrei illustrare in questa sezione. Poiché è difficile spiegare tutto senza creare una documentazione (video) adeguata, esploro alcuni casi d'uso ed esempi comuni per spiegare ciò che deve essere spiegato.

Tuttavia, è improbabile che avrò il tempo di fornire una documentazione completa. Quindi incoraggio tutti a supportarmi con tutorial e idee, che potrebbero essere collegati a questo README

Ora iniziamo con uno dei compiti più basici:

2.1 Eseguire un'iniezione di tasti contro un host a cui P4wnP1 è collegato via USB

Il requisito di configurazione minimo per raggiungere questo obiettivo è:

  • Il sottosistema USB è configurato per emulare almeno una tastiera
  • C'è un modo per accedere a P4wnP1 (da remoto), al fine di avviare l'iniezione di tasti

La configurazione predefinita di P4wnP1 (immagine non modificata) soddisfa già questi requisiti:

  • le impostazioni USB sono inizializzate per fornire tastiera, mouse e ethernet via USB (sia RNDIS che CDC ECM)
  • P4wnP1 può già essere accessibile da remoto, utilizzando uno dei seguenti metodi:
    • WiFi
      • il nome dell'Access Point dovrebbe essere ovvio
      • la password è MaMe82-P4wnP1
      • l'IP di P4wnP1 è 172.24.0.1
    • Ethernet USB
      • l'IP di P4wnP1 è 172.16.0.1
    • Bluetooth
      • nome dispositivo P4wnP1
      • PIN 1337
      • l'IP è 172.26.0.1
      • Nota: Secure Simple Pairing è disattivato per forzare l'associazione tramite PIN. Questo significa anche che la modalità ad alta velocità è disattivata. Quindi la connessione bluetooth è molto lenta, il che è meno problematico per l'accesso SSH, ma richiedere il client web potrebbe richiedere fino a 10 minuti (in contrasto con alcuni secondi con la modalità ad alta velocità abilitata).
  • un server SSH è accessibile da tutti gli IP sopra menzionati
  • L'utente SSH per KALI Linux è root, la password predefinita è toor
  • Il client web può essere raggiunto su tutte e tre le connessioni sulla porta 8000 via HTTP

Nota: La distribuzione di una connessione HTTPS non è attualmente nell'ambito del progetto. Quindi tieni presente questo, se gestisci dati sensibili, come le credenziali WiFi, nel client web. L'intero progetto non è stato costruito pensando alla sicurezza (ed è improbabile che diventi mai un requisito). Quindi adotta misure appropriate (ad es. limitare l'accesso al client web con iptables, se l'Access Point è configurato con autenticazione aperta; non mantenere la Scopribilità e Connettività Bluetooth abilitate senza protezione PIN ecc. ecc.)

A questo punto presumo:

  1. Hai collegato P4wnP1 a un host target tramite USB (la porta più interna delle micro USB del Raspberry è quella da usare)
  2. L'host USB esegue un'applicazione in grado di ricevere le pressioni dei tasti e ha il focus corrente sull'input da tastiera (ad es. un editor di testo)
  3. Sei connesso da remoto a P4wnP1 tramite SSH (il modo migliore è il WiFi), preferibilmente la connessione SSH è in esecuzione da un host diverso da quello a cui è collegato P4wnP1 A.L.O.A. via USB

Per eseguire il client CLI dalla sessione SSH, emetti il seguente comando:``` 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.

root@kitploit:~
La schermata di aiuto mostra già che il client CLI utilizza diversi comandi per interagire con i vari sottosistemi di 
P4wnP1 A.L.O.A. La maggior parte di questi comandi ha a sua volta dei propri sottocomandi. 
L'aiuto per ogni comando o sottocomando può essere visualizzato aggiungendo `-h` al comando 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")

Ora, per digitare "Hello world" sull'host USB, è possibile usare il seguente comando CLI:

P4wnP1_cli hid run -c 'type("Hello world")'

L'output risultante nella sessione SSH dovrebbe apparire simile a questo:``` TempFile created: /tmp/HIDscript295065725 Start appending to 'HIDscript295065725' in folder 'TMP' Result: null

root@kitploit:~
On the USB host "Hello World" dovrebbe essere stato digitato nell'applicazione con il focus della tastiera.

*Se il tuo client SSH è in esecuzione sull'host USB stesso, il "Hello world" digitato finisce da qualche parte tra l'output risultante del comando CLI (non appartiene all'output, ma è stato digitato nel mezzo).*

**Obiettivo raggiunto. Abbiamo iniettato sequenze di tasti nel target.**

Molta lettura per un compito semplice come l'iniezione di sequenze di tasti, ma ancora una volta, questa sezione è pensata per spiegare i concetti di base.

### 2.2 Passare a caratteristiche linguistiche più sofisticate di HIDScript

Se sei riuscito a eseguire l'iniezione di sequenze di tasti "Hello world", questo è un buon punto per esplorare alcune funzionalità aggiuntive di HIDScript.

Conosciamo già il comando `type`, ma proviamo a discutere alcuni comandi HIDScript più sofisticati:

#### Premere tasti speciali e combinazioni

Il comando `type` supporta la pressione del tasto Invio, codificando un carattere di "nuova riga" nella stringa di input, in questo modo:

type('Hello world\r\n')

root@kitploit:~
P4wnP1_cli hid run -c 'type("line 1\nline 2\nline 3 followed by pressing RETURN three times\n\n\n")'
```
Ma per quanto riguarda i tasti speciali o le combinazioni di tasti? 

Il comando `press` viene in aiuto!

Usiamo `press` per inviare CTRL+ALT+DELETE all'host USB:```
P4wnP1_cli hid run -c 'press("CTRL ALT DELETE")'
```
*Nota: Due dei tasti erano modificatori (CTRL e ALT) e solo uno era un tasto effettivo (DELETE)*

Premiamo il tasto 'A' senza alcun tasto modificatore:```
P4wnP1_cli hid run -c 'press("A")'
```
Il risultato dovrebbe essere una 'a' minuscola, perché `press("A")` interpreta 'A' come tasto. Il comando `type("A")`, d'altra parte, tenta di premere una combinazione di tasti che dovrebbe produrre un carattere 'A' maiuscolo.

Combiniamo un tasto modificatore e un tasto non modificatore, per produrre un carattere 'A' maiuscolo (imitando il comportamento di `type("A"):```
P4wnP1_cli hid run -c 'press("SHIFT A")'
```
Questo avrebbe dovuto produrre un output con la A maiuscola.

È importante capire che `press` interpreta gli argomenti forniti come tasti, mentre `type` cerca di trovare le combinazioni di tasti appropriate per produrre i caratteri di output desiderati.   

In un ultimo esempio, combiniamo `press` e `type`.```
P4wnP1_cli hid run -c 'type("before caps\n"); press("CAPS"); type("after caps\n"); press("CAPS");'
```
L'ultimo comando ha digitato una stringa, ha attivato CAPSLOCK, ha digitato un'altra stringa e ha disattivato CAPSLOCK. 
Di conseguenza, il CAPSLOCK dovrebbe essere nello stato iniziale (attivato due volte), ma una delle stringhe viene digitata in maiuscolo, l'altra in minuscolo nonostante entrambe le stringhe siano state fornite in minuscolo.

Note aggiuntive sulla pressione dei tasti con `press`:

Non voglio addentrarmi nei dettagli del funzionamento interno dei report delle tastiere USB, ma alcune cose meritano di essere menzionate per evidenziare i limiti e le possibilità del comando `press` (che a sua volta funziona basandosi sui report grezzi della tastiera):
- un report della tastiera può contenere fino a 8 tasti modificatori contemporaneamente
- i tasti modificatori sono
  - LEFT_CTRL
  - RIGHT_CTRL
  - LEFT_ALT
  - RIGHT_ALT
  - LEFT_SHIFT
  - RIGHT_SHIFT
  - LEFT_GUI
  - RIGHT_GUI
- P4wnP1 permette di usare alias per i modificatori comuni
  - CTRL == CONTROL == LEFT_CTRL
  - ALT == LEFT_ALT
  - SHIFT == LEFT_SHIFT
  - WIN == GUI == LEFT_GUI
- oltre ai modificatori, `press` consuma fino a sei tasti normali o speciali
  - i tasti normali rappresentano caratteri e tasti speciali
  - esempi di tasti speciali: BACKSPACE, ENTER (== RETURN), F1 .. F12)
  - i tasti sono indipendenti dal layout della lingua (`press("Z")` produce USB_KEY_Z per il layout EN_US, ma produce USB_KEY_Y per un layout tedesco. Ciò corrisponde alla pressione del tasto hardware 'Z' su una tastiera tedesca, che produrrebbe anch'esso USB_KEY_Y.)
  - `/usr/local/P4wnP1/keymaps/common.json` contiene un keymap JSON formattato con tutti i tasti possibili (fare attenzione a non modificare il file)
- **aggiungere più tasti a un singolo comando `press` non produce una sequenza di tasti.** Tutti i tasti forniti vengono premuti contemporaneamente e rilasciati contemporaneamente.
- `press` rilascia automaticamente i tasti, ciò significa che una sequenza come "tenere premuto ALT, premere TAB, premere TAB, rilasciare ALT" attualmente non è possibile

#### Layout della tastiera

Il comando HIDScript per cambiare il layout della tastiera è `layout(<nome della mappa lingua>)`.

Il seguente esempio cambia il layout della tastiera in 'US', digita qualcosa e cambia il layout in 'Tedesco' prima di continuare a digitare:```
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");'
```
Il risultato dell'output del comando fornito sopra dipende dal layout di destinazione utilizzato dall'host USB. 

Su un host con layout di tastiera tedesco il risultato appare così:```
Tzping with EN?US lazout
Typing with German layout supporting special chars üäö
```
Su un host con layout di tastiera US appare così:```
Typing with EN_US layout
Tzping with German lazout supporting special chars [';
```
Si noti che il risultato desiderato si ottiene solo se il layout della tastiera di P4wnP1 corrisponde al layout della tastiera
effettivamente utilizzata dall'host USB. 

Il comando `layout` permette di allineare il layout interno di P4wwP1 a quello dell'host USB target. 

Essere in grado di cambiare layout durante l'esecuzione di uno script HID può tornare utile: chissà, forse vuoi 
fare brute force sul layout della tastiera dell'host target emettendo comandi con layout diversi finché uno dei comandi digitati
ottiene l'effetto desiderato.

**Importante:** Il layout ha effetto globale. Questo significa che se più script HID sono in esecuzione contemporaneamente e uno di essi
imposta un nuovo layout, anche tutti gli altri script ne vengono immediatamente influenzati.

#### Velocità di digitazione

Per impostazione predefinita, P4wnP1 inietta pressioni di tasti il più velocemente possibile. A seconda del tuo obiettivo, questo potrebbe essere eccessivo (pensa a
contromisure che impediscono l'iniezione di tasti basate sull'analisi comportamentale della velocità di digitazione). HIDScript supporta un
comando per modificare questo comportamento.

`typingSpeed(delayMillis, jitterMillis)`

Il primo argomento del comando `typingSpeed` rappresenta un ritardo costante in millisecondi, applicato tra
due pressioni di tasti. Il secondo argomento è un jitter aggiuntivo in millisecondi. Aggiunge un ritardo casuale aggiuntivo, che
si scala tra 0 e il jitter dato in millisecondi, al ritardo statico fornito con il primo argomento.

Proviamo a usare `typingSpeed` per rallentare la digitazione:```
P4wnP1_cli hid run -c 'typingSpeed(100,0); type("Hello world")'
```
Successivamente, invece di un ritardo costante, proviamo un jitter casuale:```
P4wnP1_cli hid run -c 'typingSpeed(0,500); type("Writing with random jitter up to 500 milliseconds")'
```
Infine, combinando e regolando entrambi i valori, possiamo simulare la velocità di digitazione naturale:```
P4wnP1_cli hid run -c 'typingSpeed(100,150); type("Writing with more natural speed")'
```
**Important:** La velocità di digitazione ha un effetto globale. Ciò significa che se più script HID vengono eseguiti simultaneamente e uno di essi imposta una nuova velocità di digitazione, tutti gli altri script ne vengono immediatamente influenzati.

#### Attesa del report LED

L'attesa del report LED, o più precisamente dei cambiamenti di stato dei LED, è una delle funzionalità più avanzate della tastiera di HIDScript. Può essere molto potente ma richiede un po' di spiegazione.

Potresti aver notato che (a seconda del sistema operativo dell'host USB) i modificatori dello stato della tastiera (BLOC NUM, BLOC SCORR, BLOC MAIUSC) sono condivisi tra più tastiere collegate. Ad esempio, se colleghi due tastiere a un host Windows e premi BLOC MAIUSC su una di esse, il LED di BLOC MAIUSC si accende su entrambe le tastiere.

Proprio questo test potrebbe essere utilizzato per determinare se i modificatori dello stato della tastiera sono condivisi tra tutte le tastiere per un dato sistema operativo.

Nel caso in cui un host USB supporti questo tipo di condivisione dello stato (ad esempio Windows lo fa), il linguaggio HIDScript di P4wnP1 potrebbe sfruttarlo.

Immagina il seguente scenario:

P4wnP1 è collegato a un host USB e vuoi eseguire un'iniezione di tasti, ma non vuoi che lo script HID esegua immediatamente le sequenze di tasti. Invece, lo script HID dovrebbe rimanere in attesa finché non premi BLOC NUM, BLOC MAIUSC o BLOC SCORR sulla tastiera reale dell'host. Perché? Forse sei impegnato in un'operazione, qualcuno è entrato e non vuoi che questa "persona" veda come magicamente un'enorme quantità di caratteri viene digitata in una finestra di console apparsa all'improvviso. Quindi aspetti che "qualcuno" esca, premi BLOC NUM e alla fine una finestra di console appare e un'enorme quantità di caratteri viene magicamente digitata... Penso che tu abbia capito.

Il comportamento descritto potrebbe essere ottenuto in questo modo:```
P4wnP1_cli hid run -c 'waitLED(NUM); type("A huge amount of characters\n")'
```
Se hai testato il comando precedente, la digitazione dovrebbe iniziare solo se NUM LOCK è premuto sulla tastiera hardware dell'host USB, 
ma potresti incontrare casi in cui i tasti vengono immediatamente inviati, anche se NUM LOCK non era premuto (e il 
LED della tastiera non è cambiato).

Questo è un comportamento voluto e la ragione è un altro caso d'uso per il comando `waitLED`:

Forse hai già usato altri linguaggi di scripting per tastiere e altri dispositivi USB in grado di iniettare sequenze di tasti. 
La maggior parte di questi dispositivi condivide un problema comune: non sai quando iniziare a digitare!

Se inizi a digitare immediatamente dopo l'accensione del dispositivo USB, è probabile che l'host USB non abbia ancora completato 
l'enumerazione del dispositivo e quindi non sia riuscito a caricare i driver della tastiera. Di conseguenza, le tue sequenze di tasti vengono perse.

Per superare questo problema potresti aggiungere un ritardo prima che inizi l'iniezione delle sequenze di tasti. Ma quanto dovrebbe durare questo ritardo? Cinque 
secondi, 10 secondi, 30 secondi?

La risposta è: dipende! Dipende da quanto velocemente l'host è in grado di enumerare il dispositivo e caricare il driver 
della tastiera. In effetti non puoi sapere quanto tempo ci vuole, senza testare sul target reale.

Ma come abbiamo già imparato, sistemi operativi come Windows condividono lo stato dei LED tra più tastiere.
Ciò significa che se il LED NUMLOCK della tastiera dell'host è impostato su ON prima di collegare una seconda tastiera, il LED NUMLOCK 
su questa nuova tastiera deve essere impostato su ON una volta collegata. Se il LED NUM LOCK fosse stato impostato su OFF, 
la tastiera appena collegata riceve comunque lo stato del LED (tutti i LED spenti in questo caso). La cosa interessante è 
che questo "aggiornamento LED" può essere inviato dall'host USB alla tastiera collegata solo se il driver della tastiera ha 
finito di caricarsi (altrimenti non sarebbe possibile inviare lo stato del LED).

Non è bellissimo? L'host USB ci dice: "Sono pronto a ricevere sequenze di tasti". Non c'è bisogno di giocare con 
ritardi iniziali.

Ma ecco un altro problema: supponiamo di collegare P4wnP1 a un host USB. Eseguiamo un HIDScript che inizia con `waitLED` invece 
di un ritardo personalizzato. La digitazione inizia dopo `waitLED`, ma non succede nulla: le nostre sequenze di tasti vengono perse, comunque! Perché? 
Perché è probabile che abbiamo perso l'aggiornamento dello stato del LED, poiché è arrivato prima ancora di avviare il nostro HIDScript.

Proprio questa "race condition" è il motivo per cui P4wnP1 preserva tutte le modifiche allo stato del LED riconosciute, a meno che almeno un 
HIDScript non le consumi chiamando `waitLED` (o `waitLEDRepeat`). Ciò potrebbe comportare il comportamento descritto in precedenza,
dove un `waitLED` ritorna immediatamente, anche se non si è verificato alcun cambiamento del LED. Ora sappiamo: il cambiamento del LED è effettivamente avvenuto, 
ma potrebbe essere accaduto molto prima (prima ancora di avviare l'HIDScript), perché la modifica dello stato è stata preservata.
Sappiamo anche che questo comportamento è necessario per evitare di perdere le modifiche allo stato del LED, nel caso in cui `waitLED` venga utilizzato per verificare 
la "prontezza del driver della tastiera dell'host USB".

*Nota: Vale la pena menzionare che `waitLED` ritorna SOLO se lo stato del LED ricevuto è diverso dallo stato interno di P4wnP1. 
Ciò significa che, anche se ascoltiamo un cambiamento su qualsiasi LED con `waitLED(ANY)`, potrebbe comunque accadere che riceviamo 
uno stato LED iniziale da un host USB che non è diverso dallo stato interno di P4wnP1. In questo caso `waitLED(ANY)` 
bloccherebbe il flusso per sempre (o fino a quando non si verifica un cambiamento reale del LED).
Questo caso speciale potrebbe essere gestito chiamando `waitLED(ANY_OR_NONE)`, che ritorna non appena arriva un nuovo stato del LED,
anche se non si traduce in un cambiamento.*

**Basta spiegazioni, passiamo alla pratica... prima di farlo, dobbiamo cambiare un po' la configurazione hardware:**

Collega un alimentatore esterno alla seconda porta USB del Raspberry Pi Zero (quella esterna). Questo assicura che
P4wnP1 non perda alimentazione quando viene scollegato dall'host USB, poiché non dipende più dall'alimentazione tramite bus. La porta USB che
dovrebbe essere utilizzata per collegare P4wnP1 all'host USB target è quella più interna delle due porte.

Ora avvia il seguente HIDScript``` 
P4wnP1_cli hid run -c 'while (true) {waitLED(ANY);type("Attached\n");}'
``` 
Stacca P4wnP1 dall'host USB (assicurati che rimanga acceso)! Ricollega all'host USB ...
Ogni volta che ricolleghi P4wnP1 all'host, "Attached" dovrebbe essere digitato sull'host.

Questo ci ha insegnato 3 fatti:
1) `waitLED` può essere usato come comando iniziale negli script, per iniziare a digitare non appena il driver della tastiera è pronto
2) `waitLED` non è la scelta perfetta per mettere in pausa gli script HID finché un tasto che cambia il LED viene premuto sull'host USB, poiché cambiamenti di stato preservati potrebbero sbloccare il comando in modo non voluto
3) Fornire HIDScript più complessi come parametro alla CLI non è molto comodo

Visto che non abbiamo ancora finito con il comando `waitLED`, ora ci occupiamo del terzo fatto. Usciamo dalla CLI.

- interrompi la CLI di P4wnP1 con CTRL+C (nel caso lo script HID ciclico sia ancora in esecuzione)
- apri un browser sull'host che hai usato per la connessione SSH a P4wnP1 (non l'host USB)
- il webclient può essere raggiunto tramite lo stesso IP del server SSH, la porta è 8000 (per WiFi `http://172.24.0.1:8000`)
- vai alla scheda "HIDScript" nel webclient ora aperto
- da lì puoi caricare e salvare HIDScript (non lo facciamo ora, anche se `ms_snake.js` è un ottimo esempio della potenza dei trigger basati su LED)

Sostituisci lo script nella finestra dell'editor con il seguente:``` 
return waitLED(ANY);
``` 
Dopo aver premuto il pulsante di esecuzione, il lato destro della finestra dovrebbe mostrare un nuovo job HID in esecuzione. Se si preme il piccolo pulsante "info" a destra del job HIDScript, è possibile vedere i dettagli, come il suo stato (dovrebbe essere in esecuzione), l'ID del job e l'ID della VM (questo è il numero della VM JavaScript che esegue questo job. Ci sono 8 di queste VM, quindi 8 HIDScript possono essere eseguiti in parallelo).

Ora, se viene emesso un cambiamento di LED dall'host USB (attivando/disattivando NUM, CAPS o SCROLL), il job HIDScript dovrebbe terminare. Può ancora essere trovato tra i job "Succeeded".

Se si preme di nuovo il piccolo pulsante "info", dovrebbero esserci informazioni sul valore del risultato (codificato come JSON), che assomiglia a questo:```
{"ERROR":false,"ERRORTEXT":"","TIMEOUT":false,"NUM":true,"CAPS":false,"SCROLL":false,"COMPOSE":false,"KANA":false}
```
Quindi il comando `waitLED` restituisce un oggetto JavaScript simile a questo:```
{
	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)
}
```
Nel mio caso, `NUM` è diventato vero. Nel tuo caso forse era `CAPS`. Non importa quale LED fosse. Ciò che conta è il fatto che il valore di ritorno offre l'opportunità di esaminare il cambiamento del LED che fa terminare il comando e quindi potrebbe essere utilizzato per prendere decisioni di ramificazione nel tuo HIDScript (basate sui cambiamenti di stato del LED emessi dalla tastiera reale dell'host USB).

Proviamo un esempio:```
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
 }
}
``` 
Supponendo che lo script fornito sia già in esecuzione, premere NUM sull'host USB dovrebbe comportare la digitazione di "NUM has been toggled", mentre premere SCROLL LOCK produce il testo digitato "SCROLL has been toggled". Questo comportamento si ripete, finché non viene premuto CAPS LOCK e il conseguente cambiamento del LED interrompe il ciclo e termina lo HIDScript.

Puhhh... un sacco di testo su questo comando per un singolo comando HIDScript, ma ci sono ancora alcune cose rimaste.

Abbiamo fornito argomenti come `NUM`, `ANY` o `ANY_OR_NONE` al comando `waitLED`, senza ulteriori spiegazioni.

Il comando `waitLED` accetta fino a due argomenti:

Il primo argomento, come potresti aver intuito, è un filtro di whitelist per i LED da osservare. Gli argomenti validi sono:
- `ANY` (reagisci a un cambiamento su qualsiasi LED)
- `ANY_OR_NONE` (reagisci a ogni nuovo stato del LED, anche se non c'è cambiamento)
- `NUM` (ignora tutti i cambiamenti dei LED, tranne che sul LED NUM)
- `CAPS` (ignora tutti i cambiamenti dei LED, tranne che su NUM CAPS)
- `SCROLL` (ignora tutti i cambiamenti dei LED, tranne che su NUM SCROLL)
- più filtri possono essere combinati in questo modo `CAPS | NUM`, `NUM | SCROLL`

Il secondo argomento, che non abbiamo ancora utilizzato, è una durata di timeout in millisecondi. Se non si verifica alcun cambiamento del LED durante questa durata di timeout, `waitLED` ritorna e ha `TIMEOUT: true` impostato nell'oggetto risultante (inoltre `ERROR` è impostato su true e `ERRORTEXT` indica un timeout).

Il comando seguente attenderà un cambiamento sul LED NUM, ma interromperà l'attesa dopo 5 secondi:```
waitLED(NUM,5000)
```
Anche se `waitLED` è un comando molto potente se usato correttamente, non ha aiutato a gestire il nostro semplice compito di mettere in pausa in modo robusto un HIDScript finché un tasto modificatore di stato non viene premuto sull'host USB di destinazione (ricorda: volevamo mettere in pausa l'esecuzione per assicurarci che l'indesiderato "qualcuno" uscisse prima che la digitazione inizi, ma `waitLED` occasionalmente restituiva il controllo in anticipo, a causa di modifiche dello stato LED preservate).

È qui che `waitLEDRepeat` entra in gioco e viene in soccorso.

Incolla il seguente script nell'editor e prova a far sì che il comando restituisca il controllo. Ispeziona i risultati HIDScript in seguito.```
return waitLEDRepeat(ANY)
```
Dovresti notare rapidamente che lo stesso LED deve essere cambiato più volte frequentemente, affinché il comando `waitLEDRepeat` restituisca il controllo. Il comando `waitLEDRepeat` non restituirebbe il controllo se LED diversi cambiano stato o se i cambiamenti su un singolo LED avvengono troppo lentamente.

L'argomento fornito a `waitLEDRepeat` (che nell'esempio è `ANY`) serve allo stesso scopo di `waitLED`. È un filtro di whitelist. Ad esempio, `waitLEDRepeat(NUM)` restituirebbe il controllo solo per i cambiamenti del LED NUM LOCK - non importa quanto velocemente e spesso tu colpisca il tasto CAPS LOCK, non restituirebbe il controllo a meno che NUM LOCK non venga premuto frequentemente.

Per impostazione predefinita, uno dei LED nella whitelist deve cambiare 3 volte e il ritardo tra due cambi successivi non deve essere superiore a 800 millisecondi affinché `waitLEDRepeat` restituisca il controllo. Questo comportamento può essere regolato fornendo argomenti aggiuntivi come mostrato in questo esempio:```
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
```
Ecco come interagire con i report dei LED da un host USB in HIDScript.

*Nota: `waitLEDRepeat` non differisce da `waitLED`, per quanto riguarda il consumo delle modifiche dello stato LED preservate. Comunque, è molto più difficile attivarlo involontariamente.*

Quindi `waitLEDRepeat` è la scelta giusta, se il compito è mettere in pausa gli HIDScript fino all'interazione umana. Ovviamente può essere usato anche per il branching, poiché fornisce lo stesso oggetto di ritorno di `waitLED`.

Fino a questo punto abbiamo acquisito una buona quantità di conoscenze su HIDScript (ovviamente non su tutto, non abbiamo nemmeno esaminato le capacità di controllo del mouse di questo linguaggio di scripting). Comunque, questo tutorial riguarda il flusso di lavoro di P4wnP1 A.L.O.A. e i concetti di base. Quindi per ora non esaminiamo altre funzionalità di HIDScript e proseguiamo.

Riassumiamo ciò che abbiamo imparato finora sul flusso di lavoro e sui concetti di P4wnP1:
- potevamo avviare azioni come l'iniezione di tasti dal client CLI, su richiesta
- potevamo usare il webclient per ottenere lo stesso risultato, avendo al contempo un controllo aggiuntivo sui job HIDScript
- se colleghiamo un alimentatore esterno a P4wnP1 A.L.O.A., ci colleghiamo/scolleghiamo a/da diversi host USB e gli HIDScript già avviati continuano a funzionare senza problemi
- potevamo configurare lo stack USB esattamente secondo le nostre esigenze (e cambiarne la configurazione in esecuzione, senza riavviare P4wnP1)
- potevamo scrivere HIDScript multiuso, con logica complessa basata su JavaScript (con supporto per funzioni, cicli, branching, ecc. ecc.)

### 3. Workflow parte 2 - Templating e TriggerActions

Prima di proseguire con gli altri concetti principali di P4wnP1 A.L.O.A., affiniamo il nostro primo obiettivo, che era "eseguire un'iniezione di tasti contro un host USB":
- Il nuovo obiettivo è digitare "Hello world" nell'editor di un host USB Windows (notepad.exe).
- L'editor deve essere aperto da P4wnP1 (non manualmente dall'utente).
- L'editor deve essere chiuso automaticamente, quando uno qualsiasi dei LED della tastiera dell'host USB viene attivato/disattivato.
- Ogni volta che P4wnP1 viene collegato all'host USB, questo comportamento deve ripetersi (con alimentatore esterno, senza riavvio di P4wnP1)
- Il processo *dovrebbe essere eseguito una sola volta*, a meno che P4wnP1 non venga ricollegato all'host USB, anche se si verificano successive modifiche dei LED della tastiera dopo l'avvio dell'HIDScript.
- Anche se P4wnP1 viene riavviato, lo stesso comportamento dovrebbe essere recuperabile senza ricreare i dettagli della configurazione da capo.

Avviare notepad, digitare "Hello world" e chiudere notepad dopo un cambiamento di LED potrebbe essere fatto con le cose che abbiamo imparato finora. Un HIDScript corrispondente potrebbe assomigliare a questo:```
// 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
```
L'unica novità in questo script è il comando `delay`, che non necessita di molte spiegazioni. Ritarda l'esecuzione per 
la quantità di millisecondi specificata.

Lo script può essere incollato nell'editor HIDScript del client web e avviato con "run" per testarlo.

Dovrebbe funzionare come previsto, quindi siamo quasi pronti. Per poter riutilizzare lo script anche dopo un riavvio, lo salviamo 
in modo persistente. Ciò può essere ottenuto premendo il pulsante "store" nella scheda HIDScript del client web. Dopo 
aver inserito un nome (usiamo `tutorial1` per ora) e confermato la finestra di dialogo, l'HIDScript dovrebbe essere stato salvato. 
Possiamo verificarlo premendo il pulsante "Load & Replace" nel client web. Lo script salvato dovrebbe apparire nell'elenco
degli script salvati con il nome `tutorial1.js` (l'estensione `.js` viene aggiunta automaticamente, se non è già stata 
fornita nella finestra di dialogo "store").

**Attenzione: Se nella finestra di dialogo di salvataggio viene utilizzato il nome di un file già esistente, il file corrispondente viene sovrascritto senza 
richiedere ulteriore conferma.**

Proviamo ad avviare lo script salvato utilizzando il client CLI da una sessione SSH, in questo modo:```
P4wnP1_cli hid run tutorial1.js
```
Questo avrebbe dovuto funzionare. Ciò significa che è possibile avviare HIDScript memorizzati da tutte le applicazioni che supportano comandi shell o da un semplice script bash, utilizzando il client CLI P4wnP1 A.L.O.A.

Sarebbe persino possibile avviare lo script in remoto da un client CLI compilato per Windows. Supponendo che l'host Windows sia in grado di raggiungere P4wnP1 A.L.O.A. tramite WiFi e che l'IP di P4wnP1 sia impostato su `172.24.0.1`, il comando corretto sarebbe simile a questo:```
P4wnP1_cli.exe --host 172.24.0.1 hid run tutorial1.js
```
*Nota: Al momento in cui scrivo, non ho ancora deciso se P4wnP1 A.L.O.A. fornirà un binario CLI per ogni possibile piattaforma e architettura. È probabile che vengano fornite versioni precompilate per le principali piattaforme. In caso contrario, non è un grosso problema, poiché la cross-compilazione del codice Go del client CLI richiede meno di un minuto.*

Il passo successivo è permettere allo script di essere eseguito nuovamente ogni volta che P4wnP1 viene ricollegato a un host USB. Un approccio già utilizzato per ottenere tale comportamento è stato quello di racchiudere tutto in un ciclo e anteporre un `waitLED(ANY_OR_NONE)`. Il `waitLED(ANY_OR_NONE)` assicurava che il ciclo continuasse solo se l'host USB di destinazione segnalava che il driver della tastiera era pronto a ricevere input, inviando un aggiornamento dello stato globale dei LED della tastiera. Uno script modificato di conseguenza potrebbe apparire così:```
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 
}
```
Lo script dato sopra, in effetti, verrebbe eseguito ogni volta che P4wnP1 viene collegato a un host USB. Ma lo script non è molto 
robusto, perché c'è un secondo `waitLED` coinvolto, che aspetta finché notepad.exe non dovrebbe essere chiuso di nuovo. 

Farlo in questo modo comporta diversi problemi. Ad esempio, se P4wnP1 viene scollegato prima che "Hello world" venga digitato, il
`waitLED` ora bloccante sarebbe quello prima di `press("ALT F4")` e l'esecuzione continuerebbe esattamente a questo punto del
HIDScript una volta che P4wnP1 viene ricollegato a un host USB (forse diverso), di nuovo.

Un criterio di uccisione definitivo per l'approccio scelto è il seguente problema: il requisito che lo script dovrebbe essere 
eseguito solo una volta dopo aver collegato P4wnP1 a un host USB non potrebbe essere soddisfatto, poiché premere NUM LOCK più volte 
riavvierebbe lo script più e più volte.

Allora come risolviamo questo problema?

#### Introduciamo TriggerActions

La soluzione al problema sono le cosiddette "TriggerActions". Come suggerisce il nome, questo concetto del flusso di lavoro di P4wnP1 A.L.O.A. 
attiva azioni basate su trigger predefiniti.

Per farti un'idea di ciò di cui sto parlando, vai alla scheda "TRIGGER ACTIONS" nel webclient. A seconda della 
configurazione corrente, potrebbero già esistere TriggerActions. Non ci interessano le TriggerActions esistenti, ora.

Premi il pulsante "ADD ONE" e una nuova TriggerAction dovrebbe essere aggiunta e aperta immediatamente in modalità di modifica. 
La nuova TriggerAction è disabilitata per impostazione predefinita e deve essere abilitata per renderla modificabile. Quindi attiviamo l'interruttore
di abilitazione.

Ora dal menu a tendina chiamato "Trigger" dovrebbe essere selezionata l'opzione "USB gadget connected to host". L'azione
dovrebbe avere un preset di "write log entry" selezionato. Lo lasciamo così e premiamo il pulsante "Update".

La TriggerAction appena aggiunta dovrebbe ora essere visibile nella panoramica delle TriggerActions (quella con l'ID più alto) e 
mostrare un riepilogo del Trigger selezionato e dell'Azione selezionata in forma leggibile.

Per testare se la TriggerAction appena definita funziona, vai alla scheda "Event Log" del webclient. 
Assicurati di aver aperto il webclient tramite WiFi (non USB ethernet). Applica alimentazione esterna a P4wnP1, scollegalo dall'host 
USB e ricollegalo. Un messaggio di log dovrebbe essere inviato al client ogni volta che P4wnP1 viene collegato a un host 
USB, immediatamente.

Se hai ripetuto questo alcune volte, potresti aver notato che il trigger "USB gadget connected to host" si attiva molto velocemente
(o in una fase iniziale della fase di enumerazione USB). Per essere più precisi: quando questo trigger si attiva, è noto che P4wnP1 
è stato collegato a un host USB, ma non c'è garanzia che l'host USB sia riuscito a caricare tutti i driver di dispositivo USB necessari. 
**In effetti è molto improbabile che il driver della tastiera USB sia caricato quando il trigger si attiva. Dobbiamo tenerlo a 
mente.**

Prima di procedere con il nostro compito, facciamo un test aggiuntivo. Tornando alla scheda "TriggerAction" e premiamo il 
piccolo pulsante blu che assomiglia a una penna per la nostra TriggerAction appena creata. Ci ritroviamo di nuovo in modalità di modifica.
 
Questa volta, abilitiamo l'opzione `One shot`. Torna al "Event Log" dopo, e di nuovo, scollega e ricollega 
P4wnP1 dall'host USB. Questa volta la TriggerAction dovrebbe attivarsi solo una volta. Non importa quante volte P4wnP1 venga ricollegato 
all'host USB in seguito, nessun nuovo messaggio di log che indica una connessione USB dovrebbe essere creato.

Vale la pena menzionare che una TriggerAction "One shot" non viene cancellata dopo che il Trigger si è attivato. Invece la 
TriggerAction viene disabilitata di nuovo. Riabilitare consente di riutilizzare una TriggerAction senza ridefinirla. Niente viene perso 
fino a quando non viene premuto il pulsante rosso "cestino" su una TriggerAction, che eliminerà la rispettiva TriggerAction.

**Attenzione: Se si fa clic sul pulsante di eliminazione per una TriggerAction, la TriggerAction viene eliminata definitivamente senza ulteriore 
conferma.**

A questo punto facciamo l'ovvio. Modifichiamo la TriggerAction creata e selezioniamo "start a HIDScript" invece di "write
log entry" per l'azione da eseguire. Inoltre disabilitiamo "one-shot" di nuovo. Viene visualizzato un nuovo campo di input chiamato "script name". 
Cliccando su questo campo di input viene visualizzata una finestra di dialogo di selezione per tutti gli HIDScript memorizzati, incluso il nostro HIDScript
creato in precedenza `tutorial1.js`.

*Prima di testare se funziona, lascia che faccia una breve nota sull'azione "write log entry": P4wnP1 A.L.O.A. non tiene traccia 
dei Trigger che sono già stati attivati. Ciò significa che le voci di log create da un'azione "write log entry" vengono 
consegnate a tutti i client in ascolto, ma non vengono memorizzate dal servizio P4wnP1 (per vari motivi). Il webclient d'altra 
parte memorizza la voce di log fino a quando il webclient stesso non viene ricaricato. Lo stesso vale per gli eventi, che sono 
relativi ai lavori HIDScript. Se un HIDScript termina (con successo o errore), un evento viene inviato a tutti i webclient attualmente 
aperti. In sintesi, ogni webclient ha uno stato di esecuzione, che contiene più informazioni rispetto al servizio core stesso. 
Se lo stato di esecuzione del webclient diventa troppo grande (troppo utilizzo della memoria), è sufficiente ricaricare il client per 
cancellare le informazioni di stato "storiche". Se il servizio core si comportasse allo stesso modo e memorizzasse ogni informazione storica, 
esaurirebbe le risorse molto presto. Quindi questo concetto si applica alla maggior parte dei sottosistemi di P4wnP1 A.L.O.A.*

Ora torniamo al nostro compito. Abbiamo una TriggerAction pronta, che dovrebbe attivare il nostro HIDScript ogni volta che P4wnP1 viene collegato a 
un host USB. 

A seconda dell'host USB di destinazione, questo funziona più o meno in modo affidabile. Nella mia configurazione di test non ha funzionato affatto e c'è un 
motivo:
 
Rivediamo le prime righe del nostro 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 ...
```
Ricordando il fatto che il trigger "USB gadget connected" si attiva nella fase iniziale di enumerazione USB e il driver della tastiera dell'host USB non è stato necessariamente caricato, il problema diventa evidente. Dobbiamo anteporre una sorta di ritardo allo script per assicurarci che il driver della tastiera sia attivo (altrimenti le nostre sequenze di tasti finirebbero nel nulla).

Come già sappiamo che non è possibile prevedere il ritardo ottimale, adottiamo l'approccio `waitLED(ANY_OR_NONE)`, spiegato in precedenza. Il nuovo script si presenta così:```
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
```
Memorizzare lo script modificato con lo stesso nome (`tutorial1`) sovrascrive il precedente HIDScript senza ulteriore conferma, come già indicato. Quindi non è necessario modificare il nostro TriggerAction, poiché il nome dell'HIDScript a cui il TriggerAction fa riferimento non è cambiato.

Con questa piccola modifica tutto dovrebbe funzionare come previsto e lo script dovrebbe attivarsi ogni volta che ci colleghiamo a un host USB, ma eseguirsi una sola volta.

Ora, se P4wnP1 viene riavviato o perde alimentazione, il nostro HIDScript sopravviverà, perché lo abbiamo salvato in modo persistente, ma il TriggerAction scomparirebbe. Inutile dire che anche i TriggerAction possono essere salvati in modo persistente.

Il pulsante "store" nella scheda "TriggerAction" funziona esattamente come quello nell'editor HIDScript. Va notato che *tutti i TriggerAction attualmente attivi* verranno salvati se la finestra di dialogo "store" viene confermata (inclusi quelli disabilitati).
La buona pratica è eliminare tutti i TriggerAction che non appartengono all'attività in ambito corrente prima di salvare (dovrebbero essere stati salvati in precedenza, se necessario) e salvare solo il piccolo insieme di TriggerAction rilevanti per l'attività corrente, utilizzando un nome appropriato. Ci sono due opzioni per ricaricare i TriggerAction salvati in quelli attivi:
 - "load & replace" cancella tutti i trigger action attivi e carica solo quelli salvati
 - "load & add" mantiene i TriggerAction già attivi e aggiunge quelli salvati. Quindi "load & add" potrebbe essere utilizzato per creare un insieme complesso di TriggerAction partendo da insiemi più piccoli. L'insieme risultante può poi essere a sua volta salvato.

Per ora dovremmo salvare solo il nostro singolo TriggerAction, che avvia il nostro HIDScript. Il nome che usiamo per salvare è ancora `tutorial1` e non entrerà in conflitto con l'HIDScript chiamato `tutorial1`.

Conferma il salvataggio riuscito premendo il pulsante "load&replace" nella scheda "TriggerAction". L'insieme di TriggerAction salvato dovrebbe essere nell'elenco e chiamarsi `tutorial1`.

**Avvertenza: Le finestre di dialogo "load" dei TriggerAction consentono di eliminare i TriggerAction salvati premendo il pulsante rosso "cestino" accanto a ciascuna azione. Premere il pulsante elimina definitivamente il rispettivo insieme di TriggerAction, senza ulteriore conferma**

A questo punto potremmo tranquillamente eliminare il nostro TriggerAction dalla scheda "TriggerActions" (!!non con il pulsante cestino di una delle finestre di dialogo load!!).

Con il TriggerAction rimosso da quelli attivi, non succede nulla se scolleghiamo e ricolleghiamo P4wnP1 dall'host USB.

In ogni caso, l'insieme di TriggerAction salvato `tutorial1` persiste ai riavvii e può essere ricaricato in qualsiasi momento.

Invece di ricaricare l'insieme di TriggerAction dal webclient, proviamo a farlo utilizzando il client CLI.

Diamo una rapida occhiata alla schermata di aiuto del sottocomando `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")

``` 
La schermata di utilizzo mostra che i TriggerAction Templates possono essere distribuiti con il flag `-t`. Eseguiamo il comando seguente, per ripristinare il set TriggerAction salvato:``` 
P4wnP1_cli template deploy -t tutorial1
``` 
Il TriggerAction che attiva HIDScript sulle connessioni host USB è ora caricato di nuovo e dovrebbe essere mostrato nella scheda TriggerActions del webclient. Se P4wnP1 A.L.O.A. è collegato a un host USB, lo script dovrebbe essere eseguito di nuovo.

La memorizzazione, il caricamento e la distribuzione dei template sono uno dei due concetti principali alla base del flusso di lavoro di automazione di P4wnP1, l'altro sono i già noti TriggerActions. Vale la pena menzionare che non solo i set di TriggerActions possono essere memorizzati e caricati come template essi stessi, ma che i TriggerActions possono essere utilizzati per distribuire template già memorizzati, se ha senso.

Rivisitando i nostri compiti, sembra che tutti i requisiti definiti siano ora soddisfatti:
- abbiamo digitato "Hello world" nell'editor di un host Windows USB
- l'editor è aperto da P4wnP1, non manualmente dall'utente
- l'editor viene chiuso automaticamente, quando uno dei LED della tastiera viene attivato una volta
- ogni volta che P4wnP1 viene collegato a un host USB, questo comportamento si ripete
- lo script HIDScript viene eseguito solo una volta, a meno che P4wnP1 non venga ricollegato all'host USB, anche se si verificano cambiamenti successivi dei LED della tastiera
- se P4wnP1 viene riavviato, lo stesso comportamento può essere recuperato caricando il set di TriggerActions memorizzato (che fa nuovamente riferimento allo script HIDScript memorizzato). Questo potrebbe essere ottenuto sia con un singolo comando CLI, sia con un semplice "load&add" o "load&replace" dalla scheda delle azioni di attivazione del webclient.

Ancora una volta, aggiungiamo obiettivi aggiuntivi:
- dovrebbe essere garantito che la configurazione USB abbia la funzionalità della tastiera abilitata (l'attuale configurazione non lo fa e il TriggerAction non potrebbe avviare lo script HIDScript nel caso in cui la tastiera USB sia disabilitata)
- la configurazione creata dovrebbe essere applicata all'avvio di P4wnP1 A.L.O.A., senza la necessità di caricare manualmente il set di TriggerActions. La configurazione deve sopravvivere a un riavvio di P4wnP1.

Per raggiungere i due obiettivi aggiuntivi, dobbiamo addentrarci in un nuovo argomento e...

#### Introduzione ai Master Template e al Master Template di Avvio

Prima di esaminare i Master Template, facciamo qualcosa che non abbiamo ancora fatto, perché finora tutto ha funzionato come previsto: Definiamo una configurazione USB valida, corrispondente al nostro compito!

- numero di serie del dispositivo: 123456789
- nome prodotto del dispositivo: Auto Writer
- produttore del dispositivo: The Creator
- ID prodotto: 0x9876
- ID venditore: 0x1D6B
- funzioni USB abilitate
  - tastiera HID
  - mouse HID

Diamo prima un'occhiata alla schermata di utilizzo del comando CLI, che potrebbe essere utilizzato per distribuire queste impostazioni:``` 
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")
``` 
Il comando ha un sacco di flag, ma esistono anche un sacco di impostazioni USB modificabili. 
Distribuire la nostra configurazione USB definita potrebbe essere fatto così, usando 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
```
L'output del (lungo) comando mostra le impostazioni USB risultanti. Controlliamo la scheda "Impostazioni USB" del client web per confermare che siano state applicate. Tutte le modifiche dovrebbero essere riflesse, se non è successo nulla di sbagliato.

Sebbene sia perfettamente possibile distribuire una configurazione USB usando la CLI, ci sono diversi vantaggi nell'usare il client web rispetto alla CLI. In questo caso:
- modificare le impostazioni dal client web è più facile e comodo
- il client web mantiene uno stato interno delle impostazioni, questo permette di definire le impostazioni USB senza effettivamente distribuirle (la CLI, d'altra parte, poteva solo manipolare le impostazioni distribuendole. Questo, ancora una volta, ripristina l'intero stack USB di P4wnP1 e tutte le funzionalità dipendenti. Ad esempio, HIDScript già in esecuzione verrebbe interrotto o le interfacce di rete USB verrebbero ridistribuite)
- le impostazioni correnti del client web possono essere salvate in un template persistente, senza distribuirle preventivamente
- il client CLI, (attualmente) non è in grado di salvare le impostazioni USB

Nel nostro caso attuale, è ovviamente una scelta migliore usare il client web per le modifiche necessarie alle impostazioni USB. La cosa positiva dell'approccio CLI (che abbiamo già usato qui): poiché la CLI ci ha costretto a distribuire le impostazioni USB, abbiamo potuto confermare che funzionano, prima di salvarle in un template persistente.

Procediamo con il salvataggio delle impostazioni USB:

Ancora una volta premiamo il pulsante "store", questa volta nella scheda "Impostazioni USB". Ancora una volta chiamiamo il template `tutorial1` (non c'è conflitto con il template TriggerAction salvato con lo stesso nome, perché viene usato un namespace diverso per le impostazioni USB).

Ora abbiamo due nuovi template salvati permanentemente::
1) un template per il set TriggerAction, chiamato `tutorial1`
2) un template per le impostazioni USB, anch'esso chiamato `tutorial1`

Supponendo che lo stato (delle impostazioni USB correnti, delle TriggerActions o di entrambi) sia cambiato in qualche modo, potremmo ricaricare entrambe le impostazioni salvate contemporaneamente, eseguendo il seguente comando CLI:```
P4wnP1_cli template deploy --usb tutorial1 --trigger-actions tutorial1
```
Il comando `P4wnP1 template deploy` potrebbe caricare un template per ciascuno dei sottosistemi di P4wnP1 A.L.O.A. in una singola esecuzione (per il sottosistema di rete potrebbero essere caricati più template, uno per adattatore). Distribuire template per vari sottosistemi è considerato un'attività comune quando si lavora con P4wnP1 A.L.O.A., perché nella maggior parte dei casi potrebbe essere necessario riconfigurare diversi sottosistemi per raggiungere un unico obiettivo. Per tenerne conto, sono stati introdotti i cosiddetti *Master Template*.

Un Master Template potrebbe essere composto da:
- un template di set TriggerAction già salvato
- un template di impostazioni USB già salvato
- un template di impostazioni WiFi già salvato
- un template di impostazioni Bluetooth già salvato
- diversi template di impostazioni di rete salvati (uno per adattatore)

Un Master Template potrebbe essere definito, salvato o caricato, utilizzando l'"Editor Master Template" dalla scheda "Impostazioni Generiche" del webclient. Usare il webclient è un modo pratico per definire Master Template, poiché supporta l'utente consentendo di selezionare solo template già salvati per i rispettivi sottosistemi (e attualmente il webclient è l'unico modo per definire Master Template).

Quindi definiamo un Master Template per il nostro compito attuale:
1) Navigare alla scheda "Impostazioni Generiche" del webclient
2) Nell'"Editor Master Template" fare clic sul piccolo pulsante a destra del campo "TriggerActions Template"
3) Dalla finestra di dialogo scegliere il template `tutorial1` e confermare con il pulsante "OK"
4) Se si seleziona il template sbagliato, riaprire il dialogo e selezionarne uno diverso oppure usare l'icona "x" a destra di "TriggerAction Template" per eliminare la selezione corrente
5) Ripetere i passaggi per la selezione del "USB Template", sempre scegliendo `tutorial1` (che è un template diverso per il sottosistema USB, sebbene condivida il nome con quello per TriggerActions)
6) Verificare che siano stati selezionati i template corretti per entrambi, USB e TriggerActions, e che tutti gli altri Template siano lasciati vuoti
7) Salvare il nuovo Master Template premendo il pulsante "Store" e fornendo il nome `tutorial1`

Per confermare che il template sia stato salvato, si può usare il pulsante "Load Stored": il template dovrebbe essere elencato nella selezione. Annullare la finestra di dialogo "Load Store".

Ora premere il pulsante "Deploy Stored", selezionare il template chiamato `startup` e confermare con "OK".

A differenza della funzione "Load Stored", che carica un template salvato nell'Editor Master Template, la funzione "Deploy Stored" applica immediatamente tutte le impostazioni di un Master Template ai corrispondenti sottosistemi di P4wnP1 (senza nemmeno caricarli nell'Editor Master Template).

Poiché il Master Template `startup` sovrascrive le attuali impostazioni WiFi, potrebbe accadere di aver perso la connessione al webclient e di doversi riconnettere alla rete WiFi di P4wnP1.

Una volta riconnessi con successo e ispezionate le impostazioni USB attuali e le TriggerActions attuali, le impostazioni che avevamo salvato in precedenza sono state sovrascritte dalle sotto-impostazioni del Master Template `startup`.

Ci sono due modi per ridistribuire il Master Template `tutorial1`:
1) Distribuirlo usando il dialogo "Deploy Stored" dall'"Editor Master Template" (come fatto con il Master Template `startup` un minuto fa)
2) Distribuirlo usando il client CLI con `P4wnP1_cli template deploy --full tutorial1` (il flag `--full` è un alias per Master Template)

Potendo distribuire il Master Template `tutorial1`, abbiamo già raggiunto uno dei nostri nuovi obiettivi:

È assicurato che la configurazione USB abbia la funzionalità della tastiera abilitata quando carichiamo la nostra configurazione di iniezione di tasti.

Un breve riepilogo di come funziona:
- il Master Template `tutorial1` carica impostazioni USB, chiamate `tutorial1`, che hanno
  - tastiera USB e mouse USB abilitati
- il Master Template `tutorial1` carica un set TriggerAction con una singola TriggerAction
  - la TriggerAction avvia lo script HID `tutorial1.js` ogni volta che P4wnP1 viene collegato a un host USB
    - lo script HID inizia a digitare, una volta che il trigger `waitLED` si attiva (driver della tastiera pronto) e termina dopo un cambio LED successivo

L'unico obiettivo rimanente è il seguente: la configurazione creata dovrebbe essere applicata all'avvio di P4wnP1 A.L.O.A., senza la necessità di caricare manualmente il set TriggerAction. La configurazione deve sopravvivere a un riavvio di P4wnP1.

Questo obiettivo potrebbe essere raggiunto abbastanza facilmente ora. La scheda "Impostazioni Generiche" del webclient presenta una carta chiamata *Startup Master Template*. Cambiare il Startup Master Template in `tutorial1` a questo punto avrebbe effetto immediato e probabilmente *distruggerebbe la configurazione di avvio funzionante di P4wnP1 A.L.O.A.".

**Importante: Se un Master Template ha sottotemplate lasciati vuoti (ad esempio, se non è selezionato alcun template Bluetooth), il rispettivo sottosistema non viene riconfigurato quando il Master Template viene caricato. Sebbene ciò sia comodo per la riconfigurazione runtime senza resettare sottosistemi già in esecuzione come lo stack USB o lo stack WiFi se non necessario, i Master Template utilizzati come Startup Master Template lasciano i sottosistemi senza template definiti in uno STATO INDEFINITO. Se, ad esempio, non viene fornito alcun template WiFi valido, è improbabile che P4wnP1 A.L.O.A. sia raggiungibile tramite WiFi dopo il riavvio**

Quindi, prima di distribuire il nostro nuovo Master Template `tutorial1` come Startup Master Template, assicuriamoci che siano caricate impostazioni corrette per gli altri sottosistemi. Lo facciamo così:

1) Dall'"Editor Master Template" premere il pulsante "Load Stored" e ricaricare il template `tutorial1` nell'editor.
2) Il template dovrebbe avere `tutorial1` impostato per "TriggerActions Template" e per "USB template"
3) Per "WiFi Template" selezionare il template chiamato `startup`
4) Per "Bluetooth Template" selezionare il template chiamato `startup`
5) Per "Network Templates" selezionare i template chiamati:
    1) `bteth_startup`
    2) `usbeth_startup`
    3) `wlan0_startup_dhcp_server`
6) Sovrascrivere il Master Template `tutorial1` con le nuove impostazioni (premere "Store", inserire `tutorial1` e confermare con "OK")
7) Ricontrollare che le modifiche siano state applicate, premendo di nuovo "Load Stored" e selezionando `tutorial1`. Tutte le sottosezioni del Master Template caricato dovrebbero apparire come descritto.

Ora siamo pronti per distribuire il nostro nuovo Master Template come Startup Master Template. Dopo averlo fatto, premere il pulsante "reboot".

Una volta riavviato, P4wnP1 A.L.O.A. dovrebbe attivare automaticamente lo script HID (e dovrebbe ancora essere raggiungibile tramite WiFi, per consentire la riconfigurazione)

**Congratulazioni, tutti gli obiettivi raggiunti**

Hai appreso i concetti di base del flusso di lavoro di P4wnP1 A.L.O.A.

## 3. Dove andare da qui

Al momento non è possibile fornire una documentazione completa. Quindi ecco alcuni commenti su argomenti che non sono stati ancora trattati, ma che vale la pena esplorare.

### BashScripts

P4wnP1 permette di eseguire BashScripts da TriggerActions. Gli script utilizzabili da TriggerActions risiedono in `/usr/local/P4wnP1/scripts`. Se uno script viene chiamato da una TriggerAction, diversi argomenti (come il trigger effettivo) vengono passati tramite variabili bash. Il file `/usr/local/P4wnP1/scripts/trigger-aware.sh` fornisce un buon esempio di uno script bash che si comporta diversamente a seconda del trigger chiamante. Vale la pena dare un'occhiata a questo script, poiché utilizza tutte le variabili "TriggerAction" attualmente disponibili.

### GPIO

La comunità della vecchia versione di P4wnP1 occasionalmente ha proposto modifiche hardware o estensioni del Raspberry PI e la domanda su come integrarle. Non è possibile per me fornire una soluzione generica a questo problema. Né è una buona idea fornire supporto per un'estensione hardware molto specifica, utilizzata solo da poche persone. Con l'introduzione delle TriggerAction è nata l'idea di supportare GPIO sia come trigger tramite input GPIO che come azioni che emettono output GPIO. Sebbene non pianificato per la prima release, questa funzionalità è già stata implementata. Non ho ancora avuto il tempo di documentarla e potrebbe facilmente accadere che alcune cose cambino. La funzionalità utilizza la libreria "periph.io" con alcune piccole estensioni (rilevamento dei bordi personalizzato con debounce personalizzato per GPIO, grazie a @marcaruel per lo scambio su questo)

### nexmon KARMA

Il firmware WiFi incluso con P4wnP1 A.L.O.A. è stato modificato (utilizzando il framework nexmon) per supportare KARMA. Questa funzionalità non è ancora stata integrata nel core (necessita di un certo rielaborazione del firmware) e quindi non è disponibile dal webclient o dalla CLI. Se si vuole giocare con le funzionalità karma, è disponibile una CLI Python legacy che permette di impostare le opzioni KARMA al volo. Lo script Python si trova qui:
`/usr/local/P4wnP1/legacy/karmatool.py`

Suggerimento: Per ottenere il massimo dalla funzionalità KARMA, si dovrebbe configurare P4wnP1 A.L.O.A. per fornire un punto di accesso WiFi senza autenticazione, altrimenti non avrebbe molto senso. Per un beacon flooding scadente questo non è necessario, ma gli SSID personalizzati (statici) per il beaconing sono limitati in numero (per risparmiare risorse sul chip WiFi)

Schermata di help di karmatool.py:

─────────────────────────────────────────────────
usage: karmatool.py [-h] [-i INTERFACE] [-c] [-d] [-t TIMEOUT] [-b] [-s SSID] [-l] [-r] [-a] [-m MODE] [-f FILE] [-p PREFERENCE] [-x] [-y] [-z]

optional arguments:
  -h, --help            show this help message and exit
  -i INTERFACE, --interface INTERFACE
                        Interface to use (default: mon0)
  -c, --clear           Clear all beacon frames
  -d, --deauth          Send deauth packets
  -t TIMEOUT, --timeout TIMEOUT
                        Timeout in seconds for deauth (default: 10)
  -b, --beacon           Enable beacon flooding
  -s SSID, --ssid SSID   SSID to add for beaconing
  -l, --list            List current beacon SSIDs
  -r, --reset           Reset all KARMA settings
  -a, --add             Add client to KARMA list
  -m MODE, --mode MODE  KARMA mode: 0=off, 1=respond, 2=inject
  -f FILE, --file FILE  File with SSIDs to beacon
  -p PREFERENCE, --preference PREFERENCE
                        Preference for KARMA responses
  -x, --enable          Enable KARMA
  -y, --disable         Disable KARMA
  -z                    Toggle KARMA verbose output```
root@kali:/usr/local/P4wnP1/legacy# ./karmatool.py 
Firmware in use seems to be KARMA capable
Firmware configuration tool for KARMA modified nexmon WiFi firmware on Pi0W/Pi3 by MaMe82
=========================================================================================

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
```
### Canale nascosto WiFi

Il canale nascosto WiFi non è stato portato su Go e non fa parte del core di P4wnP1. Tuttavia, la funzionalità legacy
è comunque disponibile. Affinché il canale nascosto funzioni, devono essere soddisfatte diverse condizioni:
- è necessario applicare un'iniezione di pressioni di tasti al client target per iniettare stage1
- stage1 carica stage2 tramite una versione semplificata del canale nascosto HID, quindi deve essere fornito un dispositivo USB HID speciale e su P4wnP1 deve essere avviato un server speciale del canale nascosto HID per fornire stage2
- deve essere avviato un secondo server che interfacci il firmware WiFi modificato, per gestire i client che si connettono
tramite il canale nascosto WiFi e fornire accesso interattivo alla shell a tali client (il server è un'applicazione
console pensata per funzionare in un multiplexer di terminale, come `screen`)

Tutte le condizioni sopra menzionate potrebbero essere soddisfatte utilizzando le funzionalità di P4wnP1 A.L.O.A., se i componenti
necessari (HID stager, server del canale nascosto WiFi, agent client da distribuire) vengono forniti.

Eseguire un tale compito con P4wnP1 A.L.O.A. è un ottimo esempio delle sue capacità. Inoltre, aiuta a
distinguere cosa P4wnP1 A.L.O.A. è destinato a essere e cosa non è destinato a essere.

P4wnP1 A.L.O.A. non è destinato a:
- essere uno strumento "armato"
- fornire payload RTR, che potrebbero essere eseguiti da chiunque, senza capire cosa sta succedendo o quali rischi
sono coinvolti

P4wnP1 A.L.O.A. è destinato a:
- essere una piattaforma flessibile, a basso costo, tascabile
- fungere da abilitatore per attività come quella qui descritta
- supportare la prototipazione, il test e l'esecuzione di tutti i tipi di attività relative all'USB, comunemente utilizzate durante penetration test o
impegni di red team, senza fornire una soluzione statica finalizzata

In un certo senso, la cartella `/usr/local/P4wnP1/legacy` contiene gli strumenti esterni necessari per eseguire il canale nascosto WiFi
(ovvero il server WiFi, il server stager del canale nascosto HID e l'agent client del canale nascosto WiFi). Questi
componenti possono essere considerati parti esterne (non appartengono al core di P4wnP1 A.L.O.A.).

Inoltre, P4wnP1 A.L.O.A. fornisce una configurazione che utilizza i componenti dati per fare quanto segue:
- drive-by contro host Windows per distribuire il codice client in memoria per scaricare stage2 tramite il canale nascosto HID,
basato sull'iniezione di pressioni di tasti (HIDScript)
- avviare l'iniezione di pressioni di tasti non appena P4wnP1 viene collegato a un host USB (TriggerAction che esegue HIDScript)
- attivare lo stager, che distribuisce l'agent client del canale nascosto WiFi tramite il canale nascosto HID, non appena
l'iniezione di pressioni di tasti inizia (TriggerAction che esegue uno script bash, che avvia a sua volta il server esterno)
- attivare il server del canale nascosto WiFi, quando necessario (stesso TriggerAction e BashScript)
- distribuire una configurazione USB che fornisce una tastiera USB (per consentire l'iniezione di pressioni di tasti) e un dispositivo HID raw aggiuntivo
(serve come canale nascosto per la distribuzione di stage2) - le impostazioni USB sono memorizzate in un template di impostazioni
- distribuire una configurazione WiFi, che consente l'accesso remoto a P4wnP1, per permettere l'interazione con il frontend CLI del
server del canale nascosto WiFi - le impostazioni WiFi sono memorizzate in un template di impostazioni
- fornire un unico punto di ingresso per distribuire tutte le configurazioni necessarie contemporaneamente (fatto da un Master Template, che
consiste di impostazioni WiFi appropriate, impostazioni USB appropriate e TriggerActions necessari per avviare l'HIDScript)

Il Master Template si chiama "canale nascosto WiFi". Distribuendolo dalla scheda "impostazioni generiche" del webclient
("DEPLOY STORED" dall'Editor Master Template) P4wnP1 A.L.O.A. è configurato per eseguire tutti i passaggi descritti.

Non appena viene ricollegato a un host USB, dovrebbe iniziare a digitare stage1 e i server corrispondenti vengono avviati
internamente.
Da una sessione SSH (ad esempio tramite WiFi) è possibile accedere al server del canale nascosto WiFi utilizzando `screen -d -r wifi_c2`
per interagire con i client che si sono riconnessi tramite il canale nascosto WiFi.
Poiché l'iniezione di pressioni di tasti dipende dal layout della lingua dell'host USB, il corrispondente HIDScript chiamato
`wifi_covert_channel.js` ha una variabile `language` che può essere utilizzata per regolare il layout della tastiera in uso.
Inoltre, c'è una variabile chiamata `hide` (false per impostazione predefinita). Se `hide` è impostata su true, la finestra della console sul
client viene nascosta mentre stage1 viene digitato. Questo, ancora una volta, evidenzia come attività complesse possano essere ridotte a una semplice variabile
bool, grazie a HIDScript e al motore JavaScript sottostante.

La demo "canale nascosto WiFi" fornita con i Master Template di P4wnP1 può essere utilizzata anche come Master Template di avvio, poiché
l'accesso WiFi è ancora possibile e quindi la configurazione può essere modificata nuovamente, in qualsiasi momento da remoto.

Lo script Bash coinvolto, che viene chiamato da un TriggerAction, è un buon esempio di quanto flessibile possa diventare il client CLI.
Poiché lo stager HID deve sapere su quale file dispositivo ascoltare (quello che rappresenta il dispositivo HID generico), ma
questa informazione è disponibile solo in fase di esecuzione (dipende dalle funzioni gadget USB abilitate), lo script richiede al CLI
di riportare il dispositivo HID corretto eseguendo `hidraw=$(P4wnP1_cli usb get device raw)`.

Lo script Bash completo è ospitato nella cartella `/usr/local/P4wnP1/scripts`, come tutti gli script bash che dovrebbero essere accessibili
dai TriggerAction.

### Bluetooth NAP

P4wnP1 fornisce funzionalità di rete basate su Bluetooth tramite il Bluetooth Network Encapsulation Protocol (BNEP).
La funzionalità attualmente più interessante è il Bluetooth Network Access Point (NAP), che consente l'accesso remoto basato su IP a P4wnP1
tramite Bluetooth, ad esempio da dispositivi mobili.

Per utilizzare questa funzionalità, è necessario sapere alcune cose:
- L'interfaccia di rete Bluetooth, chiamata `bteth`, può essere configurata e modellata come le altre interfacce di rete
(webclient o CLI)
- Per consentire l'accesso NAP da un dispositivo mobile Android (iPhone non testato), il dispositivo mobile non solo deve connettersi, ma
inoltre P4wnP1 deve assegnare un IP appropriato per il gateway predefinito sull'interfaccia `bteth` tramite DHCP. Questo perché
il dispositivo mobile vuole utilizzare il NAP come gateway per Internet (che sarebbe l'uso previsto). Se il NAP stesso
non fornisse un gateway, il dispositivo Android non effettuerebbe ulteriori richieste dopo il DHCP D.O.R.A. Il modo più semplice per
superare questo problema è istruire il server DHCP affinché fornisca l'IP dell'interfaccia `bteth` stessa come gateway predefinito
(opzione DHCP 3). Anche se non esiste una connessione upstream reale, durante i miei test ha funzionato - poiché il dispositivo mobile deve accedere
al gateway con comunicazione di livello 3 per "telefonare a casa". Anche se i test di connettività successivi falliscono, la connessione
di livello 3 funzionante persiste. Ciò consente, ad esempio, l'accesso SSH tramite Bluetooth. Con "High Speed" abilitato, il
webclient funziona abbastanza bene.
- Per consentire l'associazione basata su PIN, è necessario disabilitare Simple Secure Pairing (SSP). Se SSP è abilitato, l'agente di associazione
in esecuzione conferma ogni passkey (il che significa ancora meno sicurezza rispetto all'associazione PIN legacy, poiché ogni dispositivo è
in grado di connettersi). Forse in futuro verrà implementata una finestra di dialogo di conferma per l'associazione passkey basata su SSP per il CLI/webclient,
ma attualmente è fuori portata. Suggerisco vivamente di disabilitare "scopribile" e "associabile" se SSP è in
uso, non appena il dispositivo desiderato si è associato.
- Un altro limite di avere SSP disabilitato è che "High Speed" non sarebbe utilizzabile per le connessioni Bluetooth (o
per abilitare High Speed, l'associazione deve essere effettuata con SSP). Senza "High Speed" abilitato (usa frame 802.11 per la
comunicazione) ci vorrebbero circa 10 minuti per richiedere il webclient, mentre con high speed abilitato ci vogliono alcuni secondi.
Tuttavia, utilizzare SSH e il client CLI su un NAP senza "High Speed" dovrebbe andare bene.
- Le impostazioni predefinite dell'interfaccia di rete Bluetooth (`bteth_startup`) e le impostazioni Bluetooth predefinite (`startup`)
dovrebbero consentire l'accesso "Low Speed" tramite SSH con associazione PIN legacy. Il PIN è `1337` e può essere modificato dal
webclient.

### Gruppi TriggerAction

I TriggerAction dispongono di una comoda funzionalità di raggruppamento chiamata "Gruppi". Non sono riuscito a preparare una demo
della funzionalità in tempo, ma ho intenzione di includere un esempio di contatore binario a 4 bit basato su LED (utilizzando GPIO, un interruttore a levetta
e 4 LED).

L'idea dei gruppi è la seguente:

Considera di volere 4 TriggerAction (TA) che si attivano sullo stesso esatto Trigger (ad esempio "al collegamento all'host USB").
Potresti ottenere questo creando 4 TA, ciascuno con il Trigger "al collegamento all'host USB".

In alternativa, potresti creare un TriggerAction che invia il valore `1` a un gruppo chiamato `"connesso"` quando si verifica
"al collegamento all'host USB". Ora definisci gli altri 4 TriggerAction in modo che si attivino quando il valore `1` viene ricevuto su
un gruppo chiamato `"connesso"`. Il risultato sarebbe lo stesso e non avrebbe molto senso per ora (anzi, richiede un
TriggerAction in più). L'unico effetto positivo, per ora, è che i TriggerAction sono leggermente più leggibili, grazie
al nome del gruppo, che può essere scelto liberamente.

Ora la prima cosa avanzata che potresti fare è eseguire il seguente comando CLI:```
P4wnP1_cli trigger send --group-name=connected --group-value=1
```
Questo comando avrebbe esattamente lo stesso effetto del TriggerAction "on attached to USB host" e tutti gli altri 4 TA, che sono in attesa del valore `1` sul gruppo `connected`, scatterebbero. Come forse ricordi, il client CLI può essere eseguito in remoto (da piattaforme diverse), quindi potrebbe essere utilizzato per attivare comandi da remoto.

Il Trigger che reagisce ai "canali di gruppo" è chiamato "value on group channel". Il trigger più interessante è chiamato "multiple values on group channel". Questo trigger a "valori multipli" permette di ascoltare sequenze ordinate di valori, o uno di più valori o tutti i valori in una sequenza non ordinata, prima di scattare.

Supponiamo che tu voglia eseguire un BashScript quando queste condizioni sono soddisfatte:
- Il punto di accesso WiFi è attivo
- P4wnP1 è stato collegato a un host USB

Potresti creare TA per entrambi gli eventi in questo modo:
1) Su "WiFi AP up" --> invia valore 1 al gruppo "conditions"
2) Su "attached to USB host" --> invia valore 2 al gruppo "conditions"

Ora potresti implementare un terzo TriggerAction in questo modo:
- Su "multiple values on group channel"; valori (1,2); tipo "All (logical AND)" --> avvia script bash

In questa configurazione, lo script bash si avvierebbe solo se entrambi i Trigger di "condition" sono scattati.

Se fosse stato utilizzato "exact ordered sequence", invece di "All (logical AND)" come tipo, lo script bash si avvierebbe solo se il punto di accesso WiFi si attiva prima del Trigger di connessione USB (non viceversa). In combinazione con i trigger GPIO, questo potrebbe essere utilizzato, ad esempio, per attivare azioni basate sull'input di un semplice tastierino PIN.

Sono sicuro che hai delle buone idee per l'uso dei canali "group".

Vale la pena menzionare:

Il client CLI è in grado di eseguire un'attesa bloccante, fino a quando un valore dedicato arriva su un "canale di gruppo", usando un comando come questo:```
P4wnP1_cli trigger wait --group-name=waitgroup --group-value=1
```
Questo potrebbe essere utilizzato per eseguire script da TriggerActions, sfruttando la CLI (con tutta la loro potenza come GPIO).

Lavori in corso, sezioni mancanti:
- Variabili Trigger di HIDScript (variabili passate agli HIDScript attivati da TriggerActions)
- Helper di HIDScript (funzioni PowerShell)
- Demo snake di HIDScript (mouse)
- Archiviazione di massa USB (helper genimg)

## 4. Salvataggio: Aiuto, non riesco a raggiungere P4wnP1 A.L.O.A. perché ho sbagliato la configurazione

P4wnP1 A.L.O.A. non ti protegge da configurazioni errate, che lo rendono inutilizzabile (così come una console di root non ti proteggerebbe dall'eseguire `rm -rf /`).

Nel caso tu abbia combinato un pasticcio, ecco alcune idee su come risolvere:

### Backup del database

Prima di apportare modifiche critiche a una configurazione di P4wnP1 ancora funzionante, crea un backup del database. Questo può essere fatto dalla scheda "Generic Settings" del webclient o tramite la CLI, con il comando `P4wnP1_cli db backup`.
Il backup verrà archiviato nella cartella `/usr/local/P4wnP1/db` con il nome scelto.
La funzione "restore" o il comando `P4wnP1_cli db restore` possono essere utilizzati per ripristinare un backup dato.
Un backup contiene tutti i template salvati (USB, WiFi, Rete, Bluetooth, TriggerActions, MasterTemplates) e il Master Template di avvio impostato. Il backup non include HIDScript o BashScript, poiché entrambi sono archiviati come file per consentire una facile modifica.

### Non ho un backup e ho combinato un pasticcio

Quando P4wnP1 A.L.O.A. si avvia, controlla se esiste un database. Se il database non esiste, ne crea uno nuovo basato su un backup iniziale fornito con P4wnP1 A.L.O.A.

Il backup iniziale è archiviato in `/usr/local/P4wnP1/db/init.db` e **non dovrebbe mai essere cancellato o sovrascritto**.

Per forzare P4wnP1 a ricreare il database, è necessario eliminare quello attuale. Questo può essere fatto montando la scheda SD di P4wnP1 A.L.O.A. su un sistema in grado di scrivere partizioni EXT.

Una volta fatto, elimina la cartella `/usr/local/P4wnP1/store` dalla partizione root della scheda SD. Questo cancella il database e quindi forza la ricreazione al successivo avvio di P4wnP1.

### Ho un backup, ma non posso accedere a P4wnP1 per ripristinarlo

Se non puoi ripristinare un database esistente perché non hai accesso, puoi comunque seguire i passaggi della sezione "Non ho un backup e ho combinato un pasticcio". Oltre a eliminare `/usr/local/P4wnP1/store`, sostituisci il file `/usr/local/P4wnP1/db/init.db` con quello del tuo backup (assicurati di avere una copia di backup di init.db).

Questo dovrebbe ricreare il tuo database personalizzato al riavvio di P4wnP1.

### Ho sbagliato il Master Template di avvio del mio backup

Se hai un backup per cui il Master Template di avvio non funziona, devi eseguire alcuni passaggi aggiuntivi, poiché non è possibile cambiare direttamente il Template di avvio in un backup.

Prima segui i passaggi della sezione "Non ho un backup e ho combinato un pasticcio", che ricrea il database iniziale di P4wnP1.
Dopo un riavvio di P4wnP1, dovresti essere in grado di accedere di nuovo al webclient di P4wnP1 in remoto.

Vai su "Generic Settings" e ripristina il tuo backup (quello con il Master Template di avvio sbagliato).

Il "Startup Master Template" dovrebbe mostrare il tuo Master Template "rotto" come selezionato. Se non è così, ricarica la scheda del browser che ospita l'applicazione webclient.

Di nuovo, naviga alla scheda "Generic Settings" e seleziona un Master Template di avvio noto per funzionare.

A questo punto dovresti essere pronto per riavviare.

### nessuno dei precedenti ha aiutato

Spiacente, sembra che tu debba ricreare la tua scheda SD di P4wnP1 A.L.O.A. da un'immagine pulita.

## 5. Crediti

In costruzione, ordine casuale

- @JohanBrandhorst (scambio ravvicinato su gRPC-web tramite gopherjs, implementazione incredibilmente veloce di "websocket per server streaming", richiesta di funzionalità)
- @steevdave, @_binkybear (script di build per Kali, scambio di discussioni in corso)
- @Re4sonKernel (supporto per lo spostamento delle modifiche al kernel di P4wnP1 in un repository ben mantenuto e popolare, collaborazione sulle correzioni di Bluez)
- @SymbianSyMoh (ispirazione per il ri-attivazione dell'attacco HID senza riavvio)
- @quasarframework (potrei elencarlo tra le librerie di terze parti, ma il lavoro fatto qui è pazzesco; l'aspetto del webclient di P4wnP1 è più o meno basato sui componenti predefiniti di questa bellissima libreria)
- @CyberArms (uno dei primi sostenitori di P4wnP1, autore del miglior tutorial e persino di libri su tali argomenti)
- @LucaBongiorni (non solo uno dei primi sostenitori, fa in hardware ciò che io faccio solo in software; tiene conferenze sul tema USB e onora le soluzioni Open Source, tutto sommato un grande ragazzo e un'ispirazione)
- @evilsocket (il suo block mi ha spinto verso Go, un grande sviluppatore OSS, leggi il suo codice e capisci cosa intendo)
- @RoganDawes e @Singe di @SensePost (ragazzi stimolanti)
- @Swiftb0y (sostenitore iniziale, creatore del "vecchio" wiki di P4wnP1, primo tester per idee su P4wnP1 A.L.O.A.)
- @marcaruel (discussione sul rilevamento dei fronti GPIO usando periph.io)

## 6. Cose da fare e supporto

Questa non è una lista completa di cose da fare, ma ci sono alcune milestone rimaste e sarei felice di ricevere un po' di supporto dalla comunità su questo
- Portare la piena funzionalità del canale occulto HID al core Go (sono da solo con questo)
- **aggiungere comando di configurazione Bluetooth per la CLI**
- Creare layout di tastiera aggiuntivi (attualmente supportati br, de, es, fr, gb, it, ru e us)
- estendere la funzionalità Bluetooth per consentire la connessione ad altri dispositivi rilevabili (autenticazione e trust)
- spostare la funzionalità WiFi KARMA dallo strumento Python dedicato al core di P4wnP1 (con supporto webclient)
- Creare documentazione completa per HIDScript (fondamentalmente manca solo la parte del mouse)
- Creare documentazione completa per P4wnP1 (sperando nella comunità)
- Eliminare una dipendenza rimanente dal netlink di Docker (vedi README della cartella `netlink`)

Nota su Bluetooth:

P4wnP1 funziona con binding personalizzati all'API Bluez. Sebbene l'API Bluez supporti Low Energy (GATT, emulazione di periferiche, ecc.), non è previsto di integrare questa funzionalità in P4wnP1 A.L.O.A.

Nota su Nexmon:

P4wnP1 utilizza nexmon. La maggior parte delle persone conosce nexmon come una modifica del firmware che consente di abilitare la modalità monitor e l'iniezione di pacchetti per chip WiFi Broadcom (incluso il BCM43430a1, utilizzato dal Raspberry Pi Zero W). Ma nexmon è di più, è un framework che consente di modificare blob del firmware ARM (dopo un po' di reverse engineering), con patch scritte in C di alto livello. P4wnP1 utilizza questo framework per applicare patch personalizzate al firmware WiFi, che abilitano il supporto KARMA basato su hardware e il supporto del firmware (così come del driver) per il canale occulto WiFi. Non è l'obiettivo di queste modifiche fornire una corretta modalità monitor o supporto per l'iniezione per l'interfaccia WiFi integrata. Sebbene la funzionalità legacy di modalità monitor di nexmon sia inclusa nell'attuale firmware WiFi, è considerata "erronea", poiché interferisce con le funzionalità WiFi standard utilizzate da P4wnP1 (crash se l'interfaccia viene utilizzata in modalità station, ecc.).

## 7. Copyright

    P4wnP1 A.L.O.A.
    Copyright (C) 2018 Marcus Mengs

    Questo programma è software libero: puoi ridistribuirlo e/o modificarlo
    secondo i termini della GNU General Public License come pubblicata dalla
    Free Software Foundation, sia la versione 3 della Licenza, o
    (a tua scelta) qualsiasi versione successiva.

    Questo programma è distribuito nella speranza che sia utile,
    ma SENZA ALCUNA GARANZIA; senza nemmeno la garanzia implicita di
    COMMERCIABILITÀ o IDONEITÀ PER UN PARTICOLARE SCOPO. Vedi la
    GNU General Public License per maggiori dettagli.

    Dovresti aver ricevuto una copia della GNU General Public License
    insieme a questo programma. In caso contrario, vedi <http://www.gnu.org/licenses/>.
Scarica lo strumento