The Raspberry PI Zero can get enough power via USB, and it can be configured, with few steps, as an OTG (On-The-Go) USB device. That's awesome, because you can do similar things like USB Rubber Ducky or O.MG cable with it.
The aim of this tutorial is to use the Raspberry PI Zero as USB Keyboard (HID).
You should already have read (and successful carried out) the following tutorials.
Install (or ensure they are installed) following packages.
# update system (optional)
$ sudo apt update -y && sudo apt upgrade -y
# install optional packages (optional)
$ sudo apt install -y vim curl tree# backup config.txt (optional)
$ sudo cp /boot/config.txt ~/boot-config.txt.bak
# enable dwc2 USB driver
$ echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt
# backup modules (optional)
$ sudo cp /etc/modules ~/etc-modules.bak
# enable dwc2 in Raspbian
$ echo "dwc2" | sudo tee -a /etc/modules
# enable libcomposite in Raspbian
$ echo "libcomposite" | sudo tee -a /etc/modulesHere you will find some information about the Raspberry Device Tree.
In order to create the device (USB Linux Gadget) which has a UDC (USB Device Controller), create a libcomposite configuration.
# download file from GitHub
$ curl -L https://raw.githubusercontent.com/Lupin3000/Raspberry-PI-Tutorials/main/Zero_WIFI_HID/hid_usb -o ~/hid_usb
# copy file to specific target
$ sudo cp ~/hid_usb /usr/bin/hid_usb
# set file permissions
$ sudo chmod +x /usr/bin/hid_usb
# modify content for needs (optional)
$ sudo vim /usr/bin/hid_usbHere you will see the content of the libcomposite configuration /usr/bin/hid_usb for the english keyboard.
In order to have the libcomposite configuration run when the Raspberry boots, you simply add the command to file /etc/rc.local.
# backup rc.local (optional)
$ sudo cp /etc/rc.local ~/etc-rc.local.bak
# add new content in rc.local (before exit 0)
$ sudo sed -i '/^exit 0.*/i /usr/bin/hid_usb' /etc/rc.localNote: use this option (rc.local) just for testing or debugging!
The slightly better way to load the configuration during the boot process is via Systemd service.
# download service into directory
$ sudo curl -L https://raw.githubusercontent.com/Lupin3000/Raspberry-PI-Tutorials/main/Zero_WIFI_HID/usb-otg.service -o /etc/systemd/system/usb-otg.service
# reload all service files
$ sudo systemctl daemon-reload
# start created service
$ sudo systemctl start usb-otg.service
# enable also for reboot
$ sudo systemctl enable usb-otg.service
# verify status (optional)
$ sudo systemctl status usb-otg.serviceHere you will see the content of the service /etc/systemd/system/usb-otg.service.
# reboot system
$ sudo rebootBefore you restart the Raspberry PI Zero, you have to change the USB port! So do not use the USB port for power anymore. In addition, make sure that you have Wi-Fi and a second device (for SSH) ready. You connect the Raspberry PI Zero to the target via USB (as Keyboard) and with the second device (over Wi-Fi/SSH) you execute the Bash script.
# confirm /dev/hidg0 (optional)
$ sudo ls -la /dev/hidg0
# confirm /sys/kernel/config/usb_gadget/hid_usb/ (optional)
$ sudo tree /sys/kernel/config/usb_gadget/hid_usb/
├── bcdDevice
├── bcdUSB
├── idProduct
├── idVendor
├── configs
│ └── c.1
│ ├── MaxPower
│ └── strings
│ └── 0x409
│ └── configuration
├── functions
│ └── hid.usb0
│ ├── protocol
│ ├── report_length
│ └── subclass
├── strings
│ └── 0x409
│ ├── manufacturer
│ ├── product
│ └── serialnumber
└── UDCNote: The command line tree is shortened. There are much more directories, files and links!
# download file from GitHub
$ curl -L https://raw.githubusercontent.com/Lupin3000/Raspberry-PI-Tutorials/main/Zero_WIFI_HID/hid_fun.sh -o ~/hid_fun.sh
# change file permissions
$ chmod u+x ~/hid_fun.shHere you will see the content of the bash script.
# new SSH connection
$ ssh pi@[ip of your Raspberry PI Zero]
# execute bash script
$ sudo ~/hid_fun.shIn the configuration example, the value 0x409 is used. This value is for English (United States)!
In case you like to use a different language, have a look on following short example list.
0x402Bulgarian0x403Catalan0x41aCroatian (Standard)0x405Czech0x406Danish0x413Dutch (Standard)0x809English (UK)0x40bFinnish0x40cFrench (Standard)0xc07German (Austria)0x407German (Standard)0x807German (Switzerland)0x408Greek0x40eHungarian0x40fIcelandic0x410Italian (Standard)0x414Norwegian (Bokmal)0x415Polish0x816Portuguese (Standard)0x418Romanian0x40aSpanish (Standard)0x41bSlovak0x424Slovenian0x41dSwedish
Note: Since I don't want to list all available values here, I recommend that you're simply looking for them online.
I wrote a small Python CLI tool, called BullDog. You can use it to simulate the keyboard easier.