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
Pi-Zero-2W-Bad-USB — Configura il tuo Pi Zero 2W per trasformarlo in una BadUSB. | Kitploit
Strumenti/GitHubGitHub/psycostea/pi-zero-2w-bad-usb
Sicurezza Sistemi EmbeddedExploitScripting e AutomazioneHacking HardwareCTFPenetration TestingApprendimento e FormazioneRed TeamingSviluppo Payload
GitHubpsycostea/pi-zero-2w-bad-usb

Pi-Zero-2W-Bad-USB

Configura il tuo Pi Zero 2W per trasformarlo in una BadUSB.

3722 mesi 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
Vedi Repository

Toolkit BadUSB HID per Raspberry Pi Zero 2 W

Una piattaforma di attacco BadUSB / HID programmabile basata su un Raspberry Pi Zero 2 W. Il Pi si presenta come un dispositivo USB composito (tastiera più un volume di archiviazione di massa di sola lettura opzionale) ed esegue payload in stile Ducky-Script sull'host a cui è collegato. Progettata per attività di red team autorizzate, test di penetrazione e CTF.

⚠️ Nota legale. Utilizzare solo su sistemi di propria proprietà o per i quali si dispone di esplicita autorizzazione scritta al test. L'accesso non autorizzato è illegale nella maggior parte delle giurisdizioni, e fingere di non saperlo non aiuta.


Indice

  1. Funzionalità
  2. Come funziona
  3. Hardware
  4. Installazione
  5. Operazioni quotidiane
  6. Scrivere payload
  7. Riferimento configurazione
  8. Note sull'architettura
  9. Test
  10. Risoluzione dei problemi
  11. Struttura del repository
  12. Riconoscimenti

Funzionalità

  • Payload di sequenze di tasti programmabili in un dialetto compatibile con Ducky-Script.
  • Rilevamento affidabile del collegamento dell'host tramite lo stato configured della UDC — nessun payload spurio viene eseguito all'avvio.
  • "Reset tra gli attacchi" che funziona realmente sull'hardware Pi Zero 2 W. Scollega, ricollega, esegui di nuovo — nessun ciclo di alimentazione.
  • Protezioni configurabili contro i loop incontrollati se il dispositivo viene lasciato collegato: intervallo minimo tra le esecuzioni e un limite di esecuzioni al minuto, entrambi sovrascrivibili tramite variabili d'ambiente.
  • Gadget composito di archiviazione di massa opzionale basato su un file immagine flat (sola lettura per impostazione predefinita — esporre la scheda SD in uso era la vecchia trappola di corruzione del file system difficile da debuggare).
  • Layout di tastiera US e UK selezionabili per payload con LAYOUT.
  • Variabili, IF / ELSE, WHILE, HOLD / RELEASE, INJECT_MOD, generatori RANDOM_*, STRING_BLOCK / STRINGLN_BLOCK, DEFINE.
  • Integrazione con systemd con ExecStop che smonta il gadget in modo pulito. Nessuno stato configfs residuo, il riavvio del servizio funziona senza riavviare il sistema.
  • Permessi gestiti da udev per /dev/hidg0 — nessun nodo di dispositivo scrivibile da tutti.
  • Suite pytest di 34 test per il parser Ducky, eseguibile su qualsiasi host senza alcun Pi collegato.
  • Indicatore di stato sul LED ACT dopo ogni esecuzione del payload.

Come funziona

root@kitploit:~
+----------------+        USB cable        +-------------+
|  Raspberry Pi  | ===================>>>  |  Host PC    |
|  Zero 2 W      |   (Pi emulates HID +    |  (target)   |
|  (this device) |    optional drive)      |             |
+----------------+                         +-------------+
        |
        |  /home/pi/pi-badusb/
        |
        +-- badusb.service ----> monitor_and_run.py
                                   |
                                   |  on `state == configured`:
                                   v
                                 run_payload.py
                                   |
                                   v
                                 /dev/hidg0  (USB HID gadget)
  1. All'avvio, l'unità systemd badusb.service esegue gadget_setup.sh, che usa configfs/libcomposite per comporre un gadget USB con una funzione di tastiera HID e (opzionalmente) una LUN di archiviazione di massa basata su un file immagine flat in /var/badusb/storage.img.
  2. L'unità esegue quindi monitor_and_run.py. Sonda /sys/class/udc/<udc>/state e attende configured — lo stato della specifica USB che indica che un host ha enumerato correttamente il gadget. (Non usiamo l'esistenza di /dev/hidg0 come segnale: tale condizione è vera nel momento in cui il gadget si lega alla UDC all'avvio, indipendentemente dal fatto che qualcosa sia collegato.)
  3. Quando l'host si collega, il listener esegue run_payload.py, che analizza payload.txt e scrive i report HID su /dev/hidg0.
  4. Quando il payload termina, il listener slega attivamente il gadget dalla UDC (il Pi Zero 2 W non può rilevare la disconnessione fisica via software — vedi ), attende un tempo di raffreddamento e rilega. Il dispositivo attende quindi la successiva transizione a .

Hardware

ComponenteNota
Raspberry Pi Zero 2 WTestato sulla revisione hardware del 2026-05. Anche il vecchio Pi Zero W con il driver BCM2835 dwc_otg funziona in linea di principio, ma questo README presuppone il 2 W con dwc2.
Cavo micro-USB verso USB-AOppure un adattatore con fattore di forma "chiavetta USB" che permette al Pi di collegarsi direttamente a una porta dell'host.
Opzionale: caricatore separatoSe si vuole alimentare il Pi da una sorgente non-host così che il listener possa avviarsi prima di essere collegato a un target (in caso contrario, la porta dell'host fornisce l'alimentazione).

Il Pi Zero 2 W ha due porte micro-USB:

  • PWR IN — solo alimentazione, non espone le linee dati USB al blocco dwc2 OTG.
  • USB — la porta dati OTG; è qui che ci si collega al target.

Software


Installazione

Clona o copia il repository nel Pi, quindi esegui l'installer:

root@kitploit:~
git clone http://your-gitea/admin/Pi-Zero-2W-Bad-USB.git /home/pi/pi-badusb
cd /home/pi/pi-badusb
sudo ./install.sh
sudo reboot

Dopo il riavvio, abilita e avvia il servizio:

root@kitploit:~
sudo systemctl enable --now badusb.service
journalctl -u badusb -f

install.sh è idempotente — rieseguilo ogni volta che modifichi i file del progetto. Esso:

  • Rileva /boot/firmware (Bookworm+) rispetto a /boot (più vecchio).
  • Garantisce che dtoverlay=dwc2,dr_mode=otg sia attivo in un blocco [all] in config.txt. Le impostazioni predefinite di Raspberry Pi Imager mettono questa riga dentro un filtro [cm5] che non si applica al Pi Zero 2 W; l'installer aggiunge un override contrassegnato da sentinella così che le riesecuzioni non lo duplichino.
  • Garantisce che modules-load=dwc2 sia presente in cmdline.txt.
  • Avvisa se g_ether è ancora presente in cmdline.txt (ruba la UDC a libcomposite e rompe la modalità gadget).
  • Installa l'unità systemd in /etc/systemd/system/badusb.service.
  • Installa la regola udev in /etc/udev/rules.d/99-badusb-hidg.rules così che sia scrivibile dal gruppo .

Operazioni quotidiane

root@kitploit:~
# Start / stop / restart
sudo systemctl start badusb
sudo systemctl stop badusb
sudo systemctl restart badusb              # safe to do while plugged in

# Watch live
journalctl -u badusb -f

# Disable autostart on boot
sudo systemctl disable badusb

# Tune timings (creates an override drop-in)
sudo systemctl edit badusb
# (paste an [Service] block with Environment="BADUSB_REARM_COOLDOWN_S=8" etc)
sudo systemctl restart badusb

Il servizio dipende da sys-kernel-config.mount e dalla presenza di una UDC, quindi non può eseguire payload prima che il gadget sia effettivamente pronto.

Modificare il payload non richiede un riavvio — payload.txt viene riletto a ogni collegamento.


Scrivere payload

payload.txt si trova nella directory di installazione. Il riferimento completo ai comandi è in payload_commands.md.

Esempio minimale

root@kitploit:~
REM Open Run dialog and type a greeting via Notepad
LAYOUT US
GUI r
DELAY 1500
STRING notepad
ENTER
DELAY 2500
STRINGLN Hello from the Pi Zero 2 W

Variabili, condizionali e cicli

root@kitploit:~
VAR $USER="alice"
VAR $COUNT=0
WHILE $COUNT < 3
  STRINGLN Hello $USER (iteration $COUNT)
  VAR $COUNT = $COUNT + 1
END_WHILE

IF $USER == "alice"
  STRINGLN matched
ELSE
  STRINGLN missed
END_IF

Le espressioni matematiche in VAR passano attraverso un valutatore sicuro basato su un walker dell'ast — niente nomi, niente chiamate, niente accesso agli attributi, solo letterali numerici e + - * / // % **.

Mantenere premuti i modificatori

root@kitploit:~
HOLD SHIFT
STRINGLN this line is in capitals
RELEASE SHIFT

Inviare combinazioni arbitrarie di modificatori

root@kitploit:~
REM Hold Ctrl+Shift (0x01 + 0x02) and tap A
INJECT_MOD 0x03
STRING a
REM Release all modifiers
INJECT_MOD 0x00

Generazione casuale

root@kitploit:~
RANDOM_LETTER 12      # 12 random mixed-case letters
RANDOM_NUMBER 6       # 6 random digits
RANDOM_SPECIAL 4      # 4 random ASCII symbols

Layout di tastiera

root@kitploit:~
LAYOUT UK             # switch to UK ISO mappings for subsequent STRING/STRINGLN
STRING @ " # ~ £ \ |  # types correctly on a UK-locale host

Inserisci un altro file in keymaps/ (accanto a us.py e uk.py) e la direttiva LAYOUT <name> lo rileverà tramite importlib.


Riferimento configurazione

Gadget di archiviazione di massa (in cima a gadget_setup.sh)

Questi possono essere sovrascritti per singola invocazione impostandoli nell'ambiente quando si esegue gadget_setup.sh manualmente, oppure globalmente tramite le direttive Environment= dell'unità.

Parametri regolabili del listener (monitor_and_run.py)

Per sovrascrivere:

root@kitploit:~
sudo systemctl edit badusb
# In the editor:
# [Service]
# Environment="BADUSB_REARM_COOLDOWN_S=8"
# Environment="BADUSB_MIN_INTER_FIRE_S=20"
sudo systemctl restart badusb

Note sull'architettura

Perché il listener usa lo state della UDC, non /dev/hidg0

La precedente implementazione verificava l'esistenza + la scrivibilità di /dev/hidg0 come segnale di "host collegato". Questo nodo di dispositivo viene creato nel momento in cui il gadget si lega alla UDC all'avvio — molto prima che un host lo abbia effettivamente enumerato. Quindi i payload venivano eseguiti immediatamente all'accensione, indipendentemente da dove il Pi era collegato.

Il segnale affidabile è /sys/class/udc/<udc>/state, che riporta lo stato del dispositivo secondo la specifica USB. Solo configured significa che l'host ha emesso SetConfiguration(1) — il dispositivo ora è idoneo a inviare report HID.

Perché forziamo lo slegamento dopo ogni payload

Rilevare la disconnessione fisica sul Pi Zero 2 W è impossibile via software: la scheda non collega il rilevamento VBUS al blocco dwc2 OTG del SoC. Dopo uno scollegamento fisico:

  • /sys/class/udc/<udc>/state rimane su configured.
  • current_speed rimane su high-speed.
  • Il registro dwc2 GOTGCTL rimane su 0x000d0000 (bit BSesVld impostato).
  • Nessun evento udev viene generato.

Quindi, invece di attendere un segnale che non arriverà mai, il listener provoca attivamente la disconnessione: dopo ogni payload, scrive "" nel file configfs UDC del gadget (che il kernel interpreta come slegamento), attende BADUSB_REARM_COOLDOWN_S, poi riscrive il nome della UDC per rilegare. Il successivo collegamento dell'host produce una transizione pulita a configured che il listener può rilevare.

Se l'operatore lascia il Pi collegato dopo un payload, il rilegamento fa sì che l'host ri-enumeri il gadget. Per prevenire un loop di esecuzioni incontrollato, entrano in gioco due protezioni:

  1. BADUSB_MIN_INTER_FIRE_S — se una transizione a configured avviene entro questa finestra dall'esecuzione precedente, sopprimila e slega di nuovo. Il gadget cicla silenziosamente in background.
  2. BADUSB_MAX_FIRES_PER_MINUTE — limite massimo a finestra scorrevole. Oltre il limite, il listener si mette in pausa per BADUSB_RATELIMIT_PAUSE_S e registra un avviso.

Perché non usiamo mai rm -rf su configfs

I file di attributo di configfs gestiti dal kernel (bcdUSB, idVendor, webusb/*, os_desc/*, …) non possono essere rimossi con rm(2) — il kernel restituisce EPERM. Vengono rilasciati solo quando la loro directory padre viene rimossa con rmdir. Sia gadget_setup.sh che teardown_gadget.sh percorrono l'albero configfs nell'ordine canonico di libcomposite — solo rmdir, mai rm sui file di attributo — e il kernel pulisce automaticamente il resto.

Perché gli helper Python usano os.write e non file.write

Scrivere una stringa vuota tramite open(path, "w").write("") non invoca write(2) con zero byte — TextIOWrapper di CPython lo elide. Per lo slegamento configfs (che il kernel interpreta da una scrittura di lunghezza zero dopo la rimozione della nuova riga), usiamo direttamente os.write(fd, b"\n") così che la syscall venga sempre emessa con almeno un byte.


Test

Il parser Ducky ha una suite pytest di 34 test che viene eseguita contro un MockHIDEngine (un sostituto in memoria del vero writer HID), quindi non richiede né un Pi né hardware USB.

root@kitploit:~
cd /home/pi/pi-badusb
python3 -m pytest tests/

La copertura include:

  • safe_eval_math che accetta operazioni aritmetiche e rifiuta nomi / chiamate / accesso agli attributi / costanti stringa.
  • evaluate_condition per confronti numerici e tra stringhe con distinzione tra maiuscole e minuscole.
  • VAR con =, +=, -=, *=, /=.
  • IF / ELSE / END_IF che seguono il ramo corretto.
  • Conteggi di iterazione di WHILE / END_WHILE per < e <=.

Risoluzione dei problemi

"Il payload non viene mai eseguito quando è collegato"

  1. cat /sys/class/udc/*/state — deve raggiungere configured quando l'host enumera. Se rimane su not attached, l'host non sta comunicando: prova un cavo diverso (alcuni sono solo per la ricarica) o una porta host diversa.
  2. lsmod | grep dwc2 — deve essere caricato. Se c'è solo dwc_otg, dtoverlay=dwc2,dr_mode=otg non si sta applicando; riesegui install.sh e riavvia.
  3. journalctl -u badusb -f durante il collegamento — dovrebbe mostrare Host attached. Running payload. entro ~2s dall'enumerazione dell'host.

"Il payload viene eseguito in loop con il LED che lampeggia, anche da scollegato"

Questo era un bug reale, ora corretto. Se accade, sei tornato a una build precedente a os.write. Assicurati che monitor_and_run.py corrisponda al ramo main corrente (cerca os.write(fd, payload)).

"Il servizio non si riavvia — Operation not permitted"

Il gadget_setup.sh precedente alla correzione usava rm -rf su configfs. La versione attuale usa teardown_gadget() — se vedi questi errori, hai una copia vecchia. Ridistribuisci dal ramo main.

"Permission denied su /dev/hidg0"

La regola udev richiede un hot-plug per essere applicata, oppure sudo udevadm trigger e un nuovo accesso così che l'utente pi acquisisca il gruppo plugdev.

"Avviso g_ether durante l'installazione"

Rimuovi g_ether da cmdline.txt; reclama la UDC prima che libcomposite possa legarsi.

"L'host mostra un'unità USB ma non ha la dimensione che mi aspettavo"

La dimensione dell'archiviazione di massa è impostata da BACKING_SIZE_MB e ha effetto solo al primo avvio, quando viene creata l'immagine di supporto. Per ridimensionare:

root@kitploit:~
sudo systemctl stop badusb
sudo rm /var/badusb/storage.img
sudo BACKING_SIZE_MB=256 /home/pi/pi-badusb/gadget_setup.sh
sudo systemctl start badusb

"Voglio lasciare il Pi collegato senza che continui a bombardare l'host"

È a questo che servono BADUSB_MIN_INTER_FIRE_S e BADUSB_MAX_FIRES_PER_MINUTE. Impostali più alti con systemctl edit badusb. Con le impostazioni predefinite, un Pi lasciato collegato riesegue il payload ogni ~15s per il primo minuto, poi si mette in pausa per 60s, poi riprende.


Struttura del repository

root@kitploit:~
.
├── README.md                   This file
├── LICENSE                     MIT
├── install.sh                  Idempotent installer (firmware config, systemd, udev, plugdev)
├── gadget_setup.sh             Composes the USB gadget via configfs/libcomposite
├── teardown_gadget.sh          Canonical configfs teardown (wired as ExecStop)
├── reload_gadget.sh            Manual UDC unbind/rebind helper
├── autorun.sh                  Legacy manual-launch wrapper (systemd is preferred)
├── monitor_and_run.py          Listener: waits for host attach, runs payload, forces re-arm
├── run_payload.py              Ducky-Script-style interpreter
├── payload.txt                 Your payload — edit freely; re-read on each plug-in
├── payload_commands.md         Full command reference
├── etc/
│   ├── badusb.service          systemd unit
│   └── 99-badusb-hidg.rules    udev rule for /dev/hidg0 ownership
├── keymaps/
│   ├── __init__.py             Dynamic layout loader
│   ├── us.py                   US ANSI (default)
│   └── uk.py                   UK ISO
└── tests/
    ├── __init__.py
    ├── conftest.py             pytest path setup
    └── test_parser.py          34 parser tests against a MockHIDEngine

Riconoscimenti

  • Script originali del progetto e ispirazione: Psycostea.
  • Ricerca sui gadget USB: USB Rubber Ducky, Hak5, documentazione di libcomposite, il driver del kernel dwc2.
  • Intervento di correzione del 2026-05: riscritto il rilevamento del collegamento dell'host, resa sicura l'archiviazione di massa, corretti diversi bug del parser, aggiunta un'astrazione delle mappature di tastiera, migrato l'avvio a systemd, aggiunto il framework di test unitari e aggirata l'incapacità a livello hardware del Pi Zero 2 W di rilevare la disconnessione fisica.

Licenza

MIT — vedi LICENSE.

Scarica lo strumento
Note sull'architettura
configured
RequisitoMotivo
Raspberry Pi OS (Debian Bookworm o Trixie, Lite 64-bit consigliato)Lo script di installazione scrive in /boot/firmware/... su Bookworm+ e ripiega su /boot/... nelle immagini più vecchie.
Python 3Incluso con Pi OS.
mkfs.vfatPer formattare l'immagine di supporto dell'archiviazione di massa al primo avvio. Da saltare se si disabilita l'archiviazione di massa.
Accesso root per l'installazioneModifica systemd, udev e /boot/firmware/config.txt.
/dev/hidg0
plugdev
  • Aggiunge l'utente pi al gruppo plugdev.
  • Crea /var/badusb/ per l'immagine di supporto dell'archiviazione di massa.
  • VariabilePredefinitoSignificato
    ENABLE_MASS_STORAGE10 per un gadget solo HID.
    BACKING_FILE/var/badusb/storage.imgImmagine flat esposta all'host.
    BACKING_SIZE_MB64Creata al primo avvio se mancante.
    BACKING_LABELBADUSBEtichetta del volume FAT.
    MASS_STORAGE_RO1Sola lettura per impostazione predefinita.
    Variabile d'ambientePredefinitoSignificato
    BADUSB_POST_PAYLOAD_FLUSH_S0.5Pausa dopo il payload prima dello slegamento per consentire lo scarico delle scritture HID.
    BADUSB_REARM_COOLDOWN_S5Per quanto tempo il gadget rimane invisibile all'host tra slegamento e rilegamento.
    BADUSB_MIN_INTER_FIRE_S10Secondi minimi tra due esecuzioni di payload; al di sotto di questo valore, l'esecuzione viene soppressa e il gadget viene nuovamente slegato.
    BADUSB_MAX_FIRES_PER_MINUTE6Limite massimo; oltre questo, pausa per BADUSB_RATELIMIT_PAUSE_S.
    BADUSB_RATELIMIT_PAUSE_S60Durata della pausa dopo l'attivazione del limite di frequenza.
  • Correttezza della lunghezza di RANDOM_*; RANDOM_<unknown> no-op + avviso.
  • Persistenza del byte dei modificatori di INJECT_MOD attraverso le sequenze di tasti successive.
  • HOLD SHIFT che capitalizza ogni carattere in STRINGLN abc.
  • LAYOUT US rispetto a LAYOUT UK che producono report diversi per @ e "; un layout sconosciuto ripiega su quello precedente.
  • STRING_BLOCK che unisce le righe; STRINGLN_BLOCK che rispetta l'indentazione minima.