2 Commits

5 changed files with 44 additions and 205 deletions

View File

@@ -1,34 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Debug info**
If possible, include debug serial data.
On Windows, use PuTTY, connect to the debug serial port (commonly COM3, but could vary)
On Linux, use minicom (minicom -b 115200 -o -D /dev/ttyACM0, where ttyACM0 corresponds to your device)
**Additional context**
Add any other context about the problem here.

View File

@@ -20,30 +20,21 @@
Install and have your USB Rubber Ducky working in less than 5 minutes. Install and have your USB Rubber Ducky working in less than 5 minutes.
1. Clone the repo to get a local copy of the files. `git clone https://github.com/dbisu/pico-ducky.git` 1. Download [CircuitPython for the Raspberry Pi Pico](https://circuitpython.org/board/raspberry_pi_pico/). *Updated to 7.0.0
2. Download [CircuitPython for the Raspberry Pi Pico](https://circuitpython.org/board/raspberry_pi_pico/). *Updated to 7.0.0 2. Plug the device into a USB port while holding the boot button. It will show up as a removable media device named `RPI-RP2`.
3. Plug the device into a USB port while holding the boot button. It will show up as a removable media device named `RPI-RP2`. 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`.
4. 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`. 4. Download `adafruit-circuitpython-bundle-7.x-mpy-YYYYMMDD.zip` [here](https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/latest) and extract it outside the device.
5. Download `adafruit-circuitpython-bundle-7.x-mpy-YYYYMMDD.zip` [here](https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/latest) and extract it outside the device. 5. Navigate to `lib` in the recently extracted folder and copy `adafruit_hid` to the `lib` folder in your Raspberry Pi Pico.
6. Navigate to `lib` in the recently extracted folder and copy `adafruit_hid` to the `lib` folder on your Raspberry Pi Pico. 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.
7. Copy `adafruit_debouncer.mpy` and `adafruit_ticks.mpy` to the `lib` folder on your Raspberry Pi Pico. 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. Copy `asyncio` to the `lib` folder on your 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.
9. Copy `boot.py` from your clone to the root of your Pico.
10. Copy `duckyinpython.py` as `code.py` in the root of the Raspberry Pi Pico, overwriting the previous file.
Linux: `cp duckyinpython.py </path/to/pico/code.py`
11. 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.
12. 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 ### Setup mode
@@ -55,10 +46,11 @@ The easiest way to so is by using a jumper wire between those pins as seen bello
### USB enable/disable mode ### USB enable/disable mode
If you need the pico-ducky to not show up as a USB mass storage device for stealth, follow these instructions. If you need the pico-ducky to not show up as a USB mass storage device for stealth, follow these instructions.
Enter setup mode. Enter setup mode.
Copy boot.py to the root of the pico-ducky.
Copy your payload script to the pico-ducky. Copy your payload script to the pico-ducky.
Disconnect the pico from your host PC. Disconnect the pico from your host PC.
Connect a jumper wire between pin 18 (`GND`) and pin 20 (`GPIO15`). Connect a jumper wire between pin 18 and pin 20.
This will prevent the pico-ducky from showing up as a USB drive when plugged into the target computer. This will prevent the pico-ducky from showing up as a USB drive when plugged into the target computer.
Remove the jumper and reconnect to your PC to reprogram. Remove the jumper and reconnect to your PC to reprogram.
The default mode is USB mass storage enabled. The default mode is USB mass storage enabled.
@@ -119,33 +111,8 @@ from keyboard_layout_win_LANG import KeyboardLayout
from keycode_win_LANG import Keycode from keycode_win_LANG import Keycode
``` ```
##### Example: Set to German Keyboard (WIN_DE)
```py
from keyboard_layout_win_de import KeyboardLayout
from keycode_win_de import Keycode
```
Copy the files keyboard_layout_win_de.mpy and keycode_win_de.mpy to the /lib folder on the Pico board
```
adafruit_hid/
keyboard_layout_win_de.mpy
keycode_win_de.mpy
```
## Useful links and resources ## Useful links and resources
### How to recover your Pico if it becomes corrupted or doesn't boot.
[Reset Instructions](RESET.md)
### Installation Tool
[raspberrypi5621](https://github.com/raspberrypi5621) Created a tool to convert a blank RPi Pico to a ducky.
You can find the tool [here](https://github.com/raspberrypi5621/pyducky)
### Docs ### Docs
[CircuitPython](https://circuitpython.readthedocs.io/en/6.3.x/README.html) [CircuitPython](https://circuitpython.readthedocs.io/en/6.3.x/README.html)

View File

@@ -1,7 +0,0 @@
# Instructions on how to reset a Raspberry Pi Pico
Follow these instructions if your Pico ends up in an odd state
1. Download the reset firmware from [flash_nuke.uf2](https://datasheets.raspberrypi.com/soft/flash_nuke.uf2)
2. While holding the BOOTSEL button on the Pico, plug in the USB cable to your computer.
3. When the RPI-RP2 drive shows up on your computer, copy the flash_nuke.uf2 file to the Pico
4. After the device reboots, follow the Install instructions [here](https://github.com/dbisu/pico-ducky/blob/main/README.md)

View File

@@ -1,6 +1,10 @@
from board import * from board import *
import digitalio import digitalio
import storage import storage
import usb_hid
usb_hid.disable()
usb_hid.enable((usb_hid.Device.KEYBOARD,))
noStorageStatus = False noStorageStatus = False
noStoragePin = digitalio.DigitalInOut(GP15) noStoragePin = digitalio.DigitalInOut(GP15)

View File

@@ -18,29 +18,9 @@ import supervisor
import time import time
import digitalio import digitalio
from digitalio import DigitalInOut, Pull
from adafruit_debouncer import Debouncer
from board import * from board import *
import pwmio led = digitalio.DigitalInOut(LED)
import asyncio led.direction = digitalio.Direction.OUTPUT
led = pwmio.PWMOut(LED, frequency=5000, duty_cycle=0)
def led_pwm_up(led):
for i in range(100):
# PWM LED up and down
if i < 50:
led.duty_cycle = int(i * 2 * 65535 / 100) # Up
time.sleep(0.01)
def led_pwm_down(led):
for i in range(100):
# PWM LED up and down
if i >= 50:
led.duty_cycle = 65535 - int((i - 50) * 2 * 65535 / 100) # Down
time.sleep(0.01)
# led = digitalio.DigitalInOut(LED)
# led.direction = digitalio.Direction.OUTPUT
duckyCommands = { duckyCommands = {
'WINDOWS': Keycode.WINDOWS, 'GUI': Keycode.GUI, 'WINDOWS': Keycode.WINDOWS, 'GUI': Keycode.GUI,
@@ -129,22 +109,8 @@ supervisor.disable_autoreload()
# sleep at 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) time.sleep(.5)
led_pwm_up(led) led.value = True
#init button
button1_pin = DigitalInOut(GP22) # defaults to input
button1_pin.pull = Pull.UP # turn on internal pull-up resistor
button1 = Debouncer(button1_pin)
#init payload selection switch
payload1Pin = digitalio.DigitalInOut(GP4)
payload1Pin.switch_to_input(pull=digitalio.Pull.UP)
payload2Pin = digitalio.DigitalInOut(GP5)
payload2Pin.switch_to_input(pull=digitalio.Pull.UP)
payload3Pin = digitalio.DigitalInOut(GP10)
payload3Pin.switch_to_input(pull=digitalio.Pull.UP)
payload4Pin = digitalio.DigitalInOut(GP11)
payload4Pin.switch_to_input(pull=digitalio.Pull.UP)
def getProgrammingStatus(): def getProgrammingStatus():
# check GP0 for setup mode # check GP0 for setup mode
@@ -161,34 +127,38 @@ def runScript(file):
global defaultDelay global defaultDelay
duckyScriptPath = file duckyScriptPath = file
try: f = open(duckyScriptPath,"r",encoding='utf-8')
f = open(duckyScriptPath,"r",encoding='utf-8') previousLine = ""
previousLine = "" for line in f:
for line in f: line = line.rstrip()
line = line.rstrip() if(line[0:6] == "REPEAT"):
if(line[0:6] == "REPEAT"): for i in range(int(line[7:])):
for i in range(int(line[7:])): #repeat the last command
#repeat the last command parseLine(previousLine)
parseLine(previousLine) time.sleep(float(defaultDelay)/1000)
time.sleep(float(defaultDelay)/1000) else:
else: parseLine(line)
parseLine(line) previousLine = line
previousLine = line time.sleep(float(defaultDelay)/1000)
time.sleep(float(defaultDelay)/1000)
except OSError as e:
print("Unable to open file ", file)
def selectPayload(): def selectPayload():
global payload1Pin, payload2Pin, payload3Pin, payload4Pin
payload = "payload.dd" payload = "payload.dd"
# check switch status # check switch status
# payload1 = GPIO4 to GND # payload1 = GPIO4 to GND
# payload2 = GPIO5 to GND # payload2 = GPIO5 to GND
# payload3 = GPIO10 to GND # payload3 = GPIO10 to GND
# payload4 = GPIO11 to GND # payload4 = GPIO11 to GND
payload1Pin = digitalio.DigitalInOut(GP4)
payload1Pin.switch_to_input(pull=digitalio.Pull.UP)
payload1State = not payload1Pin.value payload1State = not payload1Pin.value
payload2Pin = digitalio.DigitalInOut(GP5)
payload2Pin.switch_to_input(pull=digitalio.Pull.UP)
payload2State = not payload2Pin.value payload2State = not payload2Pin.value
payload3Pin = digitalio.DigitalInOut(GP10)
payload3Pin.switch_to_input(pull=digitalio.Pull.UP)
payload3State = not payload3Pin.value payload3State = not payload3Pin.value
payload4Pin = digitalio.DigitalInOut(GP11)
payload4Pin.switch_to_input(pull=digitalio.Pull.UP)
payload4State = not payload4Pin.value payload4State = not payload4Pin.value
@@ -212,63 +182,6 @@ def selectPayload():
return payload return payload
async def blink_pico_led(led):
print("starting blink_pico_led")
led_state = False
while True:
if led_state:
#led_pwm_up(led)
print("led up")
for i in range(100):
# PWM LED up and down
if i < 50:
led.duty_cycle = int(i * 2 * 65535 / 100) # Up
await asyncio.sleep(0.01)
led_state = False
else:
#led_pwm_down(led)
print("led down")
for i in range(100):
# PWM LED up and down
if i >= 50:
led.duty_cycle = 65535 - int((i - 50) * 2 * 65535 / 100) # Down
await asyncio.sleep(0.01)
led_state = True
await asyncio.sleep(0)
async def monitor_buttons(button1):
global inBlinkeyMode, inMenu, enableRandomBeep, enableSirenMode,pixel
print("starting monitor_buttons")
button1Down = False
while True:
button1.update()
button1Pushed = button1.fell
button1Released = button1.rose
button1Held = not button1.value
if(button1Pushed):
print("Button 1 pushed")
button1Down = True
if(button1Released):
print("Button 1 released")
if(button1Down):
print("push and released")
if(button1Released):
if(button1Down):
# Run selected payload
payload = selectPayload()
print("Running ", payload)
runScript(payload)
print("Done")
button1Down = False
await asyncio.sleep(0)
progStatus = False progStatus = False
progStatus = getProgrammingStatus() progStatus = getProgrammingStatus()
@@ -282,12 +195,8 @@ if(progStatus == False):
else: else:
print("Update your payload") print("Update your payload")
led_state = False while True:
time.sleep(1.0)
async def main_loop(): led.value = False
global led,button1 time.sleep(1.0)
pico_led_task = asyncio.create_task(blink_pico_led(led)) led.value = True
button_task = asyncio.create_task(monitor_buttons(button1))
await asyncio.gather(pico_led_task, button_task)
asyncio.run(main_loop())