Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
Pi-Zero-2W-Bad-USB — Configure your Pi Zero 2W to be a BadUSB | Kitploit
Инструменты/GitHubGitHub/psycostea/pi-zero-2w-bad-usb
Embedded Systems SecurityExploitationScripting & AutomationHardware HackingCTFPenetration TestingLearning & EducationRed TeamingPayload Development
GitHubpsycostea/pi-zero-2w-bad-usb

Pi-Zero-2W-Bad-USB

Configure your Pi Zero 2W to be a BadUSB

3722 месяцев назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий

Raspberry Pi Zero 2 W BadUSB HID Toolkit

Программируемая платформа для атак BadUSB / HID, построенная на Raspberry Pi Zero 2 W. Pi эмулирует составное USB-устройство (клавиатуру плюс опциональный доступный только для чтения том массового хранения) и выполняет пейлоады в стиле Ducky-Script на хосте, к которому она подключена. Предназначена для авторизованных заданий red-команд, тестирования на проникновение и CTF.

⚠️ Юридическое уведомление. Используйте только на системах, которыми вы владеете или на которые имеете явное письменное разрешение на тестирование. Несанкционированный доступ незаконен в большинстве юрисдикций, и притворство, что вы не знали, не поможет.


Содержание

  1. Возможности
  2. Как это работает
  3. Аппаратное обеспечение
  4. Установка
  5. Ежедневная эксплуатация
  6. Написание пейлоадов
  7. Справочник по конфигурации
  8. Заметки по архитектуре
  9. Тесты
  10. Устранение неполадок
  11. Структура репозитория
  12. Благодарности

Возможности

  • Программируемые пейлоады нажатий клавиш в диалекте, совместимом с Ducky-Script.
  • Надёжное обнаружение подключения хоста через состояние UDC configured — никаких ложных запусков пейлоада при загрузке.
  • «Сброс между атаками», который действительно работает на оборудовании Pi Zero 2 W. Отключи, подключи снова, запусти — без перезагрузки.
  • Настраиваемые меры защиты от бесконечных циклов, если устройство остаётся подключённым: минимальный интервал между срабатываниями и ограничение частоты срабатываний в минуту, оба переопределяются переменными окружения.
  • Опциональное составное устройство массового хранения на основе плоского образа файла (по умолчанию только чтение — открытие вашей живой SD-карты было старой, трудно отлаживаемой ловушкой повреждения файловой системы).
  • Раскладки клавиатуры US и UK, выбираемые для каждого пейлоада с помощью LAYOUT.
  • Переменные, IF / ELSE, WHILE, HOLD / RELEASE, INJECT_MOD, генераторы RANDOM_*, STRING_BLOCK / STRINGLN_BLOCK, DEFINE.
  • Интеграция с systemd с ExecStop, который корректно отключает гаджет. Никаких остаточных состояний configfs, перезапуск работает без перезагрузки.
  • Управление правами через udev для /dev/hidg0 — никаких узлов устройств, доступных на запись всем.
  • Набор из 34 тестов pytest для парсера Ducky, запускаемый на любом хосте без подключённого Pi.
  • Индикатор состояния на ACT LED после каждого выполнения пейлоада.

Как это работает

root@kitploit:~
+----------------+        USB cable        +-------------+
|  Raspberry Pi  | ===================>>>  |  Host PC    |
|  Zero 2 W      |   (Pi эмулирует HID +  |  (целевой)  |
|  (это устройство)|    опциональный диск)  |             |
+----------------+                         +-------------+
        |
        |  /home/pi/pi-badusb/
        |
        +-- badusb.service ----> monitor_and_run.py
                                   |
                                   |  при `state == configured`:
                                   v
                                 run_payload.py
                                   |
                                   v
                                 /dev/hidg0  (USB HID гаджет)
  1. При загрузке systemd-юнит badusb.service запускает gadget_setup.sh, который с помощью configfs/libcomposite собирает USB-гаджет с функцией HID-клавиатуры и (опционально) LUN массового хранения на основе плоского образа файла в /var/badusb/storage.img.
  2. Затем юнит запускает monitor_and_run.py. Он опрашивает /sys/class/udc/<udc>/state и ждёт configured — состояние USB-спецификации, означающее, что хост успешно перечислил гаджет. (Мы не используем существование /dev/hidg0 как сигнал: оно истинно в момент привязки гаджета к UDC при загрузке, независимо от того, что-либо подключено или нет.)
  3. Когда хост подключается, слушатель запускает run_payload.py, который разбирает payload.txt и записывает HID-отчёты в /dev/hidg0.
  4. Когда пейлоад завершается, слушатель активно отвязывает гаджет от UDC (Pi Zero 2 W не может обнаружить физическое отключение программно — см. ), ждёт время остывания и повторно привязывает. Затем устройство ждёт следующего перехода в .

Аппаратное обеспечение

КомпонентПримечание
Raspberry Pi Zero 2 WПротестировано на ревизии оборудования 2026-05. Более старые Pi Zero W с драйвером BCM2835 dwc_otg также работают в принципе, но этот README предполагает 2 W с dwc2.
Кабель micro-USB → USB-AИли переходник в форм-факторе «USB-флешки», позволяющий подключить Pi напрямую к порту хоста.
Опционально: отдельное зарядное устройствоЕсли вы хотите питать Pi от источника, отличного от хоста, чтобы слушатель мог загрузиться до подключения к целевому устройству (в противном случае питание подаётся от порта хоста).

Pi Zero 2 W имеет два micro-USB порта:

  • PWR IN — только питание, не выставляет линии данных USB на блок OTG dwc2.
  • USB — порт данных OTG; сюда подключаетесь к целевому устройству.

Программное обеспечение


Установка

Клонируйте или скопируйте репозиторий на Pi, затем запустите установщик:

root@kitploit:~
git clone http://your-gitea/admin/Pi-Zero-2W-Bad-USB.git /home/pi/pi-badusb
cd /home/pi/pi-badusb
sudo ./install.sh
sudo reboot

После перезагрузки включите и запустите сервис:

root@kitploit:~
sudo systemctl enable --now badusb.service
journalctl -u badusb -f

install.sh идемпотентен — запускайте его повторно при изменении файлов проекта. Он:

  • Определяет /boot/firmware (Bookworm+) vs /boot (старые версии).
  • Убеждается, что dtoverlay=dwc2,dr_mode=otg активен под блоком [all] в config.txt. По умолчанию Raspberry Pi Imager помещает эту строку внутрь фильтра [cm5], который не применяется на Pi Zero 2 W; установщик добавляет переопределение с меткой, чтобы повторные запуски не дублировали её.
  • Убеждается, что modules-load=dwc2 присутствует в cmdline.txt.
  • Предупреждает, если g_ether всё ещё присутствует в cmdline.txt (он перехватывает UDC у libcomposite и ломает режим гаджета).
  • Устанавливает systemd-юнит в /etc/systemd/system/badusb.service.
  • Устанавливает правило udev в /etc/udev/rules.d/99-badusb-hidg.rules, чтобы был доступен для записи группе .

Ежедневная эксплуатация

root@kitploit:~
# Запуск / остановка / перезапуск
sudo systemctl start badusb
sudo systemctl stop badusb
sudo systemctl restart badusb              # безопасно, даже если подключено

# Просмотр лога в реальном времени
journalctl -u badusb -f

# Отключение автозапуска при загрузке
sudo systemctl disable badusb

# Настройка таймингов (создаёт переопределение drop-in)
sudo systemctl edit badusb
# (вставьте блок [Service] с Environment="BADUSB_REARM_COOLDOWN_S=8" и т.д.)
sudo systemctl restart badusb

Сервис зависит от sys-kernel-config.mount и наличия UDC, поэтому он не сможет запустить пейлоады, пока гаджет не будет действительно готов.

Редактирование пейлоада не требует перезапуска — payload.txt читается заново при каждом подключении.


Написание пейлоадов

payload.txt находится в каталоге установки. Полная справка по командам — в payload_commands.md.

Минимальный пример

root@kitploit:~
REM Открыть диалог Run и напечатать приветствие через Notepad
LAYOUT US
GUI r
DELAY 1500
STRING notepad
ENTER
DELAY 2500
STRINGLN Hello from the Pi Zero 2 W

Переменные, условия, циклы

root@kitploit:~
VAR $USER="alice"
VAR $COUNT=0
WHILE $COUNT < 3
  STRINGLN Hello $USER (iteration $COUNT)
  VAR $COUNT = $COUNT + 1
END_WHILE

IF $USER == "alice"
  STRINGLN matched
ELSE
  STRINGLN missed
END_IF

Математические выражения в VAR проходят через безопасный вычислитель обхода ast — никаких имён, вызовов, доступа к атрибутам, только числовые литералы и + - * / // % **.

Удержание модификаторов

root@kitploit:~
HOLD SHIFT
STRINGLN эта строка ЗАГЛАВНЫМИ
RELEASE SHIFT

Отправка произвольных комбинаций модификаторов

root@kitploit:~
REM Удерживать Ctrl+Shift (0x01 + 0x02) и нажать A
INJECT_MOD 0x03
STRING a
REM Отпустить все модификаторы
INJECT_MOD 0x00

Случайные значения

root@kitploit:~
RANDOM_LETTER 12      # 12 случайных букв в разном регистре
RANDOM_NUMBER 6       # 6 случайных цифр
RANDOM_SPECIAL 4      # 4 случайных символа ASCII

Раскладка клавиатуры

root@kitploit:~
LAYOUT UK             # переключиться на британскую раскладку для последующих STRING/STRINGLN
STRING @ " # ~ £ \ |  # правильно печатается на хосте с британской раскладкой

Поместите ещё один файл в keymaps/ (рядом с us.py и uk.py), и директива LAYOUT <name> подхватит его через importlib.


Справочник по конфигурации

Гаджет массового хранения (в начале gadget_setup.sh)

Эти значения можно переопределить для каждого вызова, установив их в окружении при ручном запуске gadget_setup.sh, или глобально через директивы Environment= юнита.

Настраиваемые параметры слушателя (monitor_and_run.py)

Переопределение:

root@kitploit:~
sudo systemctl edit badusb
# В редакторе:
# [Service]
# Environment="BADUSB_REARM_COOLDOWN_S=8"
# Environment="BADUSB_MIN_INTER_FIRE_S=20"
sudo systemctl restart badusb

Заметки по архитектуре

Почему слушатель использует состояние UDC state, а не /dev/hidg0

В предыдущей реализации проверка существования и доступности для записи /dev/hidg0 использовалась как сигнал «хост подключён». Этот узел устройства создаётся в момент привязки гаджета к UDC при загрузке — задолго до того, как какой-либо хост фактически его перечислил. Поэтому пейлоады запускались сразу после включения питания независимо от того, куда был подключён Pi.

Надёжным сигналом является /sys/class/udc/<udc>/state, который сообщает состояние устройства по USB-спецификации. Только configured означает, что хост выдал SetConfiguration(1) — теперь устройство может отправлять HID-отчёты.

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

Обнаружение физического отключения на Pi Zero 2 W невозможно программно: плата не подключает VBUS sense к блоку OTG dwc2 SoC. После физического отключения:

  • /sys/class/udc/<udc>/state остаётся configured.
  • current_speed остаётся high-speed.
  • Регистр dwc2 GOTGCTL остаётся 0x000d0000 (бит BSesVld установлен).
  • Никаких событий udev не происходит.

Поэтому вместо ожидания сигнала, который никогда не придёт, слушатель активно вызывает отключение: после каждого пейлоада он записывает "" в файл UDC configfs гаджета (что ядро интерпретирует как отвязку), ждёт BADUSB_REARM_COOLDOWN_S, затем записывает имя UDC обратно для повторной привязки. Следующее подключение хоста порождает чистый переход в configured, который слушатель может обнаружить.

Если оператор оставляет Pi подключённым после пейлоада, повторная привязка вызывает повторное перечисление гаджета хостом. Чтобы предотвратить бесконечный цикл срабатываний, включены две меры защиты:

  1. BADUSB_MIN_INTER_FIRE_S — если переход в configured происходит в пределах этого окна после предыдущего срабатывания, подавить его и снова отвязать. Гаджет циклически молча в фоне.
  2. BADUSB_MAX_FIRES_PER_MINUTE — скользящее жёсткое ограничение. При превышении лимита слушатель приостанавливается на BADUSB_RATELIMIT_PAUSE_S и логирует предупреждение.

Почему мы никогда не используем rm -rf для configfs

Файлы атрибутов, управляемые ядром, в configfs (bcdUSB, idVendor, webusb/*, os_desc/*, …) не могут быть удалены через rm(2) — ядро возвращает EPERM. Они освобождаются только при rmdir их родительского каталога. Как gadget_setup.sh, так и teardown_gadget.sh обходят дерево configfs в каноническом порядке libcomposite — только rmdir, никогда rm для файлов атрибутов — и ядро автоматически очищает остальное.

Почему Python-помощники используют os.write, а не file.write

Запись пустой строки через open(path, "w").write("") не вызывает write(2) с нулевым количеством байт — TextIOWrapper CPython пропускает его. Для отвязки configfs (которую ядро интерпретирует как запись нулевой длины после обрезания символа новой строки) мы используем непосредственно os.write(fd, b"\n"), чтобы системный вызов всегда выполнялся хотя бы с одним байтом.


Тесты

Парсер Ducky имеет набор из 34 тестов pytest, которые запускаются против MockHIDEngine (внутренний заменяющий модуль для реального записи HID), поэтому не требуется ни Pi, ни USB-оборудования.

root@kitploit:~
cd /home/pi/pi-badusb
python3 -m pytest tests/

Покрытие включает:

  • safe_eval_math – принимает арифметику, отклоняет имена / вызовы / доступ к атрибутам / строковые константы.
  • evaluate_condition – для числовых и чувствительных к регистру строковых сравнений.
  • VAR с =, +=, -=, *=, /=.
  • IF / ELSE / END_IF – выбор правильной ветки.
  • WHILE / END_WHILE – количество итераций для < и <=.

Устранение неполадок

«Пейлоад никогда не срабатывает при подключении»

  1. cat /sys/class/udc/*/state — должно достигнуть configured, когда хост перечисляет устройство. Если остаётся not attached, хост не общается: попробуйте другой кабель (некоторые только для зарядки) или другой порт хоста.
  2. lsmod | grep dwc2 — должен быть загружен. Если только dwc_otg, dtoverlay=dwc2,dr_mode=otg не применяется; перезапустите install.sh и перезагрузитесь.
  3. journalctl -u badusb -f при подключении — должно показывать Host attached. Running payload. в течение ~2 секунд после перечисления хоста.

«Пейлоад срабатывает циклически с мигающим LED, даже при отключении»

Это была реальная ошибка, которая теперь исправлена. Если это происходит, вы вернулись к версии до os.write. Убедитесь, что monitor_and_run.py соответствует текущей основной ветке (ищите os.write(fd, payload)).

«Сервис не перезапускается — Operation not permitted»

До исправления gadget_setup.sh использовал rm -rf для configfs. Текущая версия использует teardown_gadget() — если вы видите эти ошибки, у вас старая копия. Повторно разверните из основной ветки.

«Отказано в доступе к /dev/hidg0»

Правило udev требует горячего подключения для применения, или sudo udevadm trigger и повторного входа в систему, чтобы пользователь pi приобрёл группу plugdev.

«Предупреждение g_ether при установке»

Удалите g_ether из cmdline.txt; он захватывает UDC до того, как libcomposite сможет привязаться.

«Хост показывает USB-диск, но он не того размера, который я ожидал»

Размер массового хранения задаётся BACKING_SIZE_MB и вступает в силу только при первом запуске, когда создаётся образ. Чтобы изменить размер:

root@kitploit:~
sudo systemctl stop badusb
sudo rm /var/badusb/storage.img
sudo BACKING_SIZE_MB=256 /home/pi/pi-badusb/gadget_setup.sh
sudo systemctl start badusb

«Я хочу оставить Pi подключённым, чтобы он не спамил хост»

Для этого предназначены BADUSB_MIN_INTER_FIRE_S и BADUSB_MAX_FIRES_PER_MINUTE. Установите их выше через systemctl edit badusb. С настройками по умолчанию Pi, оставленный подключённым, будет срабатывать каждые ~15 секунд в течение первой минуты, затем сделает паузу на 60 секунд, затем возобновит.


Структура репозитория

root@kitploit:~
.
├── README.md                   Этот файл
├── LICENSE                     MIT
├── install.sh                  Идемпотентный установщик (конфигурация прошивки, systemd, udev, plugdev)
├── gadget_setup.sh             Собирает USB-гаджет через configfs/libcomposite
├── teardown_gadget.sh          Каноническое отключение configfs (используется как ExecStop)
├── reload_gadget.sh            Вспомогательный скрипт для ручной отвязки/привязки UDC
├── autorun.sh                  Устаревшая обёртка для ручного запуска (рекомендуется systemd)
├── monitor_and_run.py          Слушатель: ждёт подключения хоста, запускает пейлоад, принудительно перезаряжает
├── run_payload.py              Интерпретатор в стиле Ducky-Script
├── payload.txt                 Ваш пейлоад — редактируйте свободно; перечитывается при каждом подключении
├── payload_commands.md         Полная справка по командам
├── etc/
│   ├── badusb.service          systemd-юнит
│   └── 99-badusb-hidg.rules    правило udev для /dev/hidg0
├── keymaps/
│   ├── __init__.py             Динамический загрузчик раскладок
│   ├── us.py                   US ANSI (по умолчанию)
│   └── uk.py                   UK ISO
└── tests/
    ├── __init__.py
    ├── conftest.py             Настройка путей для pytest
    └── test_parser.py          34 теста парсера против MockHIDEngine

Благодарности

  • Оригинальные скрипты проекта и вдохновение: Psycostea.
  • Исследования USB-гаджетов: USB Rubber Ducky, Hak5, документация libcomposite, драйвер ядра dwc2.
  • Исправления корректности 2026-05: переписано обнаружение подключения хоста, сделан безопасным массовый накопитель, исправлены несколько ошибок парсера, добавлена абстракция раскладок, миграция запуска на systemd, добавлена инфраструктура модульных тестов и обход невозможности обнаружения физического отключения на уровне оборудования Pi Zero 2 W.

Лицензия

MIT — см. LICENSE.

Скачать инструмент
Заметки по архитектуре
configured
ТребованиеЗачем
Raspberry Pi OS (Debian Bookworm или Trixie, рекомендуется 64-битная Lite)Скрипт установки пишет в /boot/firmware/... на Bookworm+ и делает откат к /boot/... на старых образах.
Python 3Поставляется с Pi OS.
mkfs.vfatДля форматирования образа массового хранения при первом запуске. Отключите, если массовое хранение не используется.
Доступ root для настройкиЗатрагивает systemd, udev и /boot/firmware/config.txt.
/dev/hidg0
plugdev
  • Добавляет пользователя pi в группу plugdev.
  • Создаёт /var/badusb/ для образа массового хранения.
  • ПеременнаяПо умолчаниюЗначение
    ENABLE_MASS_STORAGE10 для гаджета только HID.
    BACKING_FILE/var/badusb/storage.imgПлоский образ, доступный хосту.
    BACKING_SIZE_MB64Создаётся при первом запуске, если отсутствует.
    BACKING_LABELBADUSBМетка тома FAT.
    MASS_STORAGE_RO1Только чтение по умолчанию.
    Переменная окруженияПо умолчаниюЗначение
    BADUSB_POST_PAYLOAD_FLUSH_S0.5Задержка после пейлоада перед отвязкой, чтобы HID-записи были отправлены.
    BADUSB_REARM_COOLDOWN_S5Как долго гаджет остаётся невидимым для хоста между отвязкой и повторной привязкой.
    BADUSB_MIN_INTER_FIRE_S10Минимальное количество секунд между двумя срабатываниями пейлоада; если меньше, срабатывание подавляется и гаджет отвязывается снова.
    BADUSB_MAX_FIRES_PER_MINUTE6Жёсткий лимит; при превышении пауза на BADUSB_RATELIMIT_PAUSE_S.
    BADUSB_RATELIMIT_PAUSE_S60Длительность паузы после превышения лимита.
  • RANDOM_* – корректность длины; RANDOM_<неизвестно> – no-op + предупреждение.
  • INJECT_MOD – сохранение байта модификатора между последующими нажатиями.
  • HOLD SHIFT – преобразование каждого символа в STRINGLN abc в заглавный.
  • LAYOUT US vs LAYOUT UK – разные отчёты для @ и "; неизвестная раскладка возвращается к предыдущей.
  • STRING_BLOCK – объединение строк; STRINGLN_BLOCK – учёт минимального отступа.