29
juin
'17

L'attaque du porte-clé intercepteur

Publié le 29 juin 2017

Lors de la quinzième édition de la Nuit du Hack, qui avait lieu ce week-end au New York Hotel de Disneyland Paris, j'ai présenté un moyen simple et pas cher de concevoir un équipement permettant de réaliser des attaques sur le protocole Bluetooth Low Energy (BLE), voire de simuler le comportement de n'importe quel équipement BLE. Je n'ai pas eu le temps d'entrer dans les détails, aussi vais-je le faire dans ce billet de blog.

Recyclage de Gablys

Cela fait quelques années que je cotoie des Gablys, des porte-clés connectés en BLE à des smartphones permettant de détecter la perte de clés ou d'objets, qui peut accessoirement être utilisé comme télécommande pour déclencher des selfies ou retrouver son smartphone égaré (une fonction de localisation inversée, en quelque sorte).

Un Gablys est assez simple: l'ensemble repose sur un transceiver de Nordic Semiconductor capable de communiquer en BLE, le nRF51822. Ce transceiver intègre un CPU ARM ainsi qu'une mémoire Flash de 256Kio, et a la particularité d'être débuggable et programmable via OpenOCD. De plus, il possède de base un bouton poussoir ainsi qu'un buzzer piezzo, qui permettent une interaction utilisateur (quoique l'on peut s'en passer selon les usages).

Les avantages du nRF51822 sont multiples:

Bref, il est dès lors possible de reprogrammer un Gablys afin de lui faire faire ce que l'on veut, à l'aide d'outils standards.

Installation des logiciels nécessaires

Pour réussir à développer et tester un firmware opensource pour Gablys, j'ai commencé par télécharger la version 11.0 du SDK de Nordic Semiconductor. Pourquoi la version 11.0 me direz-vous ? Parce que c'était celle a priori employée pour développer le firmware original de la bête. Notez que la dernière version du SDK devrait tout aussi bien fonctionner, mais il faudra prendre en compte les évolutions des fonctions exposées par ce dernier.

Tout d'abord, on télécharge la version voulue du SDK (la version 12.0 par exemple sur le site de Nordic Semiconductor. On dézippe le fichier dans un dossier prévu à cet effet:

$ unzip nRF5_SDK_12.3.0_d7731ad.zip
$ mv nRF5_SDK_12.3.0_d7731ad nrf5-sdk

Il nous faut ensuite installer la toolchain ARM et en ce qui me concerne j'ai préféré installer une version à jour plutôt que celle de ma debian, en la téléchargeant directement à partir du site d'ARM. J'en ai profité pour la décompresser dans un dossier à part, nommé toolchain:

$ cd nrf5-sdk && mkdir toolchain && cd toolchain
$ wget "https://developer.arm.com/-/media/Files/downloads/gnu-rm/6_1-2017q1/gcc-arm-none-eabi-6-2017-q1-update-linux.tar.bz2?product=GNU%20ARM%20Embedded%20Toolchain,64-bit,,Linux,6-2017-q1-update"
$ tar xvjf gcc-arm-none-eabi-6-2017-q1-update-linux.tar.bz2

Une fois la toolchain ARM décompressée, il suffit de la déclarer dans le fichier components/toolchain/gcc/Makefile.posix du SDK Nordic Semiconductor:

GNU_INSTALL_ROOT := /home/virtualabs/nrf5-sdk/toolchain/gcc-arm-none-eabi-6-2017-q1-update/
GNU_VERSION := 6.3.1
GNU_PREFIX := arm-none-eabi

Enfin, il nous faut ajouter une configuration particulière pour notre Gablys dans le fichier examples/bsp/gablys.h. Pour ce faire, il suffit de copier un fichier de configuration existant:

$ cp pca20006.h gablys.h

Nous en profitons pour ajouter une ligne dans le fichier boards.h du même dossier afin de déclarer notre board:

...

#elif defined(BOARD_N5DK1)
  #include "n5_starterkit.h"
#elif defined(BOARD_GABLYS)
  #include "gablys.h"
#elif defined(BOARD_CUSTOM)
  #include "custom_board.h"
#else
#error "Board is not defined"

...

Puis de modifier la fin du fichier afin de ne pas utiliser de quartz basse-fréquence, absent sur notre Gablys:

// Low frequency clock source to be used by the SoftDevice
#define NRF_CLOCK_LFCLKSRC      *                      \
    .source        = NRF_CLOCK_LF_SRC_RC,            \
    .rc_ctiv       = 16,                                                 \
    .rc_temp_ctiv  = 2,                                               \
   .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM \
*

De cette manière, tous les codes exemples fonctionneront sans problème avec notre Gablys, ce dernier ne possédant pas d'oscillateur basse-fréquence. Il est alors temps de lancer notre première compilation, et voir si ces modifications portent leurs fruits.

Première compilation

Pour essayer notre configuration, nous allons tenter de compiler une application BLE sur mesure, ble_app_beacon. Pour ce faire, nous allons ajouter une configuration propre à notre Gablys, et faire en sorte de tout configurer pour que cela compile correctement.

Dans un premier temps, il nous faut créer une arborescence sur mesure:

$ cd nrf5-sdk/examples/ble_peripheral/ble_app_beacon/
$ mkdir -p gablys/s130/armgcc/
$ cp pca20006/s130/config ./gablys/s130/ -rf
$ cp pca20006/s130/armgcc ./gablys/s130/armgcc -rf

Puis nous éditons dans un premier temps le fichier Makefile situé dans le dossier gablys/s130/armgcc/, afin de déclarer notre board plutôt que celle d'origine (PCA20006). Pour ce faire, il faut changer les options de compilation -DBOARD_PCA20006 en -DBOARD_GABLYS:

# Libraries common to all targets
LIB_FILES += \

# C flags common to all targets
CFLAGS += -DSWI_DISABLE0
CFLAGS += -DSOFTDEVICE_PRESENT
CFLAGS += -DNRF51
CFLAGS += -DNRF51822
CFLAGS += -DS130
CFLAGS += -DBLE_STACK_SUPPORT_REQD
CFLAGS += -DBOARD_GABLYS
CFLAGS += -DNRF_SD_BLE_API_VERSION=2
CFLAGS += -mcpu=cortex-m0
CFLAGS += -mthumb -mabi=aapcs
CFLAGS +=  -Wall -Werror -O3 -g3
CFLAGS += -mfloat-abi=soft
# keep every function in separate section, this allows linker to discard unused ones
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
CFLAGS += -fno-builtin --short-enums

# C++ flags common to all targets
CXXFLAGS += \

# Assembler flags common to all targets
ASMFLAGS += -x assembler-with-cpp
ASMFLAGS += -DSWI_DISABLE0
ASMFLAGS += -DSOFTDEVICE_PRESENT
ASMFLAGS += -DNRF51
ASMFLAGS += -DNRF51822
ASMFLAGS += -DS130
ASMFLAGS += -DBLE_STACK_SUPPORT_REQD
ASMFLAGS += -DBOARD_GABLYS
ASMFLAGS += -DNRF_SD_BLE_API_VERSION=2

Et on lance la compilation avec make:

$ make
mkdir _build
Compiling file: nrf_log_backend_serial.c
Compiling file: nrf_log_frontend.c
Compiling file: app_button.c
Compiling file: app_error.c
Compiling file: app_error_weak.c
Compiling file: app_timer.c
Compiling file: app_util_platform.c
Compiling file: hardfault_implementation.c
Compiling file: nrf_assert.c
Compiling file: sdk_errors.c
Compiling file: boards.c
Compiling file: nrf_drv_clock.c
Compiling file: nrf_drv_common.c
Compiling file: nrf_drv_gpiote.c
Compiling file: nrf_drv_uart.c
Compiling file: bsp.c
Compiling file: bsp_nfc.c
Compiling file: main.c
Compiling file: RTT_Syscalls_GCC.c
Compiling file: SEGGER_RTT.c
Compiling file: SEGGER_RTT_printf.c
Compiling file: ble_advdata.c
Compiling file: ble_conn_params.c
Compiling file: ble_srv_common.c
Assembling file: gcc_startup_nrf51.S
Compiling file: system_nrf51.c
Compiling file: softdevice_handler.c
Linking target: _build/nrf51822_xxaa.out

   text        data     bss     dec     hex filename
  11808         136     616   12560    3110 _build/nrf51822_xxaa.out

Preparing: _build/nrf51822_xxaa.hex
Preparing: _build/nrf51822_xxaa.bin

Le code compile parfaitement, et le Makefile produit un fichier binaire ainsi qu'un fichier au format ihex, dont nous allons nous servir pour programmer le nRF51822 présent sur le Gablys.

Programmation du Gablys

Le Makefile standard est fait pour fonctionner avec l'outil nrfjprog, cependant il est possible de le faire fonctionner avec OpenOCD et un STLink v2 à la chinoise.

Première étape, installer OpenOCD. La version 0.10.0 tirée de Github fera l'affaire. Vous pouvez tout aussi bien l'installer via les paquets standards de votre distribution, cela devrait fonctionner de la même façon.

On modifie donc la fin de notre fichier Makefile pour y intégrer deux cibles: la première nommée flash permettant de flasher l'application, la seconde nommée flash_softdevice permettant de flasher le SoftDevice [1].

flash: nrf51822_xxaa
    @echo Flashing: $(OUTPUT_BINARY_DIRECTORY)/$<.hex
    openocd -f interface/stlink-v2.cfg -f target/nrf51.cfg -c init -c "reset init" -c "halt" -c "program _build/nrf51822_xxaa.hex verify" -c "reset" -c "exit"

## Flash softdevice
flash_softdevice:
    @echo Flashing SoftDevice s130 ...
    openocd -f interface/stlink-v2.cfg -f target/nrf51.cfg -c init -c "reset init" -c "halt" -c "nrf51 mass_erase" -c "program $(abspath ../../../../../../components/softdevice/s130/hex/s130_nrf51_2.0.1_softdevice.hex) verify" -c "reset" -c "exit"

Ensuite, il faut connecter correctement le STLink à notre Gablys:

Puis flasher d'abord le SoftDevice, et ensuite l'application:

$ make flash_softdevice && make flash
Flashing SoftDevice s130 ...
openocd -f interface/stlink-v2.cfg -f target/nrf51.cfg -c init -c "reset init" -c "halt" -c "nrf51 mass_erase" -c "program /home/virtualabs/nrf5-sdk/components/softdevice/s130/hex/s130_nrf51_2.0.1_softdevice.hex verify" -c "reset" -c "exit"
Open On-Chip Debugger 0.10.0+dev-00146-g1025be36 (2017-06-16-16:35)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 1000 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : clock speed 950 kHz
Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.246408
Info : nrf51.cpu: hardware has 4 breakpoints, 2 watchpoints
target halted due to debug-request, current mode: Thread
xPSR: 0xc1000000 pc: 0x000006d0 msp: 0x000007c0
Info : nRF51822-QFAA(build code: G2) 256kB Flash
target halted due to debug-request, current mode: Thread
xPSR: 0xc1000000 pc: 0xfffffffe msp: 0xfffffffc
** Programming Started **
auto erase enabled
Info : Padding image section 0 with 2112 bytes
Warn : using fast async flash loader. This is currently supported
Warn : only with ST-Link and CMSIS-DAP. If you have issues, add
Warn : "set WORKAREASIZE 0" before sourcing nrf51.cfg to disable it
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000001e msp: 0xfffffffc
wrote 110592 bytes from file /home/virtualabs/nrf5-sdk/components/softdevice/s130/hex/s130_nrf51_2.0.1_softdevice.hex in 4.979112s (21.691 KiB/s)
** Programming Finished **
** Verify Started **
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000002e msp: 0xfffffffc
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000002e msp: 0xfffffffc
verified 108448 bytes in 0.698049s (151.717 KiB/s)
** Verified OK **
Flashing: /nrf51822_xxaa.hex
openocd -f interface/stlink-v2.cfg -f target/nrf51.cfg -c init -c "reset init" -c "halt" -c "program _build/nrf51822_xxaa.hex verify" -c "reset" -c "exit"
Open On-Chip Debugger 0.10.0+dev-00146-g1025be36 (2017-06-16-16:35)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 1000 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : clock speed 950 kHz
Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.246408
Info : nrf51.cpu: hardware has 4 breakpoints, 2 watchpoints
target halted due to debug-request, current mode: Thread
xPSR: 0xc1000000 pc: 0x000006d0 msp: 0x000007c0
target halted due to debug-request, current mode: Thread
xPSR: 0xc1000000 pc: 0x000006d0 msp: 0x000007c0
** Programming Started **
auto erase enabled
Info : nRF51822-QFAA(build code: G2) 256kB Flash
Warn : using fast async flash loader. This is currently supported
Warn : only with ST-Link and CMSIS-DAP. If you have issues, add
Warn : "set WORKAREASIZE 0" before sourcing nrf51.cfg to disable it
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000001e msp: 0x000007c0
wrote 12288 bytes from file _build/nrf51822_xxaa.hex in 0.589847s (20.344 KiB/s)
** Programming Finished **
** Verify Started **
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000002e msp: 0x000007c0
verified 11944 bytes in 0.088029s (132.503 KiB/s)
** Verified OK **

La programmation du SoftDevice et de l'application se sont bien déroulées, tout comme la vérification de la bonne écriture du code. De base, le CPU a été remis à zéro après la programmation, et si vous avez laissé votre Gablys connecté, celui-ci doit annoncer un périphérique BLE ressemblant à un beacon.

Il est temps d'aller plus loin dans le code source, afin d'implémenter quelque chose d'utile !

Firmware opensource pour Gablys

J'ai profité de l'occasion pour développer un firmware opensource pour Gablys, réimplémentant les principaux services et leurs characteristics, et se comportant presque à l'identique. Le code source de ce firmware est disponible sur Github. Ce dernier peut être compilé et flashé comme décrit précédemment.

En pratique, les services propres au Gablys sont implémentés dans le fichier gss/gss.c, dont la fonction ble_gss_init a pour rôle la création et l'initialisation de l'ensemble de ces services et des characteristics associées. A noter l'astuce avec le SDK Nordic pour déclarer un service ayant un UUID sur 128 bits:

static const ble_uuid128_t m_btn_uuid128 =
    {
       {
           0x45, 0xfa, 0x56, 0xc1, 0xfb, 0x1b, 0xc0, 0x28,
           0x96, 0xa8, 0x67, 0x18, 0x01, 0x28, 0x17, 0x4f
       }
    };

    /* ... du code ici ... */

    /* Add Gablys Button service. */
    ble_btn_uuid.uuid = GSS_BTN_SERVICE_UUID;
    err_code = sd_ble_uuid_vs_add(&m_btn_uuid128, &ble_btn_uuid.type);
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                            &ble_btn_uuid,
                            &p_gss->btn_service_handle);

    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

Enfin, la stack BLE est initialisée dans le fichier main.c, grâce à la fonction ble_stack_init:

static void ble_stack_init(void)
{
    uint32_t err_code;

    nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;

    // Initialize the SoftDevice handler module.
    SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);

    ble_enable_params_t ble_enable_params;
    err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
                                                    PERIPHERAL_LINK_COUNT,
                                                    &ble_enable_params);
    APP_ERROR_CHECK(err_code);

    //Check the ram settings against the used number of links
    CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT);

    // Enable BLE stack.
    sd_ble_enable(&ble_enable_params, &app_ram_base);
    ble_enable_params.common_enable_params.vs_uuid_count = 10;
    err_code = softdevice_enable(&ble_enable_params);
    APP_ERROR_CHECK(err_code);

    // Register with the SoftDevice handler module for BLE events.
    err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
    APP_ERROR_CHECK(err_code);

    // Register with the SoftDevice handler module for BLE events.
    err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
    APP_ERROR_CHECK(err_code);
}

C'est d'ailleurs dans cette fonction que l'on peut rajouter du code permettant d'usurper une adresse MAC, comme ci-dessous:

static void ble_stack_init(void)
{
    uint32_t err_code;
    ble_gap_addr_t address;

    address.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
    address.addr[0] = 0xFE;
    address.addr[1] = 0xFE;
    address.addr[2] = 0xC0;
    address.addr[3] = 0x15;
    address.addr[4] = 0x4D;
    address.addr[5] = 0xDE;

    nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;

    // Initialize the SoftDevice handler module.
    SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);

    ble_enable_params_t ble_enable_params;
    err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
                                                    PERIPHERAL_LINK_COUNT,
                                                    &ble_enable_params);
    APP_ERROR_CHECK(err_code);

    //Check the ram settings against the used number of links
    CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT);


    // Enable BLE stack.
    sd_ble_enable(&ble_enable_params, &app_ram_base);
    ble_enable_params.common_enable_params.vs_uuid_count = 10;
    err_code = softdevice_enable(&ble_enable_params);
    APP_ERROR_CHECK(err_code);

    sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &address);

    // Register with the SoftDevice handler module for BLE events.
    err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
    APP_ERROR_CHECK(err_code);

    // Register with the SoftDevice handler module for BLE events.
    err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
    APP_ERROR_CHECK(err_code);
}

Une fois compilé et flashé, le nouvel équipement est visible avec l'adresse MAC DE:4D:15:C0:FE:FE, comme le montre l'exemple ci-dessous (testé avec l'exemple beacon et non le firmware opensource):

Vous vous imaginez bien à ce stade de la lecture qu'il n'est pas très difficile de recréer n'importe quel équipement Bluetooth Low Energy à partir de ce petit porte-clé, et qu'avec un peu d'imagination et de temps on pourrait mettre à mal la sécurité de quelques équipements, voire réaliser des attaques très ciblées sur des périphériques communiquant en BLE.

Ok, et quoi d'autre ?

Nous avons démontré qu'il était possible d'utiliser un Gablys comme plateforme de développement peu onéreuse, à l'aide de logiciels libres et d'équipement à bas coût (STLink v2 notamment), et de profiter des avantages de ce dernier: il est petit, peu gourmand en énergie, programmable à volonté et alimenté par une pile bouton !

Il est dès lors possible de le mettre dans une poche et de simuler un équipement existant jusqu'à utiliser la même adresse Bluetooth (MAC), disons par exemple un cadenas connecté, et d'amener une application sur smartphone à transmettre à ce faux cadenas un code confidentiel (cette dernière faisant confiance à l'adresse Bluetooth du cadenas), comme je l'ai démontré l'année dernière lors de la Nuit du Hack.

J'ai placé le SDK modifié avec les examples cités dans cet article sur un repository spécifique, si certains d'entre vous veulent tester sans tout modifier à la main.

[1] Pour plus d'information sur les SoftDevice de NordicSemiconductor, consulter la page dédiée sur le site du fondeur

06
oct.
'16

Le BBC Micro:bit, c'est awesome !

Publié le 06 octobre 2016

La BBC a initié en 2015 le projet Micro:bit, qui se veut être un ordinateur de poche programmable destiné à l'éducation. L'objectif de cette dernière: fournir à chaque écolier de 12 ans («year 7») un support amusant et facile à utiliser. Exit l'Arduino et ses connexions complexes, le Micro:bit est voué à être la plateforme d'apprentissage du code à l'école, pour un prix modique (une board, un cable USB, une alimentation à piles et un boîtier pour 25€).

Le Micro:bit

Avant d'aller plus loin, il me semblait important de définir le genre du Micro:bit: masculin. Pour la simple et bonne raison que si vous en parlez au féminin dans un bon français, certaines personnes ne manqueront pas de remettre en question vos attributs, en particulier si vous êtes de sexe masculin. Trève de plaisanterie.

Le Micro:bit se base sur un SoC nRF51822 de Nordic Semiconductor, qui n'est rien de moins qu'un micro-contrôleur basé sur un CPU ARM Cortex M0 intégrant les technologies Bluetooth Low Energy et ShockBurst (SB) (version "ancienne" et améliorée, Enhanced ShockBurst (ESB)). Le protocole de communication ESB est utilisé par la couche logicielle sur laquelle repose le Micro:bit, mais il n'est pas directement accessible, ce qui est dommage car il y a des choses bien drôles à faire, comme intercepter les frappes de touches des claviers sans fil.

Le gros intérêt du Micro:bit, ce sont ses interfaces de programmation. Les concepteurs ont mis en place de la compilation dans le Cloud, à partir des environnement suivants: * JavaScript * Python * Scratch-like

Vous éditez votre code en ligne, vous le testez sur l'émulateur puis vous télécharger le binaire (compilé à la demande) afin de programmer votre Micro:bit. Et rien de complexe pour la programmation: il suffit de brancher le câble USB à un ordinateur, et le Micro:bit est reconnu comme une clef USB (stockage de masse). Une simple copie du fichier téléchargé sur ce support de stockage émulé suffit à déclencher la programmation du Micro:bit, qui se déconnectera automatiquement et lancera votre code. On ne peut plus simple.

Pour ceux que l'aspect en ligne rebute, il existe des environnements de développement intégrés, comme [mu-editor->https://github.com/mu-editor/mu], ou on peut se rabattre sur du C++ en dernier recours.

Micro:bit repose sur MicroPython, un portage de Python3 pour les micro-contrôleurs, et permet ainsi de développer très simplement en Python ! Le code suivant permet d'effectuer une animation sur l'écran intégré:

from microbit import *

while True:
    display.show(Image.HAPPY)
    sleep(1000)
    display.show(Image.SAD)
    sleep(1000)

Les fonctionnalités du Micro:bit

L'avantage principal du Micro:bit est le fait que l'on peut développer en Python à l'aide de la bibliothèque standard. Cette dernière interface tout le matériel, et rend le développement très intuitif. Elle permet notamment : * de gérer l'affichage de l'écran de LEDs (elle possède une banque d'images intégrées) ; * de gérer les boutons poussoirs ; * de gérer les boutons capacitifs (les pads apparents) ; * de jouer de la musique (en connectant un HP comme il faut) ; * de faire de la synthèse vocale (toujours avec le HP) ; * de gérer les accéléromètres ; * de gérer la boussole ; * de communiquer avec d'autres Micro:bit par radio ; * de communiquer avec d'autres Micro:bit par "réseau" filaire ; * de stocker des fichiers via un système de fichiers minimaliste (sans carte SD !).

Bref, c'est juste énorme les possibilités offertes ! Sans ajout de composants, on peut faire des jeux qui communiquent via radio, des horloges binaires, des écrans affichant des messages, etc ... Et je ne parle pas des shields qui sont en train d'être développés.

Utilisation avancée

Ce n'est pas parce que c'est conçu pour les débutants que ça n'offre pas de possibilités ! J'étais à la recherche depuis quelques temps d'une plateforme portable permettant de mener des attaques particulières sur les protocoles Bluetooth Low Energy et ShockBurst. C'est d'ailleurs pour cela que j'avais conçu le ProbeZero que j'ai présenté à la Nuit du Hack 2016. Mais le Raspberry Pi est relativement lourd, et mon système mettait facilement 30 secondes à se lancer, sans parler de la consommation de batterie. Le Micro:bit est de fait une très bonne alternative, avec un écran en plus !

Pour le développement, on ne peut pas se limiter à la bibliothèque standard: les aspects radio sont très limités, et ce serait dommage de se passer du SDK de Nordic Semiconductor (nRF51 SDK) pour s'amuser avec de la radio. Le code source du fork de MicroPython est disponible sur github, où toute la phase d'installation est relativement documentée. Si vous souhaitez forker la base Python du Micro:bit, c'est une bonne piste à suivre.

Il est aussi possible de développer directement en C++ et d'appeler les fonctionnalités présentes via Python: Micro:bit propose une couche d'abstraction (nommée Microbit-DAL) qui permet d'utiliser toutes les fonctionnalités du Micro:bit. L'aspect intéressant de cette couche est que l'on peut du coup utiliser le SDK nRF51 pour accéder aux éléments internes du nRF51822. Pour hacker sans se fouler, c'est quand même classe :).

Conclusion

Le Micro:bit est pour moi une plateforme qui me donne envie d'expérimenter, qui me semble tout à fait abordable par des élèves, et que je souhaite faire essayer dès que ce sera possible par mes minis-moi. Elle est aussi très intéressante car elle offre un moyen simple de bidouiller encore plus sur des protocoles sans-fil par exemple, voire développer des outils d'attaque portables (je n'ai pas abordé l'USB HID mais à mon avis il y a aussi de quoi creuser: Teensy-like, rubber-ducky et consors doivent pouvoir être portés sans trop de souci AMHA).

Je suis conquis par ce projet, au point même que ça me donne envie de faire un workshop là dessus à la prochaine Nuit du Hack (ou même Nuit du Hack Kids). Et en parler à une de mes amies qui est directrice d'école et pour qui l'enseignement du code à l'école est quelque peu compliqué.

Essayez-le, ça vaut franchement le coup.

22
sept.
'16

Super Minitel: suite et fin

Publié le 22 septembre 2016

J'en parlais récemment, j'ai profité de mon temps libre de ces dernières semaines pour apporter la touche finale à mon Super Minitel. Le résultat est plutôt probant, bien qu'il y ait des améliorations à apporter, à mon humble avis.

Ajout d'un support pour Raspberry Pi

J'ai ressorti mon bon vieux OpenScad afin de concevoir un support pour tenir le Raspberry Pi et sa carte d'adaptation vidéo/clavier dans le Minitel. J'ai opté pour une fixation par collage sur le Minitel, avec un espace pour laisser passer le connecteur de clavier. Le Raspberry Pi est fixé avec un vis, tandis qu'un ergot vient se loger dans le second emplacement de vis et empêcher tout mouvement.

Je l'ai ensuite imprimé sur ma Prusa i3, puis testé à blanc avec le Raspberry Pi. J'ai enfin monté le tout dans le Minitel, en prenant soin de maintenir l'ensemble avec des pinces serrantes. C'est franchement pratique ces pinces, j'ai découvert leur utilité grâce à Babozor et ses conseils de la Grotte du Barbu !

Après une nuit de séchage, j'ai pu fixer le Raspberry Pi dessus et tester le bon fonctionnement du clavier rétractable (qui passe du coup en dessous du Rasp).

Intégration du son

Après avoir commandé tout un lot de composants pour ajouter un ampli audio dans le minitel et les avoir soudé, j'ai pu tester le rendu. C'est pas trop mal, mais il y a un shhh de fond qui est plutôt gênant, ça doit être du au fait que mon ampli n'intègre pas de filtre ... Ceci dit en ajustant correctement le volume, on ne l'entend quasimment plus.

Pour la fixation, même recette que précédemment: j'ai conçu un support adapté au PCB (avec une seule vis pour la fixation, j'ai été radin), je l'ai imprimé et collé dans le Minitel.

Le rendu son n'est pas merveilleux, mais ça donne un bon vieux son old school, j'aime bien :). Pour terminer, j'ai conçu et imprimé un guide de perçage afin de faire des petits trous sur le côté du Minitel à l'endroit où se trouve le haut-parleur afin de laisser le son se diffuser.

Je l'ai imprimé, et je m'en suis servi de guide pour percer les trous sur le Minitel. Le rendu est très propre, et n'a nécessité aucun tracé particulier, juste la fixation du guide avec une pince auto-serrante.

Déco finale

S'il y a bien un domaine dans lequel je suis une quiche, c'est la déco. Je suis une bille en peinture, pochoirs, dessin, etc. Mais je ne voyais qu'une seule manière de décorer ce super Minitel: repeindre la carcasse en blanc cassé, et peindre un sigle «Super Minitel» au pochoir.

J'ai donc commencé par concevoir un pochoir sur Inkscape. En reprenant des polices de Nintendo et en bidouillant un peu, j'ai réussi à imprimer un motif noir sur blanc sur du papier photo. Après un petit tour chez Cultura pour acheter de la peinture en bombe et à pochoir, quelques babioles et de la colle repositionnable en spray, j'ai entamé à la main la découpe des caractères. Un bon gros fail. Peu de précision malgré l'utilisation d'un cutter très fin, et l'encre bavait sur mes mains. Il fallait trouver autre chose.

Je me suis rabattu sur l'impression 3D: en effet, quoi de mieux que d'imprimer un pochoir en 3D et de s'en servir pour peindre le motif ! C'était sans compter deux éléments importants pour des pochoirs. Le premier, c'est que lorsque l'on crée des pochoirs, on ne peut pas raisonnablement réaliser de belles lettres possédant des vides, comme les lettres P ou R. On est obligé de laisser une liaison pour que la partie masquant l'intérieur "tienne". Le rendu en est forcément moins bon. Second point, il doit être assez fin pour masquer et tenir correctement sur le support. Avec l'imprimante 3D, imprimer fin c'est imprimer pour rien. Lorsque l'on décolle le motif imprimé, il se plie et généralement cette déformation reste. C'est du plastique (PLA dans mon cas), donc assez difficile à reformer, et la colle repositionnable n'y a rien fait. Il ne me restait qu'à tester mon pochoir épais (1mm) afin de voir si le rendu serait correct.

Ma dernière erreur avec les pochoirs a été de penser que la colle repositionnable c'était LA solution. En réalité, elle a créé des petits points de colle sous le pochoir, et l'encre s'est enfournée sous le pochoir à cause de l'irrégularité de celui-ci et de l'espace vacant laissé par la colle en spray. Merci les tutos Youtube, mais cette fois-ci ça ne m'a pas aidé. heureusement que j'avais fait des tests sur carton et papier avant de me lancer sur le Minitel...

J'étais pas loin d'abandonner quand j'ai eu une idée toute simple: pourquoi ne pas imprimer les lettres avec l'imprimante 3D et les coller de façon jolie sur la carcasse du Minitel ? De cette façon, on obtient un effet de relief et un beau contraste blanc cassé/noir qui est du plus bel effet (enfin je crois). J'ai donc modélisé les lettres en convertissant le modèle SVG en SCAD (merci paths2openscad !) et les ai imprimé à l'envers pour que le côté lisse corresponde à la partie visible (de face) et donne un rendu moins "imprimante 3D". Le résultat est très probant je trouve.

j'ai ensuite placé les lettres, les ai collé et ai attendu que cela sèche. J'ai fait l'erreur de marquer l'alignement au crayon papier, et cela se voit encore un peu de très près, c'est dommage. Je prendrais une équerre pour le prochain exemplaire et ne tracerai aucun trait, cela sera plus propre.

Résultat final

Au final, j'ai un Super Minitel qui ressemble exactement à ce que je voulais, qui accepte jusqu'à deux manettes Super NES en USB (pratique pour Street Fighter, mais on peut aussi jouer grâce au clavier), et qui attire la curiosité avec son aspect "presque" Super Nintendo.

Je vais le beta-tester à la maison afin de déceler de potentiels défauts de conception avant de le donner à un généreux soutien du projet OpenIt, et d'en faire deux autres pour les deux autres soutiens ayant choisi cette récompense.

Il me reste encore quelques Minitels un brin différents à la maison, certainement l'occasion de me faire la main sur la soudure CMS à air chaud ;). Il me faut absolument un exemplaire à la maison, et les minis-moi auront obligation d'y jouer (vous en conviendrez: Super Mario World, Street Fighter II, Bomberman 3 et Worms sont des jeux formidables o/).

Ah et si vous voulez tenter de reproduire ce hack, j'ai mis des ressources à disposition (majoritairement les PCBs, les fichiers de conception 3D ainsi que le software permettant d'interfacer le clavier). Il manque encore des éléments (comme la liste des composants pour les PCBs, mais ça viendra -- il y aura peut-être des modifications suite au beta-test).



Les contenus disponibles sur ce blog sont publiés sous licence Creative Commons BY-NC-SA.
Vous pouvez réutiliser tout ou partie de ces contenus à condition de citer l'auteur et l'origine, vous ne pouvez en faire une utilisation commerciale, et enfin vous devez partager tout travail ou œuvre dérivée sous les mêmes conditions — c'est-à-dire avec la même licence d'utilisation Creative Commons.