
Перехватывает и анализирует трафик USB Mass Storage на уровне блоков и файлов, эмулирует USB-устройства и поддерживает пользовательские заглушки Python для исследований в области безопасности, криминалистики и тестирования уязвимостей TOCTOU.

usb-spy — это анализатор трафика USB Mass Storage, построенный на базе микроконтроллера с поддержкой WiFi или Ethernet.
Плата предоставляет образ диска (FAT или любая файловая система) в виде поддельного USB-устройства массового хранения для целевой системы, в то время как реальные данные хранятся на удалённом сервере, доступном через WiFi или Ethernet. Такая конфигурация позволяет usb-spy перехватывать и анализировать каждый блок, к которому обращается целевая система.
Помимо трассировки на уровне сырых блоков, usb-spy понимает файловые системы и может сопоставить каждый прочитанный блок с соответствующим файлом и каталогом, что позволяет сразу видеть, какой файл читается или записывается, а не только номера секторов.
Кроме того, usb-spy может эмулировать любое USB-устройство, настраивая его свойства, такие как идентификатор производителя, идентификатор продукта, серийный номер, производитель и название продукта, через JSON-файл конфигурации. Это позволяет выдавать себя за определённые USB-устройства для целей тестирования и анализа.
Инструмент легко расширяется с помощью пользовательских заглушек на Python, позволяя реализовать собственную логику обработки событий чтения/записи USB и операций на уровне блоков.

При обнаружении поддерживаемой файловой системы usb-spy:
В настоящее время поддерживаются следующие файловые системы:
Поддержка дополнительных файловых систем будет добавлена в будущем.
Если файловая система не поддерживается, usb-spy всё равно можно использовать:
Это гарантирует, что usb-spy остаётся полезным даже с неизвестными, пользовательскими или проприетарными файловыми системами.

Инструкции по сборке прошивки для каждой поддерживаемой платы приведены здесь:
Исходный код находится в каталоге src. Он загружает FAT-образ, предоставляет к нему доступ через TCP-порт и регистрирует каждое обращение к образу. Для вывода информации о файлах и каталогах инструмент использует библиотеку TheSleuthKit.
Для сборки выполните следующую команду в корневом каталоге
Получите все подмодули
git submodule update --init --recursive
Затем выполните команду настройки waf.
./waf configure
Она проверит и соберёт все необходимые зависимости, а затем для непосредственной сборки проекта выполните
./waf build
Бинарный файл будет находиться в каталоге wbuild
Это легко сделать с помощью пакета утилит mtools
Создайте файл размером 2 МБ
dd if=/dev/zero of=disk.img bs=1M count=2
Поместите на него файловую систему FAT (используйте -F для FAT32, иначе она автоматическая)
mformat -i disk.img ::
Добавьте в него файл
mcopy -i disk.img example.txt ::
Список файлов
mdir -i disk.img ::
Извлеките файл
mcopy -i disk.img ::/example.txt extracted.txt
Запустите шпиона с только что созданным образом
./usb-spy -v disk.img
Подключите плату к целевому USB-порту.
Для эмуляции определённого USB-устройства параметры можно переопределить через JSON-файл конфигурации:
Следующий JSON-файл эмулирует USB-устройство Kingston DataTraveler:
{
"vendor_id": 2385,
"product_id": 5734,
"bcd_device": 272,
"product_rev": "3.0",
"manufacturer": "Kingston",
"product_name": "DataTraveler",
"serial": "509C4BBFACCDE742880C026B",
"language": 1033
}
Запустите шпиона с этим файлом конфигурации
./usb-spy -c config/kingston.json disk.img
Вывод dmesg для этого устройства:
usb 1-8: New USB device found, idVendor=0951, idProduct=1666, bcdDevice= 1.10
usb 1-8: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-8: Product: DataTraveler
usb 1-8: Manufacturer: Kingston
usb 1-8: SerialNumber: 509C4BBFACCDE742880C026B
usb-storage 1-8:1.0: USB Mass Storage device detected
scsi host6: usb-storage 1-8:1.0
scsi 6:0:0:0: Direct-Access Kingston DataTraveler 3.0 PQ: 0 ANSI: 2
Если вы хотите реализовать свою логику для каждого события чтения/записи, это можно легко сделать на Python.
Реализуйте класс USBImage на Python, как в этом dummy образце:
class USBImage:
def __init__(self, *args, **kwargs):
"""
Initialize the USBImage.
:param args: should contain:
- filename: The name of the file to manage.
:param kwargs: Arbitrary arguments passed from the c++ command line including:
readOnly: Whether the interface is read-only.
verbose: Whether to enable verbose logging.
block: Whether to enable block mode.
"""
pass
def getBlockNumber(self):
"""Get block number"""
return 100
def getBlockSize(self):
"""Get block size"""
return 512
def read(self, lba, buffer, size):
"""Read block"""
print(f"read block={lba} size={size}")
for i in range(size):
buffer[i] = (lba + i) % 256 # Simulate reading data
return size
def write(self, lba, buffer, size):
"""Write block"""
print(f"write block={lba} size={size}")
print(buffer)
return size
def flush(self):
"""Flush block"""
print("flush data")
И запустите шпиона со своим модулем Python.
./usb-spy --py python/dummy.py disk.img
Вы также можете передавать произвольные аргументы из командной строки в свой класс Python. Аргументы доступны в kwargs.
./usb-spy --py python/dummy.py --py-args arg1=2 --py-args arg2=Hello disk.img
Также можно начать с примера rawimage, который содержит полную реализацию (~100 строк кода) того, что реализовано в бинарном файле usb-spy нативно.
Этот проект предоставляется «как есть». Не даётся никаких гарантий корректности, безопасности или пригодности для каких-либо целей.
Используйте инструменты и прошивку на свой страх и риск. Автор и участники не несут ответственности за любой ущерб, потерю данных или юридические последствия, которые могут возникнуть в результате использования данного программного или аппаратного обеспечения.
Вклад приветствуется! Пожалуйста, следуйте этим шагам:
Этот проект распространяется под лицензией GNU General Public License v3.0. Подробнее см. в файле LICENSE.