Lorsqu'un bug apparaît dans une application réseau et qu'il n'est pas possible de modifier le comportement du client ni du serveur pour le contourner, il peut être nécessaire d'altérer les informations pendant leur transmission. Cette manipulation nécessite évidemment que les infomations transitent en clair sur le réseau.

Dans cet article, j'explique la manière dont j'ai corrigé la configuration du client DLNA intégré dans ma télévision.

Apparition du problème

Alors que je parcourais les différentes options de tri dans la liste des vidéos depuis le client DLNA de ma télévision, la connexion avec le serveur s'est brutalement interrompue. J'ai alors relancé le client DLNA, mais le problème a persisté.

Il restait cependant possible de consulter les contenus en sélectionnant "Tous les contenus", "Musiques" et "Images". Cela a permis de confirmer que le client et le serveur fonctionnaient encore correctement, seul un paramètre appliqué pour un seul type de contenu causait l'erreur.

Tentatives de correction du paramétrage

En parcourant les menus de la télévision et après quelques recherches sur Internet, j'ai compris que ce paramètre ne pouvait être modifié que depuis l'écran devenu inaccessible. Je n'ai pas non plus trouvé de possibilité de réinitialiser la configuration du client DLNA de la télévision sans réinitialiser totalement la télévision elle-même, ce que je ne voulais pas faire.

Je me suis donc tourné vers le serveur DLNA, une simple instance de minidlna lancée sur mon NAS sous Debian. Après avoir activé le paramètre log_level=http=debug, j'ai comparé les requêtes entre l'affichage du type de contenu "Musiques", totalement fonctionnel, et l'affichage du type de contenu "Vidéos", affecté par le problème. Cette comparaison m'a permis de déterminer l'erreur exacte : le type d'objet demandé (ObjectID) par la télévision était vide lors de la sélection du type de contenu "Vidéos", le serveur DLNA ne pouvait donc répondre correctement à cette requête.

La requête émise par le client étant invalide, il n'y avait pas non plus de possibilité de contourner le problème en agissant sur la configuration du serveur.

Contournement de l'erreur

La seule solution pour corriger le paramétrage de la télévision était donc d'accéder à l'écran qui provoquait l'erreur. Pour cela, j'ai opté pour une attaque de l'homme du milieu (MitM) afin de modifier à la volée le contenu de la requête, et permettre au serveur DLNA de recevoir une requête valide. L'outil parfait pour cela dans mon cas se nomme netsed (NETwork Stream EDitor).

Un autre problème mineur s'est posé lors de mes premières tentatives pour appliquer cette solution. Le protocole DLNA repose sur une détection automatique des paramètres du serveur par les clients. Il était donc inutile de tenter une modification du port coté serveur pour intercaler netsed entre le client et le serveur, puisque le client utilisait alors le nouveau port configuré. Pour contourner cet autre problème, j'ai simplement utilisé une règle iptables afin de rediriger les paquets à destination du port du serveur DLNA vers le port utilisé par netsed en local lors de l'arrivée des paquets sur le serveur.

$ # Redirection du port 8200 de l'interface enp1s0 vers le port 8201 pour les paquets entrants
$ sudo iptables -t nat -A PREROUTING -i enp1s0 -p tcp --dport 8200 -j REDIRECT --to-port 8201
$ # Lancement de netsed pour écouter sur le port 8201 et retransmettre les requêtes modifiées sur le port 8200
$ netsed tcp 8201 localhost 8200 's/ObjectID></ObjectID>V<'

Une fois netsed lancé, j'ai relancé le client DLNA, et le type de contenu "Vidéos" s'est correctement affiché. J'ai alors pu modifier le paramètre bugué pour remettre une valeur fonctionnelle. La dernière étape a consisté à stopper netsed et retirer la règle iptables pour restaurer le fonctionnement normal du service.