Etude en profondeur de Deezer ou comment télécharger des albums complets sans se prendre la tête

Image illustrant l'article : Etude en profondeur de Deezer ou comment télécharger des albums complets sans se prendre la tête

Etude en profondeur de Deezer ou comment télécharger des albums complets sans se prendre la tête

par Korben -

Aujourd’hui, je vais vous parler d’un petit outil qui s’appelle Dysnomia et qui permet de télécharger de la musique sur Deezer. Deezer uniquement car il s’agit de la première version, mais l’auteur envisage d’intégrer le support de Jamendo, Last.fm, RadioblogClub, Youtube et Dailymotion.

L’intérêt de cet outil, hormis télécharger des albums complets, c’est qu’il s’agit d’un Proof Of Concept assez interressant montrant vraiment comment fonctionne Deezer.

Dysnomia est dispo pour Windows et Linux (et tous systèmes supportant les librairies wxWidgets et libcurl) et ne doit pas être utilisé pour télécharger de la musique soumis aux droits d’auteurs.

Etude en profondeur de Deezer pour le téléchargement d’albums

J’ai eu la chance de m’entretenir par email avec Solozerk, son concepteur. J’ai regardé aussi le code source et je dois dire que c’est plutôt bien pensé. Voici l’explication technique de comment fonctionne Deezer et Dysnomia pour télécharger des albums et des mp3 sur Deezer. Deezer, pour dialoguer entre l’applet flash du site (exécutée en local chez le visiteur) et les scripts php du site en lui même, utilise un framework : amfphp (http://amfphp.org/). Ce framework permet à flash de serialiser les données à transmettre à php sous une forme particuliere (se réferer au code de amfphp pour plus de détails), et à php de les désérialiser pour les obtenir sous une forme lisible. Il permet également l’opération inverse, pour passer des données de PHP à l’applet flash en réponse à des requetes provenant de l’applet flash. Le script php deezer s’occupant de gérer les requetes (recherche, demande de lecture de musiques, etc…) envoyées par l’applet flash, et d’y répondre, est nommé gateway.php (http://www.deezer.com/flashservices/gateway.php).. Ce script s’occupe donc de recevoir les demandes de l’applet flash et d’y répondre, les deux (les requetes comme les réponses) étant transmises sous forme sérialisée amfphp. Pour effectuer une recherche sur le site deezer, l’applet flash (aprés avoir permis à l’utilisateur de taper sa recherche dans la textbox en flash) procède comme ceci :

  • Envoi d’une requete demandant un identifiant de session deezer (en réalité, cette requete est envoyée au chargement de l’applet flash et le résultat est utilisé partout aprés, mais en demander un nouveau avant chaque opération ne pose pas de probleme, et les opérations en question ne peuvent pas être exécutées sans identifiant de session).
  • L’identifiant de session deezer est récupéré en résultat de la requete. Il est reçu sous forme cryptée, avec une clef A.
  • Une requete de recherche est envoyée, comportant le motif de recherche tapé par le visiteur (exemple : “tryad”). Ce motif de recherche est crypté avec une clef B avant son envoi.
  • Les résultats de la recherche sont récupérés en résultat de la requete. Ils sont en clair et chacun des résultats comporte de nombreux champs (artiste, titre, album, PUID unique de la chanson, note des visiteurs, etc…).
  • L’applet flash n’a plus qu’à afficher les différents résultats de la recherche.

Toutes ces requetes/ces résultats de requetes sont, là encore, envoyés/reçus à gateway.php, sous forme sérialisée amfphp. Or, l’applet flash n’est qu’une application comme une autre, exécutée sur l’ordinateur du visiteur. Ce qu’elle fait (requetes, déserialisation et analyse des réponses, etc…), n’importe quelle autre application peut le faire. C’est ce que fait dysnomia : il imite completement le comportement de l’applet flash deezer pour avoir accés aux même fonctionnalités (recherche, lecture de musique…) que l’applet. Le champs PUID renvoyé avec les résultats de recherche est un identifiant unique pour chaque chanson. Il s’agit en réalité de l’identifiant musicbrainz, une base de données libre regroupant des informations sur des musiques. Par exemple, le PUID de la musique “The final rewind”, de l’artiste Tryad, est : 0d9236ca-3027-0a87-3f9a-4e8c11b6aa4a. On peut consulter les informations relatives à ce PUID ici, par exemple : http://musicbrainz.org/show/puid/?puid=0d9236ca-3027-0a87-3f9a-4e8c11b6aa4a Voyons maintenant comment fonctionne la lecture de musique. L’applet flash, une fois la recherche effectuée, a une liste de musiques résultante de la recherche, avec pour chacune un PUID. Pour pouvoir lire une musique en particulier, elle doit exécuter une requete demandant le mp3 en spécifiant ce PUID unique. Elle recevra en réponse le mp3, qu’elle pourra jouer. Dysnomia, là encore, se contente d’imiter son comportement, mais au lieu de jouer le mp3 reçu, il l’enregistre sur le disque. Cela permet de télécharger des musiques depuis deezer. En réalité, la demande de réception du mp3 est un peu plus compliquée qu’une simple requete précisant le PUID, pour des raisons de protection du contenu. Voila comment ça se passe :

  • Envoi d’une requete demandant un identifiant de session deezer (même remarque que plus haut : l’identifiant de session est en fait récupéré juste aprés le chargement de l’applet, meme si dysnomia en redemande un à chaque fois - ce qui n’a aucun impact sur le fonctionnement).
  • Reception de cet identifiant, crypté avec la clef A.
  • Envoi d’une requete demandant une clef de téléchargement de mp3. Une telle clef donne l’autorisation de “télécharger” (normalement afin de lire la musique dans l’applet, mais dans le cas de dysnomia de la sauver sur le disque) une musique en particulier, une fois et une seule. Cette requete de demande de clef doit comporter l’identifiant de session deezer récupéré, *aprés* l’avoir decrypté, ainsi que le PUID de la musique que l’on souhaite télécharger (et qui est disponible dans les résultats de recherche). Si l’identifiant de session ou le PUID spécifié dans la requete n’existent pas (PUID ne correspondant à aucune musique ou identifiant de session jamais attribué en réponse à une requete), alors une erreur se produit et rien n’est renvoyé.
  • Reception de la clef de téléchargement, cryptée avec la clef A.
  • Envoi d’une requete demandant le mp3. Cette requete doit comporter l’identifiant de session deeezer decrypté, la clef de téléchargement decryptée, et le PUID de la musique désirée. Contrairement aux autres requetes, celle ci est effectuée sur une page différente, cacheDiffusion.php, et sur un serveur différent. L’url de la requete est plus précisément :

http://proxy-.deezer.com/cacheDiffusion.php?ID=&KEY=&SESSION_ID= est le dernier caractere du PUID de la chanson désiré. Exemple pour le PUID évoqué plus haut (tryad - the final rewind) : proxy-a.deezer.com.. Si l’identifiant de session spécifié n’existe pas (parce que jamais attribué ou mal decrypté), si la clef n’existe pas (mêmes raisons possibles), ou si le PUID spécifié ne correspond pas à celui pour lequel la clef de téléchargement a été demandée, ou encore si la clef a déjà été utilisée pour télécharger la musique, alors un message d’erreur apparait, indiquant que “votre ip a été enregistrée”, blablabla. Le message d’erreur en question peut par exemple être visualisé simplement en ne passant aucun parametre, ici par exemple : http://proxy-a.deezer.com/cacheDiffusion.php On note également que contrairement aux autres requetes, celle ci passe les parametres par GET dans la requete et non par sérialisation amfphp. A noter également que n’importe quel proxy est en fait utilisable pour télécharger la chanson, pas forcément celui dont le caractere correspond au dernier caractere du PUID de la musique (même si à l’époque où j’avais testé ça, des erreurs php apparaissaient en plus de la musique indiquant un espace disque insuffisant pour copier un fichier, probablement le mp3 dans le cache du proxy utilisé, qui n’est pas prévu à la base pour relayer cette musique).

  • Réception du mp3 et lecture (dans le cas de l’applet) ou enregistrement sur le disque (dans le cas de dysnomia).

Par ailleurs, dysnomia propose également un mode de téléchargement “alternatif”, qui utilise le fait que les caches des proxy deezer sont insuffisament protégés. En fait, il est tout à fait possible d’accéder à n’importe quel mp3 sans la moindre clef ou identifiant de session valide via une url sous la forme suivante : http://proxy-.deezer.com/cache//.rbs est le dernier caractere du PUID, l’avant dernier, et le puid de la musique désirée. Exemple avec une autre musique de tryad, “Beat into submission”, dont le PUID est 4b75899d-6c0f-dcf8-ccf8-889a31042c0f : http://proxy-0.deezer.com/cache/f/4b75899d-6c0f-dcf8-ccf8-889a31042c0f.rbs Cependant, ce mode de téléchargement n’est pas utilisé par l’applet flash deezer (et il est *théoriquement* détectable dans les logs http du proxy concerné). Il est proposé dans dysnomia en tant que proof of concept (et permet de téléchargement des musiques tout aussi bien que le téléchargement “classique”, sans besoin de demander aucune clef). Voila donc comment fonctionne dysnomia, en imitant le comportement de l’applet flash deezer (à l’exception de ce dernier mode de téléchargement où il procede différemment). A noter que j’ai parlé d’une clef A et d’une clef B, utilisées respectivement pour decrypter/crypter les identifiants de session et clef de téléchargement et les motifs de recherche. En réalité, l’applet flash utilise un cryptage RC4 mais étant donné la maniere dont fonctionne l’algorithme RC4, il revient exactement au meme dans ce cas précis de crypter/decrypter avec un simple XOR à l’aide de ces deux clef différentes. C’est ce que fait dysnomia, au lieu d’utiliser RC4. A noter qu’utiliser du cryptage pour “protéger” deezer n’a en réalité strictement aucune utilité, puisque qu’on dispose du texte en clair (simplement en sniffant les requetes envoyées par l’applet flash pour voir quelle est la version decryptée de la clef de téléchargement/de l’identifiant de session - et qu’on a la version en clair du motif de recherche pour la bonne raison que c’est le visiteur qui le tape) ET de la version cryptée (en sniffant les réponses envoyées depuis deezer à l’applet pour la clef/l’identifiant de session, et en sniffant la requete de recherche envoyée par l’applet pour le motif de recherche). Dans ces conditions, aucune véritable cryptanalyse n’est nécessaire pour obtenir des clefs permettant de crypter les données à l’identique. Dysnomia utilise curl pour effectuer les requetes http (http://curl.haxx.se/) et wxWidgets pour l’interface (http://wxwidgets.org/). Il n’y a pas de véritable sérialisation/déserialisation amfphp implémentée dans dysnomia. A la place, le logiciel se contente de serialiser/déserialiser au format amfphp les données dans le cas particulier de deezer, en connaissant la structure des résultats de requete/des requetes à envoyer. Voila voila :-) Pour plus de détails (notamment les valeurs exactes des clefs A et B, ou encore le format exact de serialisation), il suffit de se reporter au code du module “deezer” (deezer.cpp et deezer.hpp) de Dysnomia. A noter qu’à deux reprises depuis la création de dysnomia, effectivement, le fonctionnement de deezer a changé (la premiere fois pour rajouter le cryptage des identifiants de session/clefs de téléchargement, la deuxieme pour modifier légerement les structures de données et les clefs de cryptage). Dans les deux cas, dysnomia a été patché pour s’adapter, et il continuera de l’être à chaque modification deezer :-)

Sachez aussi que la prochaine version 0.4 permettra de télécharger de la musique depuis Radioblogclub, supportera le téléchargement en parallèle, le tri des listes et le renommage des mp3. Encore une fois, un simple hacker démontre qu’aucune protection n’est de taille à rivaliser avec un peu d’imagination. Si ça vous interresse, sachez aussi que le code source est ouvert et que vous pouvez donc aider Solozerk a faire progresser son logiciel. Si vous voulez tester Dysnomia pour mieux comprendre tout ce qui a été décrit précédemment (et pas pour télécharger des albums sur Deezer, hein ?) vous trouverez tout ce qu’il faut sur le site Dysnomia-project.org.

Encore merci à Geoffrey pour l’info et grand merci à Solozerk pour son talent et sa disponibilité.