Coder Social home page Coder Social logo

hungdojan / elastic-quacker Goto Github PK

View Code? Open in Web Editor NEW
1.0 3.0 0.0 18.21 MB

Implementation of RubberDucky-like device on Raspberry Pi Pico W.

License: MIT License

CMake 0.97% Makefile 0.75% C 51.03% Python 47.25%
c python raspberry-pi-pico rubber-ducky security-tools lwip tinyusb

elastic-quacker's Introduction

Implementation of RubberDucky using Raspberry Pi Pico W

This repository contains source files used in practical part of my bachelor thesis "Implement Rubber Duckies on Available USB Devices and Make a Practical Test".

Author: Hung Do (xdohun00)
School: Faculty of Information Technologies, BUT
Year: 2022/2023

Introduction

Rubber Ducky is a USB device produced by Hak5, a tool used for injecting keystrokes into the host machine. It can be used for penetration testing or educational purposes. My goal was to create a software that runs on top of Raspberry Pi Pico W that behaves in a similar way as a Rubber Ducky device. The project uses TinyUSB library to enable keyboard emulation. My software provides:

  • HID (keyboard) and MSC (mass storage) support.
    • Mass Storage is a PoC feature (for now...).
  • rd_client parser that converts a payload written in custom RD script to C source code.
  • Control the USB device and upload new payloads wirelessly. You don't need to recompile the code everytime you fix change your payload.
  • Rerun your script without unplugging the device. Simple toggle the DEBUG_CAPS_LOCK feature before compiling the code.

The result? See it for yourself (sound on):

20230417_115156.mp4

Requirements

This project was developed and tested on 5.15.104-2-MANJARO x86_64 GNU/Linux operating system.

Softwares required to run this project are:

Optionally, you may want to install

  • poetry (optional, developed and tested with version 1.4.0)

The installation of the listed softwares will differ depending on the user's operating systems.

Setting up this project

In order to build this project, user is required to initialized all submodules needed. This set of commands installs the bare minimum that the project needs to run or to develop on. If you want to install everything use command git submodule update --init --recursive (optional).

git clone https://github.com/hungdojan/RubberDucky_BachelorThesis.git
cd RubberDucky_BachelorThesis
git submodule init
git submodule update --init

# initialize pico-sdk submodules
cd pico-sdk
git submodule update --init

Compile project and upload to the device

The project can be compile with a given Makefile. Simply run make command in the project's root directory. That will create a build directory build_rd with lots of new generated files. In there you will find build_rd/rubber_ducky/rubber_ducky.uf2 binary file that you will copy to your Raspberry Pi Pico device. You can find a tutorial on how to drop UF2 binary onto Raspberry Pi Pico device here.

You can also compile the project manually. Just create a new build directory and run cmake .. -DPICO_SDK_PATH=../pico-sdk/ in it. That will create a Makefile inside the build directory. Then call make command to generate UF2 binary file.

mkdir build_rd
cd build_rd
cmake .. -DPICO_SDK_PATH=../pico-sdk/
make -j8

# ...or one-liner from the root directory
cmake -H. -B'build_rd' -DPICO_SDK_PATH=pico-sdk/ && make -C'build_rd' -j8

The Makefile script offers more actions which you can find all of them listed here.

RD script parser

Additionally, I created a Python script that converts a custom RD script to a series of key presses readable by our Rubber Ducky device. rd_client module app currently supports 2 modes:

  • CLI mode - Used to convert RD script to C source code. Replace the output with `rubber_ducky/
  • Client mode - Send the transformed RD script over TCP socket. Need to be connected to Rubber Ducky Wifi.

The TUI mode is not implemented yet but is planned in the future.

You can run Python scripts using Makefile/poetry or Python. No special modules required. There are 8 arguments that you can run the script with. To list all of them run python -m rd_client -h or poetry run app -h in the project's root directory.

$ poetry run app -h
usage: RubberDucky script parser [-h] [--version] [-H IP address] [-i filename] [-l filename] [-n] [-o filename] [-p PORT] [-t] [-v]

options:
  -h, --help                        show this help message and exit
  --version                         show program's version number and exit
  -H IP address, --host IP address  IP address of the RubberDucky device.
  -i filename, --input filename     Source RubberDucky script file.
  -l filename, --log_file filename  Log filename. Defaults to STDERR.
  -n, --network                     Upload script using networking.
  -o filename, --output filename    Generated output filename.
  -p PORT, --port PORT              Application port of the RubberDucky device. Defaults to 5000.
  -t, --tui                         Open program in interactive mode.
  -v, --verbose                     Enable logging.

Configuration and RD script language rules

User is allowed to modify Rubber Ducky's device configuration file rubber_ducky/config.h. Check the configuration documentation for more detailed information.

RD script is a custom language designed to allow user to easily write the payloads. It is inspired by vim key notations. The language supports:

  • single line comments
  • setting delays - wait for a defined time period before pressing another keys
  • holding delay - keys are pressed for a defined time period
  • huge selection of keys to press - list of them can be found here
  • up to 6 keys + modifiers simultaneously pressed - allows to run shortcuts
    • doesn't include special keys, only one special key can be pressed at a time (plan to update this in the future)

You can find more information related to RD script language here.

# example script that opens terminal and list out current directory's content
# Ubuntu's keyboard shortcut for opening terminal is Ctrl+Alt+t
<c-a-t>

# wait for the terminal to open (500 ms)
<DELAY 500>

# run the command
ls<\enter>

Make commands

The given Makefile contains 7 useful commands that the user can call. They are all listed below:

  • make or make build - Calls cmake and compiles the project in pico-build directory. If enabled this command will also generate compile_commands.json file.
  • make clean - Removes generated files from the project directory.
  • make run_cli - Runs a Python script which transform RD script file into C source code.
  • make run_client - Once connected to Rubber Ducky's WiFi, this command can be used to send a new RD script to the USB device.
  • make test - Runs a Python unit tests and shows the coverage. Requires poetry.
  • make test_show_coverage - Runs a Python unit tests and shows the coverage in the firefox. Requires poetry and firefox.

If you use language servers like ccls you can enable compile_commands.json generation in the script. Just uncomment the forth line in the Makefile:

# C project: Bachelor Thesis
BUILD_DIR=./build_rd
CMAKE_MACROS=-DCMAKE_BUILD_TYPE=Debug -DPICO_SDK_PATH=pico-sdk/
#CMAKE_MACROS+=-DCMAKE_EXPORT_COMPILE_COMMANDS=YES   # <<< uncomment this line
...

Basic usage

Here are some example of the use cases:

  • Change Rubber Ducky's starting/default script. Replace make run_cli with python -m rd_client -v if poetry is not present on your machine.
$ make run_cli > rubber_ducky/keyseqv/key_seqv_script.c
INFO :: ------ Start parsing script ------
<c-a-t><DELAY 500>firefox fit.vut.cz<\enter>
INFO :: Modifiers: [LCTRL, LALT]; Keys: [t]
INFO :: Wait: 500 ms; 
INFO :: Keys: [f, i, r, e]
INFO :: Keys: [f, o, x, space]
INFO :: Keys: [f, i, t, ., v, u]
INFO :: Keys: [t, ., c, z]
INFO :: Keys: [enter]
^D
INFO :: ------- Writing to output -------
INFO :: -------- Writing finished --------
INFO :: Number of key sequences: 12
$
$ echo "<\meta><DELAY 500>notepad<\enter><DELAY 500>hello world<\enter>" | make run_cli > /dev/null
INFO :: ------ Start parsing script ------
INFO :: Modifiers: [LMETA]; 
INFO :: Wait: 500 ms; 
INFO :: Keys: [n, o, t, e, p, a]
INFO :: Keys: [d]
INFO :: Keys: [enter]
INFO :: Wait: 500 ms; 
INFO :: Keys: [h, e, l]
INFO :: Keys: [l, o, space, w]
INFO :: Keys: [o, r, l, d]
INFO :: Keys: [enter]
INFO :: ------- Writing to output -------
INFO :: -------- Writing finished --------
INFO :: Number of key sequences: 16
$
$ make run_cli < scripts/linux_open_fit_vut_page.txt > rubber_ducky/keyseqv/key_seqv_script.c 
INFO :: ------ Start parsing script ------
INFO :: Modifiers: [LCTRL, LALT]; Keys: [t]
INFO :: Wait: 500 ms; 
INFO :: Keys: [f, i, r, e]
INFO :: Keys: [f, o, x, space]
INFO :: Keys: [f, i, t, ., v, u]
INFO :: Keys: [t, ., c, z]
INFO :: Keys: [enter]
INFO :: ------- Writing to output -------
INFO :: -------- Writing finished --------
INFO :: Number of key sequences: 12
  • Upload script to Rubber Ducky device using client mode. Replace make run_client with python -m rd_client -vn -p 5000 -H 192.168.4.1. The machine needs to be connected to Rubber Ducky's wifi network. Network's SSID and password can be found in rubber_ducky/config.h file. You can change those to your liking.
$ cat rubber_ducky/config.h | grep "define WIFI"
    #define WIFI_ENABLE 1
    #define WIFI_SSID "RubberDucky_WiFi"
    #define WIFI_PSWD "TheCakeIsALie"
$ make run_client < scripts/win_trackmania_training01.txt
INFO :: ------ Start parsing script ------
INFO :: Hold: 3350 ms; Keys: [w]
INFO :: Hold: 500 ms; Keys: [d]
INFO :: Hold: 900 ms; Keys: [w, d]
INFO :: Hold: 300 ms; Keys: [w]
INFO :: Hold: 500 ms; Keys: [a]
INFO :: Hold: 800 ms; Keys: [a, w]
INFO :: Hold: 600 ms; Keys: [w]
INFO :: Hold: 500 ms; Keys: [d]
INFO :: Hold: 500 ms; Keys: [w, d]
INFO :: Hold: 1500 ms; Keys: [w]
INFO :: ------ Connecting to host... ------
INFO :: --------- Sending to host ---------
INFO :: Sent - SET_EDITABLE:   [01]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - CLEAR_DATA:     []
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [16 0d 00 00 00 00 1a 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [00 00 00 00 00 00 00 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [f4 01 00 00 00 00 07 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [00 00 00 00 00 00 00 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [84 03 00 00 00 00 1a 07  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [00 00 00 00 00 00 00 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [2c 01 00 00 00 00 1a 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [00 00 00 00 00 00 00 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [f4 01 00 00 00 00 04 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [00 00 00 00 00 00 00 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [20 03 00 00 00 00 04 1a  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [00 00 00 00 00 00 00 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [58 02 00 00 00 00 1a 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [00 00 00 00 00 00 00 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [f4 01 00 00 00 00 07 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [00 00 00 00 00 00 00 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [f4 01 00 00 00 00 1a 07  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [00 00 00 00 00 00 00 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [dc 05 00 00 00 00 1a 00  00 00 00 00 00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - PUSH_DATA:      [00 00 00 00 00 00 00 00  00 00 00 00 01]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - SET_EDITABLE:   [00]
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: Sent - RUN_SEQUENCES:  []
INFO :: Recv - RESPONSE_OK:    [0a 00 00 00]
INFO :: ----- Payload successfully sent -----
INFO :: Number of key sequences: 20

Contribution

Feel free to fork this repository and create a new projects on top of this. New feature suggestions or bug fixes are also welcomed. Have fun.

elastic-quacker's People

Contributors

hungdojan avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

elastic-quacker's Issues

Handling bad parsing in `network_mode.py`

There is no parsing handling in rd_client/app_modes/network_mode.py. If the user inputs the key sequence in the wrong format, nothing will take care of the ParserError exception raised by the rd_client/parser module.

JSON support

Allow users to create key sequences with JSON structure. The structure would look something like this:

[
  {
    "delay": 0,
    "report": {
      "modifiers": [
        "KEYBOARD_MODIFIER_LEFTCTRL",
        "KEYBOARD_MODIFIER_LEFTALT"
      ],
      "keycodes": [
        "HID_KEY_DELETE"
      ]
    },
    "last_item": false,
  },
  {
    "delay": 200,
    "report": {
      "modifiers": [],
      "keycodes": []
    },
    "last_item": true,
  },
]

will be equivalent to <c-a-\delete><DELAY 200>.

Implementation of hold delay

Regex: (<DELAY (\d+)>)|(<((?:(\d+)-)?((?:[a-z]{1,2}-)*)([a-z\d]+|[^<>\s]+))>)|([ -~])|(\[DELAY (\d+)\])

In the fifth position, the user can find the value of the hold delay.

Meta key button

Add a way to toggle meta key alone (to open the Start menu on Windows).

Logging string multi-line breaking issue

When a string is broken into two lines in logging it creates an error not all arguments converted during string formatting.

Full stack trace:

--- Logging error ---
Traceback (most recent call last):
  File "/usr/lib64/python3.11/logging/__init__.py", line 1110, in emit
    msg = self.format(record)
          ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/logging/__init__.py", line 953, in format
    return fmt.format(record)
           ^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/logging/__init__.py", line 687, in format
    record.message = record.getMessage()
                     ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/logging/__init__.py", line 377, in getMessage
    msg = msg % self.args
          ~~~~^~~~~~~~~~~
TypeError: not all arguments converted during string formatting
Call stack:
  File "/home/hungdo/disk/VUT/RubberDucky_BachelorThesis/scripts/parser-cli.py", line 61, in <module>
    main()
  File "/home/hungdo/disk/VUT/RubberDucky_BachelorThesis/scripts/parser-cli.py", line 51, in main
    ksp.parse_content()
  File "/home/hungdo/disk/VUT/RubberDucky_BachelorThesis/scripts/rd_parser/key_seqv_parser.py", line 260, in parse_content
    self.parse_line(line, i)
  File "/home/hungdo/disk/VUT/RubberDucky_BachelorThesis/scripts/rd_parser/key_seqv_parser.py", line 234, in parse_line
    self.__check_special_keys(match, line_index)
  File "/home/hungdo/disk/VUT/RubberDucky_BachelorThesis/scripts/rd_parser/key_seqv_parser.py", line 193, in __check_special_keys
    logging.error('When pressing normal keys, special key sequence should',
Message: 'When pressing normal keys, special key sequence should'
Arguments: ('not contain shift modifier in the script.',)

Find a way to fix this.

Sending small files

Add a new feature where a user can upload a small file to the Rubber Ducky device.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.