diff --git a/README.md b/README.md index 065611c..21ff8a3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,9 @@ A physical pentesting toolkit on a regular Raspberry Pi Pico. ### Intro -The Raspberry Pi Pico is a flexible microcontroller board designed for multiple purposes. With this project I intend to use make a powerful Keystroke Injection tool for such an intricate board with a special purpose. It is designed to be easy to configure, modify, and use for fun. This will be designed to be a little more than a *Bad USB*. Instead of being a basic, high level program on a Pico, we build firmware designed for this purpose. +You've probably seen other similar tools for other MCU's and SBC's, such as the ESP32 Marauder, ESP8266 Deauther, P4wnP1 A.L.O.A, PocketPhishr, Pwnagotchi, etc. Although these are all very good projects, there hasn't been much talk regarding the Raspberry Pi Pico becoming a good tool in the right hands. + +The Raspberry Pi Pico is a flexible microcontroller board designed for multiple purposes. With this project, I intend to use make a powerful Keystroke Injection tool for such an intricate board with a special purpose. It is designed to be easy to configure, modify, and use for fun. This will be designed to be a little more than a *Bad USB*. Instead of being a basic, high-level program on a Pico, we build firmware designed for keystroke injection. ### Development progress This [project](https://github.com/users/dj1ch/projects/3) showcases my progress thus far. @@ -20,24 +22,24 @@ Unlike your usual *Bad USB*, the setup is a lot more complex. 3. Your config must be edited to allow the script to be run on startup after editing it, using the shell or your computer. -**Before asking to install, this is merely a blueprint for what I will be working on for the next couple weeks!** +**Before asking to install, this is merely a blueprint for what I will be working on for the next couple of weeks!** ### The shell -The shell allows you to do a fair share of things with the board, allowing you to make it look like a USB drive by blinking the LED, checking board stats, and the testing of payloads. I plan on making this a very small "OS" for the Pico to do basic things. +The shell allows you to do a fair share of things with the board, allowing you to make it look like a USB drive by blinking the LED, checking board stats, and testing of payloads. I plan on making this a very small "OS" for the Pico to do basic things. ### FAQ **How long will it be until a release?** -Most of the changes haven't been tested and it is yet to work as intended. This might take a while depending on how long it will take to implement the wanted feature(s). Most likely this will all be finalized sometime around March/April 2024 +Most of the changes haven't been tested and it is yet to work as intended. This might take a while depending on how long it will take to implement the wanted feature(s). Most likely this will all be finalized sometime around late April 2024 **Can it do things other than Keystroke injection?** -It's pretty bare bones right now, it has a work in progress text editor, to build the scripts on the board without having to worry about editing the files on your own computer, along with being able to test scripts on the device it is plugged into. Unless we can implement some way to control GPIO over the shell, it does only keystroke injection. The OS itself is minimal and can only do so much. +It's pretty bare bones right now, it has a work-in-progress text editor, to build the scripts on the board without having to worry about editing the files on your computer, along with being able to test scripts on the device it is plugged into. Unless we can implement some way to control GPIO over the shell, it does only keystroke injection. The OS itself is minimal and can only do so much. ### Contributing -TBA, will add contributing guidelines soon +TBA will add contributing guidelines soon **Made with :heart: by [@dj1ch](https://github.com/dj1ch)** diff --git a/pico-key/boot.c b/pico-key/boot.c new file mode 100644 index 0000000..50e70d2 --- /dev/null +++ b/pico-key/boot.c @@ -0,0 +1,34 @@ +/** + * boot.c + * "bootup" process to run after the firmware is loaded +*/ + +#include "boot.h" + +int boot() { + // boot logo + char coolArt[] = "pico-key..."; + char author[] = "by dj1ch"; + + // print this ^^ + printf("\n%s\n", coolArt); + sleep(1); + printf("%s\n", author); + + // board info + boardInfo(); + + if (config.run_on_startup) { + read(); + return 0; + } else { + // do nothing + } +} + +void boardInfo() { + // we can only really print memory here + printf("\nBoard info:\n"); + printf(malloc_stats() + " bytes"); + printf(checkConfig()); +} \ No newline at end of file diff --git a/pico-key/boot.h b/pico-key/boot.h new file mode 100644 index 0000000..0ada610 --- /dev/null +++ b/pico-key/boot.h @@ -0,0 +1,16 @@ +/** + * boot.h + * headers for boot.c +*/ + +#ifndef BOOT_H +#define BOOT_H + +#include "config.h" +#include "pico/stdio.h" +#include "pico/malloc.h" + +int boot(); +void boardInfo(); + +#endif // BOOT_H \ No newline at end of file diff --git a/pico-key/config.c b/pico-key/config.c new file mode 100644 index 0000000..54daaea --- /dev/null +++ b/pico-key/config.c @@ -0,0 +1,14 @@ +/** + * config.c + * configuration related things in a source file +*/ + +#include "config.h" + +void checkConfig(const Configuration& config) { + printf("\nCurrent Config: \n"); + printf("LED Pin definition: %d\n", config.led_pin); + printf("Payload location: %s\n", config.payload_location.c_str()); + printf("Run on startup: %s\n", config.run_on_startup ? "true" : "false"); + printf("Current version: %s\n", config.version.c_str()); +} \ No newline at end of file diff --git a/pico-key/config.h b/pico-key/config.h index da17339..6a39b51 100644 --- a/pico-key/config.h +++ b/pico-key/config.h @@ -6,12 +6,22 @@ #ifndef CONFIG_H #define CONFIG_H -// configuration parameters +#include +#include "pico/stdio.h" + +// default config params #define LED_PIN PICO_DEFAULT_LED_PIN -#define PAYLOAD_LOCATION "/payload.dd" -#define RUN_ON_STARTUP true +#define DEFAULT_PAYLOAD_LOCATION "/payload.dd" +#define DEFAULT_RUN_ON_STARTUP true + +// configuration structure +struct Configuration { + int led_pin; + std::string payload_location; + bool run_on_startup; + std::string version; +}; -// version -#define VERSION "0.1.0-alpha\n" +void checkConfig(); -#endif // CONFIG_H \ No newline at end of file +#endif // CONFIG_H diff --git a/pico-key/duckyscript.c b/pico-key/duckyscript.c new file mode 100644 index 0000000..cd127a6 --- /dev/null +++ b/pico-key/duckyscript.c @@ -0,0 +1,38 @@ +/** + * duckyscript.c + * this handles the commmands and the hid +*/ + +#include "duckyscript.h" + +// run a duckyscript command based on what is in duckyscript.h +int run(const char* command) { + + return 0; +} + +// crap i gotta build a new compiler for this :/ +void read(const char* filePath) { + FILE *file = fopen(filePath, "r"); + + if (file == NULL) { + perror("Can't open '%s' :/", filePath); + return; + } + + char line[256]; + while (fgets(line, sizeof(line), file)) { + char *command = strtok(line, " \t\n"); + + char *param = strtok(NULL, "\n"); + while (param && strtok(NULL, "\n")) { + strcat(command, " "); + strcat(command, param); + param = strtok(NULL, "\n"); + } + + run(command); + } + + fclose(filePath); +} \ No newline at end of file diff --git a/pico-key/duckyscript.h b/pico-key/duckyscript.h new file mode 100644 index 0000000..c1382ff --- /dev/null +++ b/pico-key/duckyscript.h @@ -0,0 +1,123 @@ +/** + * duckyscript.h + * define duckyscript in C...? +*/ + +#ifndef DUCKYSCRIPT_H +#define DUCKYSCRIPT_H + +#include +#include "pico/stdio.h" + +// control keys +#define WINDOWS 0x08 +#define GUI 0x10 +#define APP 0x20 +#define MENU 0x40 +#define SHIFT 0x80 +#define ALT 0x40 +#define CONTROL 0x20 +#define CTRL 0x20 + +// arrows +#define DOWNARROW 0x51 +#define DOWN 0x51 +#define LEFTARROW 0x50 +#define LEFT 0x50 +#define RIGHTARROW 0x4F +#define RIGHT 0x4F +#define UPARROW 0x52 +#define UP 0x52 + +// other keys +#define BREAK 0x48 +#define PAUSE 0x48 +#define CAPSLOCK 0x39 +#define DELETE 0x4C +#define END 0x4D +#define ESC 0x29 +#define ESCAPE 0x29 +#define HOME 0x4A +#define INSERT 0x49 +#define NUMLOCK 0x53 +#define PAGEUP 0x4B +#define PAGEDOWN 0x4E +#define PRINTSCREEN 0x46 +#define ENTER 0x28 +#define SCROLLLOCK 0x47 +#define SPACE 0x2C +#define TAB 0x2B +#define BACKSPACE 0x2A + +// abc's +#define A 0x04 +#define B 0x05 +#define C 0x06 +#define D 0x07 +#define E 0x08 +#define F 0x09 +#define G 0x0A +#define H 0x0B +#define I 0x0C +#define J 0x0D +#define K 0x0E +#define L 0x0F +#define M 0x10 +#define N 0x11 +#define O 0x12 +#define P 0x13 +#define Q 0x14 +#define R 0x15 +#define S 0x16 +#define T 0x17 +#define U 0x18 +#define V 0x19 +#define W 0x1A +#define X 0x1B +#define Y 0x1C +#define Z 0x1D + +// f keys +#define F1 0x3A +#define F2 0x3B +#define F3 0x3C +#define F4 0x3D +#define F5 0x3E +#define F6 0x3F +#define F7 0x40 +#define F8 0x41 +#define F9 0x42 +#define F10 0x43 +#define F11 0x44 +#define F12 0x45 + +// mouse actions +typedef enum { + MOUSE_MOVE, + CLICK, + RIGHT_CLICK, + MIDDLE_CLICK +} mse; + +// keyboard actions +typedef enum { + PRESS_KEY, + RELEASE_KEY +} key; + +// mouse commands +typedef struct { + mse action; + int x; + int y; +} mseCommand; + +// keyboard commands +typedef struct { + key action; + char key; +} keyCommand; + +void run(); + +#endif // DUCKYSCRIPT_H \ No newline at end of file diff --git a/pico-key/easter-egg.c b/pico-key/easter-egg.c new file mode 100644 index 0000000..9eae776 --- /dev/null +++ b/pico-key/easter-egg.c @@ -0,0 +1,36 @@ +/** + * egg.c + * maybe this is an easter egg ;) +*/ + +#include "easter-egg.h" + +void specialMessage() { + printf("\nWhat did you expect to be here???\n"); + printf("\nAnyway, wanna play a game? (Y/N) > "); + + char* specialChoice[10]; + + fgets(specialChoice, sizeof(specialChoice), stdin); + specialChoice[strcspn(specialChoice, "\n")] = '\0'; + + for (int i = 0; specialChoicep[i]; i++) { + specialChoice[i] = toupper(specialChoice[i]); + } + + if (strcmp(specialChoice, "Y") == 0) { + continue; + } else if (strcmp(specialChoice, "N") == 0) { + break; + } else { + printf("%s: Not a valid response\n", specialChoice); + continue; + } + + // cool game + game(); +} + +void game() { + +} \ No newline at end of file diff --git a/pico-key/easter-egg.h b/pico-key/easter-egg.h new file mode 100644 index 0000000..8484d71 --- /dev/null +++ b/pico-key/easter-egg.h @@ -0,0 +1,16 @@ +/** + * egg.h + * special header? +*/ + +#ifndef EASTER_EGG_H +#define EASTER_EGG_H + +#include "pico/stdio.h" + +char* specialChoice[10]; + +void specialMessage(); +void game(); + +#endif // EASTER_EGG_H \ No newline at end of file diff --git a/pico-key/pico-key.c b/pico-key/pico-key.c index 15ad07c..52b4e0a 100644 --- a/pico-key/pico-key.c +++ b/pico-key/pico-key.c @@ -8,42 +8,7 @@ * old pr w/ python is here: https://github.com/dj1ch/pico-key/pull/1/commits/5d4c65106c6aa490b7eb047827c1ed3a00a21377 */ -// config -#include "config.h" - -// libraries -#include -#include -#include -#include - -// sdk -#include "pico/stdio.h" -#include "pico/stdlib.h" -#include "pico/malloc.h" -#include "hardware/uart.h" -#include "hardware/gpio.h" - -void boot() { - // boot logo - char coolArt[] = "pico-key..."; - char author[] = "by dj1ch"; - - // print this ^^ - printf("\n%s\n", coolArt); - sleep(1); - printf("%s\n", author); - - // board info - boardInfo(); - - if (RUN_ON_STARTUP) { - read(); - return 0; - } else { - // do nothing - } -} +#include "pico-key.h" int main() { boot(); @@ -80,6 +45,10 @@ int main() { options(); break; + case 69: + specialMessage(); + break; + default: printf("\n%d: Invalid choice :/\n", choice); break; @@ -94,7 +63,7 @@ void buildScript() { printf("Type 'exit' to stop.\n"); // assume it's named payload.dd - FILE *file = fopen(PAYLOAD_LOCATION, "w"); + FILE *file = fopen(config.payload_location, "w"); if (file == NULL) { printf("Failed to open payload.dd! :(\n"); @@ -128,13 +97,44 @@ void buildScript() { } void testScript() { + printf("\nRemember that testing the script will run this on your machine!\n"); + char userWarning[10]; -} + while (1) { + printf("Are you okay with this? (Y/N) > "); -// crap i gotta build a new compiler for this :/ -void read() { + // get only the characters + fgets(userWarning, sizeof(userWarning), stdin); + userWarning[strcspn(userWarning, "\n")] = '\0'; -} + // convert to uppercase + for (int i = 0; userWarning[i]; i++) { + userWarning[i] = toupper(userWarning[i]); + } + + if (strcmp(userWarning, "Y") == 0) { + continue; + } else if (strcmp(userWarning, "N") == 0) { + break; + } else { + printf("%s: Not a valid response\n", userWarning); + continue; + } + } + + char scriptPath[256]; + while (1) { + printf("Script to test? > "); + fgets(scriptPath, sizeof(scriptPath), stdin); + scriptPath[strcspn(scriptPath, "\n")] = '\0'; + + if (strcmp(scriptPath, "EXIT") == 0 || strcmp(scriptPath, "exit") == 0) { + break; + } else { + read(scriptPath); + } + } +} void fakeUSB() { bool led = false; @@ -216,11 +216,4 @@ void options() { if (strcmp(choiceC, "1") == 0) { boardInfo(); } -} - -void boardInfo() { - // we can only really print memory here - printf("\nBoard info:\n"); - printf(malloc_stats() + " bytes"); - printf(VERSION); } \ No newline at end of file diff --git a/pico-key/pico-key.h b/pico-key/pico-key.h new file mode 100644 index 0000000..ccc3653 --- /dev/null +++ b/pico-key/pico-key.h @@ -0,0 +1,32 @@ +/** + * pico-key.h + * main header for main stuff +*/ + +#ifndef PICO_KEY_H +#define PICO_KEY_H + +#include "config.h" +#include "boot.h" +#include "duckyscript.h" +#include "easter-egg.h" + +#include +#include +#include +#include + +#include "pico/stdio.h" +#include "pico/stdlib.h" +#include "hardware/uart.h" +#include "hardware/gpio.h" + +int main(); +void buildScript(); +void testScript(); +void read(); +void fakeUSB(); +void misc(); +void options(); + +#endif // PICO_KEY_H \ No newline at end of file