
Keystroke injection vulnerabilities in wireless presentation clickers
Мне захотелось заняться реверс-инжинирингом RF-устройств, поэтому я заказал несколько презентационных кликеров и немного повеселился.
Это форк nrf-research-firmware (который я написал несколько лет назад в Bastille). Я добавил поддержку нескольких новых трансиверов/протоколов и включил PoC-эксплойты инъекции нажатий клавиш для 13 распространённых презентационных кликеров.
| Производитель | Модель | Протокол | RFIC | Добавлено |
|---|---|---|---|---|
| AmazonBasics | P-001 | AmazonBasics P-001 | nRF24 | 2019-04-20 |
| Canon | PR100-R | Canon PR100-R | PL1167 | 2019-04-20 |
| Funpick | Wireless Presenter | HS304 | HS304 | 2019-04-20 |
| AMERTEER | Wireless Presenter | HS304 | HS304 | 2019-04-20 |
| BEBONCOOL | D100 | HS304 | HS304 | 2019-04-20 |
| ESYWEN | Wireless Presenter | HS304 | HS304 | 2019-04-20 |
| Red Star Tech | PR-819 | HS304 | HS304 | 2019-04-20 |
| DinoFire | D06-DF-US | HS304 | HS304 | 2019-04-20 |
| TBBSC | DSIT-60 | TBBSC DSIT-60 | BK2451 | 2019-04-21 |
| Rii | Wireless Presenter | Rii Wireless Presenter | BK2451 |
Это стандартный зашифрованный протокол клавиатур Logitech, используемый в R500. Он частично уязвим к атаке «инъекция зашифрованных нажатий клавиш», которую я задокументировал для клавиатур Logitech Unifying в рамках проекта MouseJack.
Я говорю частично, потому что принимаются не все HID-скан-коды. А именно, 0x04-0x1D (A-Z) заменяются на 0x00, когда приёмник отправляет пакет на хост-компьютер, а это значит, что мы можем внедрить всё, что угодно, если это не буква. Ещё одно исключение — комбинации с ctrl разрешены, даже когда они содержат буквы.
Для эффективной инъекции нажатий клавиш через R500 необходимо проявить немного креативности.
Предположим, цель находится в bash-сессии. В bash мы можем закодировать наши символы в восьмеричной системе, кодируя команды, содержащие буквы, которые мы хотим, чтобы цель выполнила.
Например, ping google.com кодируется как $'\160\151\156\147' $'\147\157\157\147\154\145\056\143\157\155'. Если отправить эту строку в bash-сессию, а затем отправить enter, команда ping google.com будет выполнена на целевой машине.
Адрес вашего Logitech R500 можно найти с помощью nrf24-scanner следующим образом:
sudo ./tools/nrf24-scanner.py -c {2..74..3} -l
Пакеты должны выглядеть примерно так:
[2019-04-21 13:11:52.507] 62 5 85:D1:9D:FE:07 00:40:00:08:B8
[2019-04-21 13:11:52.515] 62 5 85:D1:9D:FE:07 00:40:00:08:B8
[2019-04-21 13:11:52.523] 62 22 85:D1:9D:FE:07 00:D3:4D:6F:B6:1B:E6:05:A2:B4:8B:98:F9:C2:00:00:00:00:00:00:00:81
Инъекция возможна, потому что приёмник не обеспечивает приращение счётчиков AES, поэтому вы можете повторять пакеты. Пакет, передаваемый по радио (OTA), состоит из полезной нагрузки USB HID, зашифрованной в режиме счётчика AES, и счётчика. Когда вы нажимаете кнопку на презентационном кликере, генерируются пакет нажатия клавиши и пакет отпускания клавиши. Пакет отпускания клавиши состоит из одних нулей, что даёт нам чистый ключевой материал, который можно повторно использовать: применить XOR с нашей собственной полезной нагрузкой и передать по радио.
Автоматизировать процесс прослушивания нажатия кнопки, извлечения второго пакета (отпускания клавиши) и автоматического использования его в качестве ключевого материала несложно. Но мне лень, поэтому сначала вам придётся самостоятельно перехватить нажатие кнопки, которое выглядит так:
[2019-04-21 16:02:56.451] 65 5 85:D1:9D:FE:07 00:40:00:08:B8
[2019-04-21 16:02:56.459] 65 5 85:D1:9D:FE:07 00:40:00:08:B8
[2019-04-21 16:02:56.468] 65 22 85:D1:9D:FE:07 00:D3:E6:7B:35:8C:BB:2C:7D:5B:8B:98:FA:76:00:00:00:00:00:00:00:B9
[2019-04-21 16:02:56.475] 65 5 85:D1:9D:FE:07 00:40:00:08:B8
[2019-04-21 16:02:56.507] 65 5 85:D1:9D:FE:07 00:40:00:08:B8
[2019-04-21 16:02:56.516] 65 22 85:D1:9D:FE:07 00:D3:99:D6:D3:8D:49:25:F5:4D:8B:98:FA:77:00:00:00:00:00:00:00:1A
[2019-04-21 16:02:56.524] 65 5 85:D1:9D:FE:07 00:40:00:08:B8
[2019-04-21 16:02:56.532] 65 5 85:D1:9D:FE:07 00:40:00:08:B8
Второй пакет длиной 22 байта — это пакет отпускания клавиши.
Удалите последний байт полезной нагрузки и скопируйте строку в logitech.py, заменив KEYUP_REF.
(Без обновления KEYUP_REF это не должно работать, но если сработает, пожалуйста, сообщите мне!)
Внедрите последовательность нажатий клавиш для bash-команды ping google.com, закодированную в восьмеричной системе, в конкретный приёмник Logitech R500 (адрес 85:D1:9D:FE:07):
sudo ./tools/r500-injector.py -l -a 85:D1:9D:FE:07
Это стандартный незашифрованный протокол Logitech, используемый в R400/R800.
Адрес вашего Logitech R400/R800 можно найти с помощью nrf24-scanner следующим образом:
sudo ./tools/nrf24-scanner.py -c {2..74..3} -l
Пакеты должны выглядеть примерно так:
[2019-04-21 12:58:43.466] 32 0 9D:9E:95:52:07
[2019-04-21 12:58:43.620] 32 10 9D:9E:95:52:07 00:C1:00:00:00:00:00:00:00:3F
Внедрите тестовую последовательность нажатий клавиш в конкретный приёмник Logitech R400/R800 (адрес 9D:9E:95:52:07):
sudo ./tools/preso-injector.py -l -f logitech -a 9D:9E:95:52:07
Беспроводной презентационный пульт Rii (в форме округлой ручки) основан на BK2451 (который, судя по всему, является клоном nRF24). Похоже, это общий протокол, учитывая распространённость аналогичных устройств, поэтому, вероятно, я переклассифицирую его после получения дополнительных данных.
Функционально это незашифрованная беспроводная клавиатура, уязвимая к инъекции нажатий клавиш.
Беспроводной пульт (в форме округлой ручки) использует nRF24 Enhanced Shockburst со скоростью 250 Кбит/с (по-видимому, без ACK) и 5-байтовый адрес. Наблюдалось, что протестированное устройство постоянно находилось на частоте 2425 МГц, но, похоже, оно использует какую-то схему адаптивной перестройки частоты. На практике перед отправкой пакетов нажатий клавиш необходимо отправить несколько фиктивных пакетов на целевой канал.
Я подозреваю, что здесь происходит перескок каналов, который я не охарактеризовал, но для демонстрации инъекции нажатий клавиш достаточно нацелиться на один канал.
Адрес вашего беспроводного пульта (в форме округлой ручки) можно найти с помощью nrf24-scanner следующим образом:
sudo ./tools/nrf24-scanner.py -c 25 -l -R 250K -A 5
Обратите внимание: ваш может находиться на другом канале.
Пакеты должны выглядеть примерно так:
[2019-04-21 11:50:33.116] 25 3 6D:8C:01:14:25 4B:51:00
[2019-04-21 11:50:33.212] 25 3 6D:8C:01:14:25 4C:00:00
[2019-04-21 11:50:33.522] 25 3 6D:8C:01:14:25 4D:51:00
[2019-04-21 11:50:33.565] 25 3 6D:8C:01:14:25 4E:00:00
Внедрите тестовую последовательность нажатий клавиш в конкретный приёмник Rii (адрес 6D:8C:01:14:25):
sudo ./tools/preso-injector.py -l -f rii -a 6D:8C:01:14:25
TBBSC DSIT-60 основан на BK2451 (который, судя по всему, является клоном nRF24). Существуют очевидные аналогичные устройства (например, это), которые я не тестировал. Пока я классифицирую это как отдельный протокол, но это, скорее всего, изменится после тестирования аналогичного устройства (устройств).
Функционально это незашифрованная беспроводная клавиатура, уязвимая к инъекции нажатий клавиш.
DSIT-60 использует nRF24 Enhanced Shockburst со скоростью 250 Кбит/с (или, по крайней мере, эквивалент по радиоинтерфейсу) с 3-байтовым адресом. Наблюдалось, что протестированное устройство постоянно находилось на частоте 2406 МГц, но я не уверен, какие другие каналы оно может использовать.
Адрес вашего DSIT-60 можно найти с помощью nrf24-scanner следующим образом:
sudo ./tools/nrf24-scanner.py -c 6 -l -R 250K -A 3
Обратите внимание: ваш может находиться на другом канале, или может присутствовать адаптивная перестройка частоты, которую я не наблюдал.
Пакеты должны выглядеть примерно так:
[2019-04-21 10:33:44.264] 6 4 87:02:09 0B:42:00:2B
[2019-04-21 10:33:44.269] 6 4 87:02:09 0B:42:00:2B
[2019-04-21 10:33:52.477] 6 4 87:02:09 01:42:00:28
Внедрите тестовую последовательность нажатий клавиш в конкретный приёмник TBBSC DSIT-60 (адрес 87:02:09):
sudo ./tools/preso-injector.py -l -f tbbsc -a 87:02:09
Это почти наверняка общий протокол, но я ещё не изучал аналогичные устройства (например, это). Пока я классифицирую это как отдельный протокол, но это, скорее всего, изменится после тестирования аналогичного устройства (устройств).
P-001 основан на семействе RFIC nRF24 и функционально является незашифрованной беспроводной клавиатурой, уязвимой к инъекции нажатий клавиш.
P-001 использует nRF24 Enhanced Shockburst со скоростью 2 Мбит/с, 5-байтовыми адресами и каналами 2402–2476.
Адрес вашего P-001 можно найти с помощью nrf24-scanner.py.
Нажатие стрелки вправо должно генерировать пакеты, выглядящие примерно так:
[2019-04-20 12:59:13.908] 27 9 44:CB:66:A3:BE 00:00:00:00:00:00:00:00:01
[2019-04-20 12:59:13.909] 27 9 44:CB:66:A3:BE 00:00:00:00:00:00:00:00:01
[2019-04-20 12:59:13.999] 27 9 44:CB:66:A3:BE 00:00:4E:00:00:00:00:00:01
[2019-04-20 12:59:14.120] 27 9 44:CB:66:A3:BE 00:00:00:00:00:00:00:00:01
[2019-04-20 12:59:14.121] 27 9 44:CB:66:A3:BE 00:00:00:00:00:00:00:00:01
[2019-04-20 12:59:14.211] 27 9 44:CB:66:A3:BE 00:00:4E:00:00:00:00:00:01
Внедрите тестовую последовательность нажатий клавиш в конкретный приёмник AmazonBasics P-001 (адрес 44:CB:66:A3:BE):
sudo ./tools/preso-injector.py -l -f amazon -a 44:CB:66:A3:BE
Я не уверен, уникален ли этот протокол для Canon PR100-R, но поскольку это единственное устройство, на котором, как я наблюдал, он используется, я оставляю его в отдельной категории, пока данные не скажут об обратном.
PR100-R основан на RFIC PL1167 и неизвестном микроконтроллере.
Функционально PR100-R является незашифрованной беспроводной клавиатурой, уязвимой к инъекции нажатий клавиш.
PR100-R использует FSK-протокол со скоростью 1 Мбит/с, работающий на каналах с шагом 5 МГц в диапазоне от 2406 МГц до 2481 МГц.
Пакеты скремблируются и защищаются 16-битным CRC.
По-видимому, приёмник не отправляет ACK, с той оговоркой, что я реверс-инженерил этот протокол ровно настолько, насколько необходимо для демонстрации инъекции нажатий клавиш.
Протокол, по-видимому, использует адаптивный подход к выбору канала: приёмник останавливается на канале после того, как пульт передаёт по нему некоторое количество пакетов. На практике достаточно передать несколько секунд фиктивных пакетов перед передачей пакетов нажатий клавиш.
Исходя из формата пакетов, неясно, использует ли этот протокол фиксированное синхрослово или адрес, уникальный для каждого устройства. Я исследовал только один экземпляр (из-за высокой цены), поэтому мне не удалось полностью проверить формат пакетов.
Скрипт инъекции работает с моим PR100-R, но для общего использования его может потребоваться модифицировать. Если у вас есть другой PR100-R и вы можете это проверить, пожалуйста, сообщите мне!
Внедрите тестовую последовательность нажатий клавиш в ближайший приёмник Canon PR100-R:
sudo ./tools/preso-injector.py -l -f canon
HS304, по-видимому, является специализированной RFIC для презентационных кликеров (или, возможно, беспроводных клавиатур/мышей). Название происходит от USB-строки устройства HAS HS304 и было одинаковым для всех устройств в этом наборе.
Наблюдалось, что RFIC представляет собой немаркированный корпус SOP-16 без видимых различий между производителями.
Устройства на основе HS304 функционально являются незашифрованными беспроводными клавиатурами, уязвимыми к инъекции нажатий клавиш.
HS304 — это FSK-протокол со скоростью 1 Мбит/с, работающий на трёх каналах в диапазоне ISM 2,4 ГГц (2407, 2433, 2463). По-видимому, приёмник не отправляет ACK обратно презентационному кликеру, а доставка пакетов обеспечивается передачей каждого пакета на каждом из трёх каналов.
На практике надёжной доставки пакетов также можно добиться, передавая каждый пакет несколько раз на одном канале.
Пакеты скремблируются и защищаются 16-битным CRC.
Здесь нет схемы адресации или сопряжения, поэтому для инъекции нажатий клавиш не требуется обнаружение устройств, однако отсутствие ACK исключает активное обнаружение приёмников.
Внедрите тестовую последовательность нажатий клавиш в ближайшие приёмники HS304:
sudo ./tools/preso-injector.py -l -f hs304
Принимайте и декодируйте пакеты, отправляемые ближайшими презентационными кликерами NS304:
sudo ./tools/preso-scanner.py -l -f hs304
| 2019-04-21 |
| Logitech | R400 | Logitech Unencrypted | nRF24 | 2019-04-21 |
| Logitech | R800 | Logitech Unencrypted | nRF24 | 2019-04-21 |
| Logitech | R500 | Logitech Encrypted | nRF24 | 2019-04-21 |