Add Quick Attack module for one-button USB/UART auto-detection and execution

This commit is contained in:
Claude
2026-09-26 00:12:48 +00:00
parent c6dfc19578
commit a8d77131a2
2 changed files with 157 additions and 0 deletions

View File

@@ -3,6 +3,7 @@
#include "theme.h" #include "theme.h"
#include <M5Cardputer.h> #include <M5Cardputer.h>
Module* makeQuickAttack();
Module* makePinScan(); Module* makePinScan();
Module* makeVSense(); Module* makeVSense();
Module* makeUartSniff(); Module* makeUartSniff();
@@ -54,6 +55,7 @@ Module* makeLogViewer();
void Shell::begin() { void Shell::begin() {
theme::load(); theme::load();
add(makeQuickAttack());
add(makePinScan()); add(makePinScan());
add(makeVSense()); add(makeVSense());
add(makeUartSniff()); add(makeUartSniff());

155
src/modules/quickattack.cpp Normal file
View File

@@ -0,0 +1,155 @@
#include "../core/module.h"
#include "../core/ui.h"
#include <HardwareSerial.h>
class QuickAttack : public Module {
enum Mode { DETECT, HID_INJECT, SERIAL_SHELL, DONE } mode = DETECT;
bool running = false;
uint32_t progress = 0;
uint32_t commands_sent = 0;
char response[256] = "";
HardwareSerial ser;
char msg[3][40] = {{0},{0},{0}};
public:
const char* name() const override { return "Quick Attack"; }
const char* blurb() const override { return "one-button compromise"; }
void onEnter() override {
running = false;
mode = DETECT;
progress = 0;
commands_sent = 0;
memset(response, 0, sizeof(response));
say("Auto-detect + attack");
ser.begin(115200, SERIAL_8N1, 16, 17);
delay(100);
detect();
}
void onExit() override { running = false; ser.end(); }
bool onKey(char c) override {
if (c == ' ') { if (!running) startAttack(); else running = false; return true; }
if (c == 'd') { mode = DETECT; progress = 0; detect(); return true; }
if (c == 's') { sendCommand("id"); return true; }
if (c == 'w') { sendCommand("whoami"); return true; }
return false;
}
void tick() override {
if (!running) return;
progress++;
if (mode == HID_INJECT) {
#ifdef HAVE_TINYSUB
if (progress < 50) {
static const char* cmds[] = {"id\n", "uname -a\n", "cat /proc/version\n"};
if (progress == 10) { sendHidString(cmds[0]); }
if (progress == 25) { sendHidString(cmds[1]); }
if (progress == 40) { sendHidString(cmds[2]); }
} else {
mode = DONE;
running = false;
say("HID injection complete");
}
#endif
} else if (mode == SERIAL_SHELL) {
while (ser.available()) {
char c = ser.read();
if (strlen(response) < sizeof(response) - 1) {
response[strlen(response)] = c;
}
}
if (progress > 100) {
mode = DONE;
running = false;
say("Shell commands sent: %u", (unsigned)commands_sent);
}
}
}
void draw() override {
const char* modes[] = {"DETECT", "HID_INJECT", "SHELL", "DONE"};
ui::lineC(0, ui::accent(), "Quick Attack: %s", modes[mode]);
ui::line(1, "status: %s", running ? "RUNNING" : "ready");
if (mode == DETECT) {
ui::line(2, "detecting target...");
} else if (mode == HID_INJECT) {
ui::bar(2, progress / 50.0f, ui::glow(), "inject");
ui::line(3, "typing commands...");
} else if (mode == SERIAL_SHELL) {
ui::line(2, "commands sent: %u", (unsigned)commands_sent);
if (response[0]) ui::line(3, "RX: %.30s", response);
} else {
ui::lineC(2, ui::glow(), "COMPLETE");
}
for (int i = 0; i < 3; i++) ui::line(7 + i, "%s", msg[i]);
if (running) ui::spinner(228, ui::BODY_Y + 1, ui::glow());
ui::hintBar("[space]attack [s]end-id [w]hoami [d]etect [`]back");
}
private:
void say(const char* fmt, ...) {
for (int i = 2; i > 0; i--) strncpy(msg[i], msg[i-1], 39);
va_list ap; va_start(ap, fmt); vsnprintf(msg[0], 40, fmt, ap); va_end(ap);
}
void detect() {
say("Probing...");
#ifdef HAVE_TINYSUB
if (tud_mounted()) {
mode = HID_INJECT;
say("USB device: HID mode");
return;
}
#endif
ser.write("\r\n");
delay(200);
if (ser.available()) {
mode = SERIAL_SHELL;
say("UART detected: shell mode");
} else {
say("No target detected");
}
}
void startAttack() {
running = true;
progress = 0;
commands_sent = 0;
memset(response, 0, sizeof(response));
say("Attacking...");
}
void sendCommand(const char* cmd) {
ser.print(cmd);
ser.flush();
commands_sent++;
say("TX: %s", cmd);
}
void sendHidString(const char* str) {
#ifdef HAVE_TINYSUB
for (size_t i = 0; i < strlen(str); i++) {
uint8_t keycode = 0;
if (str[i] >= 'a' && str[i] <= 'z') keycode = 0x04 + (str[i] - 'a');
else if (str[i] >= 'A' && str[i] <= 'Z') keycode = 0x04 + (str[i] - 'A');
else if (str[i] >= '0' && str[i] <= '9') keycode = (str[i] == '0') ? 0x27 : 0x1E + (str[i] - '1');
else if (str[i] == ' ') keycode = 0x2C;
else if (str[i] == '\n') keycode = 0x28;
else if (str[i] == '-') keycode = 0x2D;
if (keycode) {
tud_hid_keyboard_report(0, 0, &keycode, 1);
delay(30);
tud_hid_keyboard_report(0, 0, nullptr, 0);
}
}
#endif
commands_sent++;
}
};
Module* makeQuickAttack() { return new QuickAttack(); }