Атаки на USB-стек персональных компьютеров

Благодаря тому, что я постоянно работаю со связкой микроконтроллер-компьютер и разрабатываю протокольные модули для работы с различными драйверами, иногда получается наткнуться на интересное поведение операционных систем.

DOS-атака на MS Windows при помощи USB-устройства

Тесно работая уже много лет с шиной USB и реализуя устройства всевозможных классов, я набрал довольно большой список различных приколов в поведении шины. В процессе отладки падало все что только можно, а главное стандартные драйвера из стандартной поставки MS Windows. В синий экран меня уводили устройства стандартных классов, падали драйвера USBHUB.SYS, USBHID.SYS, USBCCID.SYS (последний вообще дырявый до чертиков). Однако, в большинстве случаев проявление было сложным и требовало действия от пользователя на самом PC.

Но вот один случай все-таки очень привлек и я сохранил «важную» микропрограмму устройства для анализа и выделения проблемы. Итак, представляю Вашему внимаю USB-устройство, которое в буквальном смысле осуществляет DOS-атаку на систему под управлением Windows XP 32-bit (так же проверено под Windows 2003 Server 32-bit). Windows Vista данной проблеме вроде бы не подвержена.

Итак, после подключения устройства в USB-порт независимо от настроек автозагрузки и независимо от того, заблокирован сеанс пользователя или нет, процесс System начинает отъедать приличный объем процессорного времени. На однопроцессорной системе это все 100% (т.е. система практически вешается), на 2х и более процессорах система внешне остается вполне работоспособной и отзывчивой, но все равно в Диспетчере задач видно, что не все «слава богу». Мало того, после извлечения устройства эффект сохраняется! Остается только перезагружать систему, да и с перезагрузкой не все гладко, вроде бы работа завершается, но непосредственно перезагрузка/выключение не происходит, система остается висеть на пустом экране с курсором.

В продолжение к этому, все новые подключаемые USB устройства так же не определяются в системе. Видимо, виснет сервис, отвечающий за процесс определения устройства.

Вот что можно увидеть в Windows 2003 Server 32-bit после подключения в Диспетчере задач:

image

Привожу готовую микропрограмму для микроконтроллера NXP LPC214х. Сделана на основе стека LPCUSB. Микропрограмма оттестирована на стандартной отладочной плате Keil MCB2140. Микропрограмму можно взять по этой ссылке: USBHID_LPCUSB_HACK.ZIP

Теперь о сути проблемы и условиях возникновения: все дело в некорректно сформированном дескрипторе USB.

Примечание: Дескрипторы USB - это набор структур, которые описывают устройство USB. В процессе инициализации устройства, хост запрашивает данный дескриптор, обрабатывает его и в соответствии с полученной информацией инициализирует устройство (находит необходимый драйвер, получает настройки устройства, устанавливает строковые константы и т.д.).

Если быть более точным: в дескрипторе конфигурации имеется поле, которое описывает суммарный размер дескрипторов отвечающих за конфигурацию устройства (сюда входит непосредственно дескриптор конфигурации, дескриптор интерфейса, дескриптор класса и дескрипторы конечных точек). Так вот, данное значение в процессе правки дескрипторов случайно было задано ошибочным: серьезно завышено, в данном примере вместо 0x29 установлено 0x200.

	0x09,				// bSize
	DESC_CONFIGURATION,	// bDescrType
	//LE_WORD(0x29),		// wTotalLength
	LE_WORD(0x200),		// wTotalLength
	0x01,				// bNumInterfaces
	0x01,				// bConfigurationValue
	0x00,				// iConfiguration
	0x80,				// bmAttributes
	0x32,				// bMaxPower

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

Выводы о представленной проблеме оставляю на вашей совести. От себя только замечу, что основное слабое место: требуется «физический контакт» с атакуемой машиной. Именно по этой причине опасность данной ошибки в стеке USB операционной системы в большинстве случаев не велика. Сервера должны стоять в помещении с ограниченным доступом, а для рядового пользователя такой «прикол» скорее всего будет просто неприятным.

Хорошо бы понять, какие еще версии MS Windows так болезненно реагируют на данный некорректный дескриптор. Я проверил на 3х машинах под Windows XP и одной под Windows 2003 Server (с полным набором всех обновлений), 64-битных операционок под рукой, к сожалению, нет. На имеющейся машине пол Windows Vista никаких зависаний не произошло, она квалифицировала устройство как полностью исправное (видимо, не использует значение данного поля вообще).

Атака на MacOS X 10.10 Yosemite

С обновлением MacOS X до версии 10.10 Yosemite в одном из рабочих проектов вылезла очень интересная проблема: при подключении устройства с Flash-диском и активным CD-ROM разделом, MacOS внезапно падала в "синий экран", а пока такое устройство не извлекалось, продолжала циклично перезагружаться.

Конечно, подключение USB-устройства - не причина для падения операционной системы (тем более на уровне ядра), однако, причины все-равно пришлось искать. Как оказалось, падение вызывал запрос MSC_GetConfiguration. В коде на него безусловно подготавливался ответ из 8 байт:

00 00 00 04 00 00 00 00 (для Flash-раздела)
00 00 00 04 00 00 00 08 (для CD-ROM-раздела)

Пришлось вставлять проверки и для отдельных случаев возвращать:

00 00 00 00

Именно, 4 байта данных в теле и вызвали переполнение в ядре MacOS X 10.10. Сам MacOS запрашивал всего 4 байта. Глубже с данной проблемой я не разбирался, вполне возможно данную уязвимость можно каким-то образом эксплуатировать, но для понимания сего факта у меня не хватает знаний и умений.

Отчет о падении был отправлен в Apple, так что скорее всего через какое-то время данная проблема будет исправлена.

Original: http://igorkov.org/usbhack,
Author: igorkov