diff --git a/README.md b/README.md index ac5f97a..8d082fe 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,62 @@ -# pico-ducky -Create a USB Rubber Ducky like device using a Raspberry PI Pico +

pico-ducky

-Download circuitpython for pico board: -https://circuitpython.org/board/raspberry_pi_pico/ +
+ Make a cheap but powerful USB Rubber Ducky with a Raspberry Pi Pico +
-Plug the Pico board into a USB port. -The board will show up as a removable media device. -Copy the UF2 file to the root of the media device. +
-The Pico board will reboot after installing the firmware image. +
+ GitHub code size in bytes + GitHub license + GitHub contributors + GitHub commit activity + GitHub Repo stars +
-Download additional libraries: -https://github.com/adafruit/Adafruit_CircuitPython_Bundle +
-https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/tag/20210130 +## Install -from zip file, unpack adafruit_hid folder. -copy adafruit_hid to the lib folder. +Install and have your USB Rubber Ducky working in less than 5 minutes. -Circuitpy HID -https://learn.adafruit.com/circuitpython-essentials/circuitpython-hid-keyboard-and-mouse +1. Download [CircuitPython for the Raspberry Pi Pico](https://circuitpython.org/board/raspberry_pi_pico/). +2. Plug the device into a USB port. It will show up as a removable media device named `RPI-RP2`. -# Ducky Script Python -Copy duckyinpython.py to the root of the media device as code.py +3. Copy the downloaded `.uf2` file to the root of the Pico (`RPI-RP2`). The device will reboot and after a second or so, it will reconnect as `CIRCUITPY`. -$ cp duckyinpython.py //code.py +4. Download `adafruit-circuitpython-bundle-6.x-mpy-YYYYMMDD.zip` [here](https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/latest) and extract it outside the device. -Copy your Ducky Script file as payload.dd +5. Navigate to `lib` in the recently extracted folder and copy `adafruit_hid` to the `lib` folder in your Raspberry Pi Pico. -$ cp /path to media device>/payload.dd +6. Click [here](https://raw.githubusercontent.com/dbisu/pico-ducky/main/duckyinpython.py), press CTRL + S and save the file as `code.py` in the root of the Raspberry Pi Pico, overwriting the previous file. -# NEW: added support for a programming switch. -Tie pin 0 (GPIO0) to pin 3 (GND) to not automatically run payloads. -Easiest way to do this is to add a jumper wire between those pins. -![jumper wire](pics/jumper.png) +7. Find a script [here](https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Payloads) or [create your own one using Ducky Script](https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript) and save it as `payload.dd` in the Pico. + +8. Be careful, if your device isn't in [setup mode](#setup-mode), the device will reboot and after half a second, the script will run. + +### Setup mode + +To edit the payload, enter setup mode by connecting the pin 1 (`GP0`) to pin 3 (`GND`), this will stop the pico-ducky from injecting the payload in your own machine. +The easiest way to so is by using a jumper wire between those pins as seen bellow. + +![Setup mode with a jumper](images/setup-mode.png) + +## Useful links and resources + +### Docs + +[CircuitPython](https://circuitpython.readthedocs.io/en/6.3.x/README.html) + +[CircuitPython HID](https://learn.adafruit.com/circuitpython-essentials/circuitpython-hid-keyboard-and-mouse) + +[Ducky Script](https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript) + +### Video tutorials + +[pico-ducky tutorial by **NetworkChuck**](https://www.youtube.com/watch?v=e_f9p-_JWZw) + +[USB Rubber Ducky playlist by **Hak5**](https://www.youtube.com/playlist?list=PLW5y1tjAOzI0YaJslcjcI4zKI366tMBYk) + +[CircuitPython tutorial on the Raspberry Pi Pico by **DroneBot Workshop**](https://www.youtube.com/watch?v=07vG-_CcDG0) \ No newline at end of file diff --git a/duckyinpython.py b/duckyinpython.py index 777b0b8..50487a7 100644 --- a/duckyinpython.py +++ b/duckyinpython.py @@ -27,8 +27,8 @@ def convertLine(line): newline = [] print(line) for j in range(len(keycodeCommands)): - if line.find(duckyCommands[j]) != -1: - newline.append(keycodeCommands[j]) + if line.find(duckyCommands[j]) != -1: + newline.append(keycodeCommands[j]) print(newline) return newline @@ -42,7 +42,7 @@ def sendString(line): def parseLine(line): if(line[0:3] == "REM"): - #comments - ignore + # ignore ducky script comments print("") elif(line[0:5] == "DELAY"): time.sleep(float(line[6:])/1000) @@ -59,19 +59,18 @@ def parseLine(line): kbd = Keyboard(usb_hid.devices) layout = KeyboardLayoutUS(kbd) -#sleep a the start to allow the device to be recognized by the host computer +# sleep at the start to allow the device to be recognized by the host computer time.sleep(.5) - -# check GPIO0 for program switch -# easiest way to implement is to run a jumper from pin 0 (GPIO0) to pin3 (GND) +# check GP0 for setup mode +# see setup mode for instructions progStatus = False progStatusPin = digitalio.DigitalInOut(GP0) progStatusPin.switch_to_input(pull=digitalio.Pull.UP) progStatus = progStatusPin.value defaultDelay = 0 if(progStatus == True): - #not in programming state, run script file + # not in setup mode, inject the payload duckyScriptPath = "payload.dd" f = open(duckyScriptPath,"r",encoding='utf-8') print("Running payload.dd") @@ -89,6 +88,6 @@ if(progStatus == True): previousLine = line time.sleep(float(defaultDelay)/1000) - print("Done...") + print("Done") else: - print("Update new payload file") + print("Update your payload") diff --git a/images/setup-mode.png b/images/setup-mode.png new file mode 100644 index 0000000..05d495c Binary files /dev/null and b/images/setup-mode.png differ diff --git a/payload.dd b/payload.dd index 880a2e8..5f21333 100644 --- a/payload.dd +++ b/payload.dd @@ -1,4 +1,6 @@ -REM Testing Script -STRING atom test.txt -DELAY 2000 -GUI L +REM The next four lines open Notepad in Windows and type "Hello World!" +GUI r +STRING notepad +ENTER +DELAY 250 +STRING Hello World! \ No newline at end of file diff --git a/pics/jumper.png b/pics/jumper.png deleted file mode 100644 index bc55606..0000000 Binary files a/pics/jumper.png and /dev/null differ