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/modules
Here 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_usb
Here 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.local
Note: 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.service
Here you will see the content of the service /etc/systemd/system/usb-otg.service
.
# reboot system
$ sudo reboot
Before 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
└── UDC
Note: 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.sh
Here 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.sh
In 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.
0x402
Bulgarian0x403
Catalan0x41a
Croatian (Standard)0x405
Czech0x406
Danish0x413
Dutch (Standard)0x809
English (UK)0x40b
Finnish0x40c
French (Standard)0xc07
German (Austria)0x407
German (Standard)0x807
German (Switzerland)0x408
Greek0x40e
Hungarian0x40f
Icelandic0x410
Italian (Standard)0x414
Norwegian (Bokmal)0x415
Polish0x816
Portuguese (Standard)0x418
Romanian0x40a
Spanish (Standard)0x41b
Slovak0x424
Slovenian0x41d
Swedish
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.