Skip to content

Commit

Permalink
Implemented Spacehuhn's WiFiDuck Legacy keys/commands
Browse files Browse the repository at this point in the history
  • Loading branch information
tobozo committed Jan 23, 2022
1 parent 61cb1e2 commit 2a99cd5
Show file tree
Hide file tree
Showing 33 changed files with 5,523 additions and 774 deletions.
35 changes: 23 additions & 12 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The payload syntax is heavily inspired by [whid-injector](https://github.com/whi

- Dongle is detected as Mouse, Keyboard and USB Pendrive
- Mouse driver uses absolute positioning
- Mounted MicroSD card allows editing files from the OS, and reading from the ESP
- Mounted MicroSD card allows editing files from the OS, ~~and~~ or reading from the ESP
- Starts WiFi in AP Mode
- Runs a Webserver with the following endpoints:
- `/key` send string sequence to the keyboard
Expand All @@ -21,8 +21,8 @@ The payload syntax is heavily inspired by [whid-injector](https://github.com/whi
- `/delete` delete a file
- `/upload` upload a file
- `/*` serves the file from the selecte filesystem
- Accepts the following ducky commands:
- `Rem`
- Implements **[SpaceHuhn's WiFiDuck commands](https://github.com/SpacehuhnTech/WiFiDuck#scripting)**, but also comes with a few extras for mouse controls:
- `help` : list all non standard ducky commands
- `logs` : show last logs
- `SetDisplay` [uint16_t+uint16_t] set display dimensions for mouse e.g. `SetDisplay:1920+1080`
- `DrawSpaceInvaders` : draw space invaders with the mouse, needs paint software full screen with brush preselected
Expand All @@ -31,18 +31,28 @@ The payload syntax is heavily inspired by [whid-injector](https://github.com/whi
- `MouseClickLEFT` : pushes left button, call MouseClickRelease to release
- `MouseClickMIDDLE` : pushes middle button, call MouseClickRelease to release
- `MouseDoubleClickLEFT` : does not need MouseClickRelease
- `DefaultDelay` [uint32_t] set default delay between commands
- `CustomDelay` [uint32_t] set custom delay between commands
- `KeyDelay` [uint32_t] set delay between keys
- `Key` [keycode] send a keycode
- `MouseMoveUp` [int8_t] move n pixels to the top, relative to last position, from -127 to 127
- `MouseMoveDown` [int8_t] move n pixels to the bottom, relative to last position, from -127 to 127
- `MouseMoveLeft` [int8_t] move n pixels to the left, relative to last position, from -127 to 127
- `MouseMoveRight` [int8_t] move n pixels to the roght, relative to last position, from -127 to 127
- `Press` [keycode+keycode+keycode....] keyboard shortcuts e.g. KEY_LEFT_CTRL+KEY_LEFT_ALT+KEY_DELETE => `Press:128+130+212`
- `Print` [String] send sentence to keyboard
- `PrintLine` [String] (same as Print but HID_KEY_ENTER appended)
- [soon] ~~`MouseDrawStr` [coord+mousestate+coord+coord....] mouse moves/clics in a string e.g. `MouseDrawStr:X127+Y-127+C1+X127+Y127+Y127+C0+X-127+X-127+C1+X127+X127`~~
- The following custom commands are also internally used at setup/boot, and kept exposed for debug or development:
- `SerialBegin` : start the serial interface
- `SerialDebug` : enable debug on serial
- `InitWiFi` : start wifi (implicit)
- `InitSPIFFS` : start SPIFFS (implicit)
- `InitSD` : start SD card (implicit)
- `InitPenDrive` : start USB PenDrive (implicit)
- `StopSD` : stop SD card (experimental)
- `StopPenDrive` : stop USB Pendrive (experimental)
- `InitKeyboard` : start USB Keyboard (implicit)
- `InitMouse` : start USB mouse (implicit)
- `StartUSB` : start USB (implicit)
- `StartWebServer` : start web server (implicit)
- `StopSerial` : stop serial
- `StopWiFi` : stop WiFi
- `StopKeyboard` : stop USB Keyboard (experimental)
- `StopMouse` : stop USB Mouse (experimental)

- Comes with many bugs but also with an easter egg


Expand Down Expand Up @@ -74,14 +84,15 @@ See the [wiki page](https://wiki.aprbrother.com/en/wud.html) for more info.

## Why Arduino?

- Because [platformio POC](https://github.com/volca/wireless_usb_disk) only works with older packages e.g. EspTinyUSB 1.2.0 / idf 4.2
- Because [platformio POC](https://github.com/volca/wireless_usb_disk) only works with older packages e.g. EspTinyUSB 1.2.0 / idf 4.2 or lags behind
- Because I'm lazy

## Roadmap

- Improved payload parser
- Improved web UI
- Add RNDIS/CDC-ECM (network interface)
- More lambda ducky commands (e.g. read exfiltrated data from USBSerial)


## Credits:
Expand Down
239 changes: 4 additions & 235 deletions USBDevices/USBAbsMouse.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,36 +37,13 @@
#include "USBHID.h"


// some easter egg to test the mouse in absolute positioning mode

#include "../xbm/alien.xbm.h"

typedef struct
{
uint32_t width;
uint32_t height;
uint32_t len;
uint32_t rowlen;
const uint8_t* bytes;
} xbmImage_t;

xbmImage_t Alien_128x64 =
{
alien_width,
alien_height,
alien_bytes,
alien_bytes_per_row,
Alien_128x64_bits
};


void (*MouseLogger)( String err );


static uint8_t _report_id = 0x05;

// we use a custom HID report descriptor with absolute mouse positioning
static const uint8_t report_descriptor[] PROGMEM = {
static const uint8_t abs_mouse_report_descriptor[] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
Expand Down Expand Up @@ -117,7 +94,7 @@ class HIDAbsMouse: public USBHIDDevice
HID = _HID;
if(!initialized){
initialized = true;
HID->addDevice(this, sizeof(report_descriptor));
HID->addDevice(this, sizeof(abs_mouse_report_descriptor));
}
}

Expand All @@ -130,8 +107,8 @@ class HIDAbsMouse: public USBHIDDevice

uint16_t _onGetDescriptor(uint8_t* buffer)
{
memcpy(buffer, report_descriptor, sizeof(report_descriptor));
return sizeof(report_descriptor);
memcpy(buffer, abs_mouse_report_descriptor, sizeof(abs_mouse_report_descriptor));
return sizeof(abs_mouse_report_descriptor);
}

bool send(abs_mouse_report_t * value)
Expand All @@ -151,211 +128,3 @@ class HIDAbsMouse: public USBHIDDevice

};

// GFX class to draw with the mouse

class GfxMouse
{

public:

GfxMouse( HIDAbsMouse *_AbsMouse, uint32_t w=1920, uint32_t h=1080 )
{
AbsMouse = _AbsMouse;
setDisplay( w, h );
};

int32_t screen_width;
int32_t screen_height;
uint32_t delayafter = 20; // ms wait after each report

// the display width/height is used to translate absolute coordinates to values understood by the mouse driver (0-32767)
void setDisplay( uint32_t w, uint32_t h )
{
screen_width = w;
screen_height = h;
if( MouseLogger ) MouseLogger( String( "Mouse moves will translate to ["+String(w)+"*"+String(h)+"]" ) );
sendReport( screen_width/2, screen_height/2, 0 );
}

// where x and y are absolute coordinates (in pixels) on the display
void setRealCoords( int32_t x, int32_t y )
{
// constrain coords to screen width/height
x = max(0, min(screen_width-1, x));
y = max(0, min(screen_height-1, y));
// store position
_lastx = x;
_lasty = y;
// map coords to the display
int32_t px = map( x, 0, screen_width-1, 0, 32767 );
int32_t py = map( y, 0, screen_height-1, 0, 32767 );
MouseReport.x = px;
MouseReport.y = py;
}

void sendDoubleClick( uint8_t buttons_mask, uint32_t pushed, uint32_t released )
{
sendButtons( buttons_mask );
delay( pushed );
sendButtons( 0 );
delay( released );
sendButtons( buttons_mask );
delay( pushed );
sendButtons( 0 );
delay( released );
}

// relative move on the X axis
void moveXrel( int8_t x )
{
sendReport( _lastx+x, _lasty, _lastbtnmask );
}

// relative move on the Y axis
void moveYrel( int8_t y )
{
sendReport( _lastx, _lasty+y, _lastbtnmask );
}

// absolute move on the X axis
void moveXabs( int32_t x )
{
sendReport( x, _lasty, _lastbtnmask );
}

// absolute move on the Y axis
void moveYabs( int32_t y )
{
sendReport( _lastx, y, _lastbtnmask );
}

// relative move on the X+Y axis with button state
void moveXYrel( int8_t x, int8_t y, uint8_t buttons_mask )
{
sendReport( _lastx+x, _lasty+y, buttons_mask );
}

// relative move on the X+Y axis with button state
void moveXYabs( int32_t x, int32_t y, uint8_t buttons_mask )
{
sendReport( x, y, buttons_mask );
}

// absolute move on the X+Y axis with button state
/*
void moveTo( int x, int y, uint8_t buttons_mask )
{
sendReport( x, y, buttons_mask );
}*/

abs_mouse_report_t *getMouseReport()
{
return &MouseReport;
}

// change buttons state without sending report
void setButtons( uint8_t buttons_mask )
{
MouseReport.buttons = buttons_mask;
_lastbtnmask = buttons_mask;
}

uint8_t getButtons()
{
return _lastbtnmask;
}

void sendButtons( uint8_t buttons_mask )
{
setButtons( buttons_mask );
sendReport();
}

void sendReport( int x, int y, uint8_t buttons_mask )
{
setButtons( buttons_mask );
setRealCoords( x, y );
sendReport();
if( _lastbtnmask != buttons_mask ) {
_lastbtnmask = buttons_mask;
vTaskDelay(delayafter);
}
}

void sendReport()
{
if( absmouse_begun ) AbsMouse->send(&MouseReport);
}



void drawLine(int x0, int y0, int x1, int y1, uint8_t buttons_mask )
{
bool steep = false;
if (std::abs(x0-x1)<std::abs(y0-y1)) {
std::swap(x0, y0);
std::swap(x1, y1);
steep = true;
}
if (x0>x1) {
std::swap(x0, x1);
std::swap(y0, y1);
}

sendReport( x0, y0, 0 );
setButtons( buttons_mask );

int dx = x1-x0;
int dy = y1-y0;
float derror = std::abs(dy/float(dx));
float error = 0;
int y = y0;
for (int x=x0; x<=x1; x++) {
if (steep) {
sendReport( y, x, buttons_mask );
} else {
sendReport( x, y, buttons_mask );
}
error += derror;
if (error>.5) {
y += (y1>y0?1:-1);
error -= 1.;
}
}
sendReport( _lastx, _lasty, 0 );
}

void drawXbm( xbmImage_t* xbmImage, int32_t startx, int32_t starty )
{
sendReport( startx, starty, 0 );
for( int i=0; i<xbmImage->len; i++ ) {
uint8_t block = xbmImage->bytes[i];
int32_t x = (i%xbmImage->rowlen)*8;
int32_t y = i/xbmImage->rowlen;
for( uint8_t a=0; a<8; a++ ) {
if( x+a > xbmImage->width ) {
x = 0;
y++;
}
sendReport( startx+x+a, starty+y, (block & (1<<a)) ? MOUSE_LEFT_BTN : 0 );
}
delay(delayafter);
}
sendReport( _lastx, _lasty, 0 );
}

// void drawCircle(int x, int y, int radius ) { }
// void fillCircle(int x, int y, int radius ) { }
// void drawRect(int x, int y, int width, int height ) { }
// void fillRect(int x, int y, int width, int height ) { }


private:
HIDAbsMouse *AbsMouse;
abs_mouse_report_t MouseReport;
int32_t _lastx;
int32_t _lasty;
uint8_t _lastbtnmask;

};

9 changes: 9 additions & 0 deletions USBDevices/USBDevices.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include "../USBDevices/USBKeyboard.h"
#include "../USBDevices/USBAbsMouse.h"
#include "../USBDevices/USBPendrive.h" // this defines HAS_PENDRIVE

USBHID HID;
HIDAbsMouse AbsMouse( &HID );
DuckyKeyboard Keyboard;
Loading

0 comments on commit 2a99cd5

Please sign in to comment.