
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".
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".
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).
Math per calcoli del mouse ecc.)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)
Quindi se vuoi usare un file batch in esecuzione su un host Windows remoto per configurare P4wnP1 ... nessun problema:
host ai tuoi comandi clientSebbene 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:
CTRL+SPACE)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:
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.
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:
Il requisito di configurazione minimo per raggiungere questo obiettivo è:
La configurazione predefinita di P4wnP1 (immagine non modificata) soddisfa già questi requisiti:
MaMe82-P4wnP1172.24.0.1172.16.0.1P4wnP11337172.26.0.1root, la password predefinita è toorNota: 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:
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.
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
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')
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/>.