BEEWi: SiMPLY WiRELESS : Bluetooth App Reversing
              
Auteur : Xartrick
Zine : Rafale #19

Beewi, simplement sans fils, voilà ce qu'ils nous envoient comme slogan. Et oui, j'ai été séduit par une de leurs conneries. Une Mini Cooper S qui fonctionne sans fil, comme promit, et qui peut être contrôlée par un smartphone. Elle est contrôlée par une application développée par l'entreprise afin de contrôler les appareils qu'ils ont créé. Cette application est disponible sur la majorité des systèmes d'exploitations des smartphones: iOS, Android, Windows Phone et sûrement d'autres. Caractéristiques ---------------- Puce Bluetooth : Bluetooth 2.0+EDR, CSR BC4 Portée du Bluetooth : minimum 10 mètres, jusqu'à 15 mètres (Classe 2) Profils Bluetooth : Wireless iAp Alimentation : 3 Piles AA (non fournies) Autonomie : Jusqu'à 3 heures Contrôles : Avant / Arrière et contrôle du volant Dimensions : 179 mm x 98 mm x 74 mm Poids : 205 g Echelle : 1:20 Je suis (tristement) propriètaire d'un téléphone sous iOS, et donc, la honte est sur moi. Bref! J'installe leur appli', je met ma voiture en position ON, et je démarre l'application. Fuck It! Aucune voiture n'a été détectée. Alors, je pense à un simple défaut sur le produit, ou une merde dans le genre. Je fais donc toute une batterie de tests (allant même jusqu'à tester si les composants était bien sous tension, mais tout est OK, pas de soucis). Alors je décide de prendre un second téléphone, sous Android cette fois. Et là, ho magie, ça marche du feu de Dieu ! Bon, c'est bien que ça marche, mais cela n'est pas mon téléphone, alors, faut une autre solution. Qu'est-ce que j'utilise le plus à part mon téléphone ? Mon ordinateur, bien sûr. Y'a pas 36 milles solutions, faut que je reverse l'application pour savoir comment marche la voiture, donc, cable USB, mode developpeur et à l'aide de ADB, on va aller chercher notre application et la récupérer sur notre PC afin de lancer l'analyse. Pour ça, il vous faut le SDK Android installé correctement (rien de compliqué, je vous assure, même moi je l'ai fait). Lancez un shell là où se trouve ADB et là, on va commencer à explorer le téléphone. Pour pouvoir récupérer l'application, il faut d'abord savoir où elle se trouve. Déjà, on met notre Android en mode developpeur puis on lance ADB et vérifiant si notre téléphone est trouvé : > adb devices * daemon not running. starting it now on port 5037 * * daemon started successfully * List of devices attached 5700a9****** device OK, ça c'est bon, notre device est bien là, on peut maitenant trouver la liste des applications installées avec une commande : pm list packages -f Donc on lance ça avec une petit grep sur le nom du machin pour pas se manger une liste avec des dizaines d'applications : > adb shell "pm list packages -f | grep remotecontrol" package:/data/app/com.baracoda.android.bluetoothcar.remotecontrol.apk= com.baracoda.android.bluetoothcar.remotecontrol Maintenant qu'on sait où elle se trouve, on la récupère : >adb pull /data/app/com.baracoda.android.bluetoothcar.remoteco ntrol.apk 1450 KB/s (842916 bytes in 0.567s) Et voilà, elle se trouve dans le répertoire courrant, plus qu'à la décompiler et voir ce qu'elle cache. Comme vous le savez peut-être, le format APK est simplement un ZIP avec une structure particulière. Il contient un fichier au format DEX, qui lui contient le code de notre application. Les programmes sous Android sont écrits en JAVA, et il existe un outil pour convertir ces fichiers en DEX vers un fichier JAR. Je vous présente donc, dextojar (original n'est-ce pas ?). https://code.google.com/p/dex2jar/ Donc, on lance ce logiciel et on se retrouve avec un fichier JAR. >d2j-dex2jar.bat classes.dex dex2jar classes.dex -> classes-dex2jar.jar Au début, j'étais parti pour décompiler l'application avec JD-GUI, mais il n'arrive pas à la décompiler complètement. Je me suis donc tourné vers autre chose, JAD. http://varaneckas.com/jad/ Tout comme le format APK, le format JAR est également une archive ZIP. Pour vous éviter les recherches, le code intéressant se trouve dans la classe CarController qui se trouve dans: .\com\baracoda\android\bluetoothcar\remotecontrol\ On extrait donc le fichier CarController.class et on le décompile avec JAD. >jad CarController.class On se retrouve avec des erreurs, mais c'est pas important, cela ne nous gènera pas pendant le reverse. Dans cette classe, on voit un code intéressant: private void sendMoveForward(byte byte0) throws Exception { if (connectionHelper != null) { vibrate(); if (!lastPaused) { connectionHelper.write(MOVE_FORWARD); lastSendCommand = 1; } updateControllerImageViewMoveState(MoveDirection.Forward); } } connectionHelper est ce qui nous permet de faire la passerelle entre le téléphone et la voiture (via le Bluetooth). La méthode write envoit une suite de bytes à la voiture. Ici, c'est MOVE_FORWARD. private static final byte MOVE_FORWARD[] = { 1 }; Donc, si on envoit un octet avec comme valeur 1, on fait avancer la voiture, intéressant non ? Et ça marche, vraiment... Pour le reste c'est la même chose. Il faut savoir que chaque direction a deux commandes, la commande d'action, et la commande d'arrêt. Le stop est la valeur du mouvement moins un. Donc pour arrêter d'avancer en avant, on envoit 0. Avancé: 1 Stop: 0 Reculé: 3 Stop: 2 Gauche: 5 Stop: 4 Droite: 7 Stop: 6 On a pas besoin d'en savoir plus, on connait déjà le protocol. On envoit un seul octet par mouvement, simpliste comme protocol hein? Pour commencer, on va mettre notre périphérique Bluetooth sur un port série (port COM), ça je vous laisse faire, j'ai choisi le port COM9. Allez, on va coder un peu, et comme personne aime le .NET, on va le faire en Python, comme ça la plus part du monde sera content :D Pour cela, on va utiliser pyserial: http://pyserial.sourceforge.net/ Donc, on commence déjà par ouvrir notre port... import serial port = serial.Serial(8) ' Le port COM1 correspond a 0 port.close() Voilà, on a notre base, ça suffit amplement. Maintenant, on va mettre en place les mouvements: def move(movement, sec=0.5): global port port.write(chr(movement)) time.sleep(sec) port.write(chr(movement - 1)) Et voilà, on a notre fonction pour bouger (on oublie pas d'importer time hein). On pose donc nos constantes: MOVE_FORWARD = 1 MOVE_BACKWARD = 3 MOVE_LEFT = 5 MOVE_RIGHT = 7 Et c'est déjà fini, libre à vous après de faire votre programme qui réagit selon les touches qu'on presse, d'intégrer un joystick et tout ce que vous voulez d'autre ! import serial import time def move(movement, sec=0.5): global port port.write(chr(movement)) time.sleep(sec) port.write(chr(movement - 1)) port = serial.Serial(8) move(MOVE_FORWARD) port.close() Xartrick.